Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 3402, 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 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-07-21-100400-3661-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 unsigned cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is equal to 0 */
102#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
103 if (length == 0) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is equal to 0 */
111#define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
112 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (length == 0) { ((void)0); return ((void*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const unsigned start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 unsigned start, int *length);
300
301static proto_item *
302proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303 unsigned start, unsigned *length);
304
305static void
306proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307static void
308proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309
310static void
311proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312static void
313proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314static void
315proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316static void
317proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318static void
319proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320static void
321proto_tree_set_string(field_info *fi, const char* value);
322static void
323proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326static void
327proto_tree_set_vines(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330static void
331proto_tree_set_ether(field_info *fi, const uint8_t* value);
332static void
333proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334static void
335proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336static void
337proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338static void
339proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340static void
341proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342static void
343proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344static void
345proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346static void
347proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348static void
349proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350static void
351proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352static void
353proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354static void
355proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356static void
357proto_tree_set_boolean(field_info *fi, uint64_t value);
358static void
359proto_tree_set_float(field_info *fi, float value);
360static void
361proto_tree_set_double(field_info *fi, double value);
362static void
363proto_tree_set_uint(field_info *fi, uint32_t value);
364static void
365proto_tree_set_int(field_info *fi, int32_t value);
366static void
367proto_tree_set_uint64(field_info *fi, uint64_t value);
368static void
369proto_tree_set_int64(field_info *fi, int64_t value);
370static void
371proto_tree_set_eui64(field_info *fi, const uint64_t value);
372static void
373proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374
375/* Handle type length mismatch (now filterable) expert info */
376static int proto_type_length_mismatch;
377static expert_field ei_type_length_mismatch_error;
378static expert_field ei_type_length_mismatch_warn;
379static void register_type_length_mismatch(void);
380
381/* Handle byte array string decoding errors with expert info */
382static int proto_byte_array_string_decoding_error;
383static expert_field ei_byte_array_string_decoding_failed_error;
384static void register_byte_array_string_decodinws_error(void);
385
386/* Handle date and time string decoding errors with expert info */
387static int proto_date_time_string_decoding_error;
388static expert_field ei_date_time_string_decoding_failed_error;
389static void register_date_time_string_decodinws_error(void);
390
391/* Handle string errors expert info */
392static int proto_string_errors;
393static expert_field ei_string_trailing_characters;
394static void register_string_errors(void);
395
396/* Handle varint errors expert info */
397static int proto_varint_errors;
398static expert_field ei_varint_decoding_failed_error;
399static void register_varint_errors(void);
400
401static int proto_register_field_init(header_field_info *hfinfo, const int parent);
402
403/* special-case header field used within proto.c */
404static header_field_info hfi_text_only =
405 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
406int hf_text_only;
407
408/* Structure for information about a protocol */
409struct _protocol {
410 const char *name; /* long description */
411 const char *short_name; /* short description */
412 const char *filter_name; /* name of this protocol in filters */
413 GPtrArray *fields; /* fields for this protocol */
414 int proto_id; /* field ID for this protocol */
415 bool_Bool is_enabled; /* true if protocol is enabled */
416 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
417 bool_Bool can_toggle; /* true if is_enabled can be changed */
418 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
419 For dissectors that need a protocol name so they
420 can be added to a dissector table, but use the
421 parent_proto_id for things like enable/disable */
422 GList *heur_list; /* Heuristic dissectors associated with this protocol */
423};
424
425/* List of all protocols */
426static GList *protocols;
427
428/* Structure stored for deregistered g_slice */
429struct g_slice_data {
430 size_t block_size;
431 void *mem_block;
432};
433
434/* Deregistered fields */
435static GPtrArray *deregistered_fields;
436static GPtrArray *deregistered_data;
437static GPtrArray *deregistered_slice;
438
439/* indexed by prefix, contains initializers */
440static GHashTable* prefixes;
441
442/* Contains information about a field when a dissector calls
443 * proto_tree_add_item. */
444#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)))
445#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
446
447/* Contains the space for proto_nodes. */
448#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
449 node->first_child = NULL((void*)0); \
450 node->last_child = NULL((void*)0); \
451 node->next = NULL((void*)0);
452
453#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
454 wmem_free(pool, node)
455
456/* String space for protocol and field items for the GUI */
457#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;
\
458 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
459 il->value_pos = 0; \
460 il->value_len = 0;
461#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
462 wmem_free(pool, il);
463
464#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", 464, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 464, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
465 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
466 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 466
, __func__, "Unregistered hf! index=%d", hfindex)
; \
467 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", 467, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
468 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", 468, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
469 hfinfo = gpa_hfinfo.hfi[hfindex];
470
471#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
472
473/* List which stores protocols and fields that have been registered */
474typedef struct _gpa_hfinfo_t {
475 uint32_t len;
476 uint32_t allocated_len;
477 header_field_info **hfi;
478} gpa_hfinfo_t;
479
480static gpa_hfinfo_t gpa_hfinfo;
481
482/* Hash table of abbreviations and IDs */
483static wmem_map_t *gpa_name_map;
484static header_field_info *same_name_hfinfo;
485
486/* Hash table protocol aliases. const char * -> const char * */
487static GHashTable *gpa_protocol_aliases;
488
489/*
490 * We're called repeatedly with the same field name when sorting a column.
491 * Cache our last gpa_name_map hit for faster lookups.
492 */
493static char *last_field_name;
494static header_field_info *last_hfinfo;
495
496/* Points to the first element of an array of bits, indexed by
497 a subtree item type; that array element is true if subtrees of
498 an item of that type are to be expanded. */
499static uint32_t *tree_is_expanded;
500
501/* Number of elements in that array. The entry with index 0 is not used. */
502int num_tree_types = 1;
503
504/* Name hashtables for fast detection of duplicate names */
505static GHashTable* proto_names;
506static GHashTable* proto_short_names;
507static GHashTable* proto_filter_names;
508
509static const char * const reserved_filter_names[] = {
510 /* Display filter keywords. */
511 "eq",
512 "ne",
513 "all_eq",
514 "any_eq",
515 "all_ne",
516 "any_ne",
517 "gt",
518 "ge",
519 "lt",
520 "le",
521 "bitand",
522 "bitwise_and",
523 "contains",
524 "matches",
525 "not",
526 "and",
527 "or",
528 "xor",
529 "in",
530 "any",
531 "all",
532 "true",
533 "false",
534 "nan",
535 "inf",
536 "infinity",
537 NULL((void*)0)
538};
539
540static GHashTable *proto_reserved_filter_names;
541static GQueue* saved_dir_queue;
542
543static gboolean
544proto_strcase_equal(const void* name1, const void* name2)
545{
546 const char* s1 = (const char*)name1;
547 const char* s2 = (const char*)name2;
548
549 return g_ascii_strcasecmp(s1, s2) == 0 ? TRUE(!(0)) : FALSE(0);
550}
551
552static int
553proto_compare_name(const void *p1_arg, const void *p2_arg)
554{
555 const protocol_t *p1 = (const protocol_t *)p1_arg;
556 const protocol_t *p2 = (const protocol_t *)p2_arg;
557
558 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
559}
560
561static GSList *dissector_plugins;
562
563#ifdef HAVE_PLUGINS1
564void
565proto_register_plugin(const proto_plugin *plug)
566{
567 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
568}
569#else /* HAVE_PLUGINS */
570void
571proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
572{
573 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 573, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
574}
575#endif /* HAVE_PLUGINS */
576
577static void
578call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
579{
580 proto_plugin *plug = (proto_plugin *)data;
581
582 if (plug->register_protoinfo) {
583 plug->register_protoinfo();
584 }
585}
586
587static void
588call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
589{
590 proto_plugin *plug = (proto_plugin *)data;
591
592 if (plug->register_handoff) {
593 plug->register_handoff();
594 }
595}
596
597void proto_pre_init(void)
598{
599 saved_dir_queue = g_queue_new();
600
601 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
602 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
603 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
604
605 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, proto_strcase_equal);
606 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
607 /* GHashTable has no key destructor so the cast is safe. */
608 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
609 }
610
611 gpa_hfinfo.len = 0;
612 gpa_hfinfo.allocated_len = 0;
613 gpa_hfinfo.hfi = NULL((void*)0);
614 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
615 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
616 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
617 deregistered_fields = g_ptr_array_new();
618 deregistered_data = g_ptr_array_new();
619 deregistered_slice = g_ptr_array_new();
620}
621
622/* initialize data structures and register protocols and fields */
623void
624proto_init(GSList *register_all_plugin_protocols_list,
625 GSList *register_all_plugin_handoffs_list,
626 register_entity_func register_func, register_entity_func handoff_func,
627 register_cb cb,
628 void *client_data)
629{
630 /* Initialize the ftype subsystem */
631 ftypes_initialize();
632
633 /* Initialize the address type subsystem */
634 address_types_initialize();
635
636 /* Register one special-case FT_TEXT_ONLY field for use when
637 converting wireshark to new-style proto_tree. These fields
638 are merely strings on the GUI tree; they are not filterable */
639 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
640
641 /* Register the pseudo-protocols used for exceptions. */
642 register_show_exception();
643 register_type_length_mismatch();
644 register_byte_array_string_decodinws_error();
645 register_date_time_string_decodinws_error();
646 register_string_errors();
647 register_varint_errors();
648 ftypes_register_pseudofields();
649 col_register_protocol();
650
651 /* Have each built-in dissector register its protocols, fields,
652 dissector tables, and dissectors to be called through a
653 handle, and do whatever one-time initialization it needs to
654 do. */
655 if (register_func != NULL((void*)0))
656 register_func(cb, client_data);
657
658 /* Now call the registration routines for all epan plugins. */
659 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
660 ((void (*)(register_cb, void *))l->data)(cb, client_data);
661 }
662
663 /* Now call the registration routines for all dissector plugins. */
664 if (cb)
665 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
666 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
667
668 /* Now call the "handoff registration" routines of all built-in
669 dissectors; those routines register the dissector in other
670 dissectors' handoff tables, and fetch any dissector handles
671 they need. */
672 if (handoff_func != NULL((void*)0))
673 handoff_func(cb, client_data);
674
675 /* Now do the same with epan plugins. */
676 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
677 ((void (*)(register_cb, void *))l->data)(cb, client_data);
678 }
679
680 /* Now do the same with dissector plugins. */
681 if (cb)
682 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
683 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
684
685 /* sort the protocols by protocol name */
686 protocols = g_list_sort(protocols, proto_compare_name);
687
688 /* sort the dissector handles in dissector tables (for -G reports
689 * and -d error messages. The GUI sorts the handles itself.) */
690 packet_all_tables_sort_handles();
691
692 /* We've assigned all the subtree type values; allocate the array
693 for them, and zero it out. */
694 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
)))
;
695}
696
697static void
698proto_cleanup_base(void)
699{
700 protocol_t *protocol;
701 header_field_info *hfinfo;
702
703 /* Free the abbrev/ID hash table */
704 if (gpa_name_map) {
705 // XXX - We don't have a wmem_map_destroy, but
706 // it does get cleaned up when epan scope is
707 // destroyed
708 //g_hash_table_destroy(gpa_name_map);
709 gpa_name_map = NULL((void*)0);
710 }
711 if (gpa_protocol_aliases) {
712 g_hash_table_destroy(gpa_protocol_aliases);
713 gpa_protocol_aliases = NULL((void*)0);
714 }
715 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)
;
716 last_field_name = NULL((void*)0);
717
718 while (protocols) {
719 protocol = (protocol_t *)protocols->data;
720 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", 720
, __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", 720, "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", 720, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
721 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", 721, "protocol->proto_id == hfinfo->id"
))))
;
722
723 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)
;
724 if (protocol->parent_proto_id != -1) {
725 // pino protocol
726 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 726, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
727 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"
, 727, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
728 } else {
729 if (protocol->fields) {
730 g_ptr_array_free(protocol->fields, true1);
731 }
732 g_list_free(protocol->heur_list);
733 }
734 protocols = g_list_remove(protocols, protocol);
735 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
736 }
737
738 if (proto_names) {
739 g_hash_table_destroy(proto_names);
740 proto_names = NULL((void*)0);
741 }
742
743 if (proto_short_names) {
744 g_hash_table_destroy(proto_short_names);
745 proto_short_names = NULL((void*)0);
746 }
747
748 if (proto_filter_names) {
749 g_hash_table_destroy(proto_filter_names);
750 proto_filter_names = NULL((void*)0);
751 }
752
753 if (proto_reserved_filter_names) {
754 g_hash_table_destroy(proto_reserved_filter_names);
755 proto_reserved_filter_names = NULL((void*)0);
756 }
757
758 if (gpa_hfinfo.allocated_len) {
759 gpa_hfinfo.len = 0;
760 gpa_hfinfo.allocated_len = 0;
761 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)
;
762 gpa_hfinfo.hfi = NULL((void*)0);
763 }
764
765 if (deregistered_fields) {
766 g_ptr_array_free(deregistered_fields, true1);
767 deregistered_fields = NULL((void*)0);
768 }
769
770 if (deregistered_data) {
771 g_ptr_array_free(deregistered_data, true1);
772 deregistered_data = NULL((void*)0);
773 }
774
775 if (deregistered_slice) {
776 g_ptr_array_free(deregistered_slice, true1);
777 deregistered_slice = NULL((void*)0);
778 }
779
780 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)
;
781 tree_is_expanded = NULL((void*)0);
782
783 if (prefixes)
784 g_hash_table_destroy(prefixes);
785
786 if (saved_dir_queue != NULL((void*)0)) {
787 g_queue_clear_full(saved_dir_queue, g_free);
788 g_queue_free(saved_dir_queue);
789 saved_dir_queue = NULL((void*)0);
790 }
791}
792
793void
794proto_cleanup(void)
795{
796 proto_free_deregistered_fields();
797 proto_cleanup_base();
798
799 g_slist_free(dissector_plugins);
800 dissector_plugins = NULL((void*)0);
801}
802
803static bool_Bool
804ws_pushd(const char* dir)
805{
806 //Save the current working directory
807 const char* save_wd = get_current_working_dir();
808 if (save_wd != NULL((void*)0))
809 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
810
811 //Change to the new one
812#ifdef _WIN32
813 SetCurrentDirectory(utf_8to16(dir));
814 return true1;
815#else
816 return (chdir(dir) == 0);
817#endif
818}
819
820static bool_Bool
821ws_popd(void)
822{
823 int ret = 0;
824 char* saved_wd = g_queue_pop_head(saved_dir_queue);
825 if (saved_wd == NULL((void*)0))
826 return false0;
827
828 //Restore the previous one
829#ifdef _WIN32
830 SetCurrentDirectory(utf_8to16(saved_wd));
831#else
832 ret = chdir(saved_wd);
833#endif
834 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)
;
835 return (ret == 0);
836}
837
838void
839proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
840{
841 if (ws_pushd(dir))
842 {
843 func(param);
844 ws_popd();
845 }
846}
847
848static bool_Bool
849// NOLINTNEXTLINE(misc-no-recursion)
850proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
851 void *data)
852{
853 proto_node *pnode = tree;
854 proto_node *child;
855 proto_node *current;
856
857 if (func(pnode, data))
858 return true1;
859
860 child = pnode->first_child;
861 while (child != NULL((void*)0)) {
862 /*
863 * The routine we call might modify the child, e.g. by
864 * freeing it, so we get the child's successor before
865 * calling that routine.
866 */
867 current = child;
868 child = current->next;
869 // We recurse here, but we're limited by prefs.gui_max_tree_depth
870 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
871 return true1;
872 }
873
874 return false0;
875}
876
877void
878proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
879 void *data)
880{
881 proto_node *node = tree;
882 proto_node *current;
883
884 if (!node)
885 return;
886
887 node = node->first_child;
888 while (node != NULL((void*)0)) {
889 current = node;
890 node = current->next;
891 func((proto_tree *)current, data);
892 }
893}
894
895static void
896free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
897{
898 GPtrArray *ptrs = (GPtrArray *)value;
899 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
900 header_field_info *hfinfo;
901
902 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", 902, __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", 902, "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", 902, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
903 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
904 /* when a field is referenced by a filter this also
905 affects the refcount for the parent protocol so we need
906 to adjust the refcount for the parent as well
907 */
908 if (hfinfo->parent != -1) {
909 header_field_info *parent_hfinfo;
910 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", 910
, __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", 910, "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", 910, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
911 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
912 }
913 hfinfo->ref_type = HF_REF_TYPE_NONE;
914 }
915
916 g_ptr_array_free(ptrs, true1);
917}
918
919static void
920proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
921{
922 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
923
924 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
925
926 if (finfo) {
927 // The fvalue_t structure was allocated using fvalue_new_pool()
928 // (see new_field_info()) and will be reclaimed when the pool is
929 // freed, so we only release the type-specific data it owns here.
930 fvalue_cleanup(finfo->value);
931 finfo->value = NULL((void*)0);
932 }
933}
934
935void
936proto_tree_reset(proto_tree *tree)
937{
938 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
939
940 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
941
942 /* free tree data */
943 if (tree_data->interesting_hfids) {
944 /* Free all the GPtrArray's in the interesting_hfids hash. */
945 g_hash_table_foreach(tree_data->interesting_hfids,
946 free_GPtrArray_value, NULL((void*)0));
947
948 /* And then remove all values. */
949 g_hash_table_remove_all(tree_data->interesting_hfids);
950 }
951
952 /* Reset track of the number of children */
953 tree_data->count = 0;
954
955 /* Reset our loop checks */
956 tree_data->idle_count_ds_tvb = NULL((void*)0);
957 tree_data->max_start = 0;
958 tree_data->start_idle_count = 0;
959
960 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
961}
962
963/* frees the resources that the dissection a proto_tree uses */
964void
965proto_tree_free(proto_tree *tree)
966{
967 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
968
969 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
970
971 /* free tree data */
972 if (tree_data->interesting_hfids) {
973 /* Free all the GPtrArray's in the interesting_hfids hash. */
974 g_hash_table_foreach(tree_data->interesting_hfids,
975 free_GPtrArray_value, NULL((void*)0));
976
977 /* And then destroy the hash. */
978 g_hash_table_destroy(tree_data->interesting_hfids);
979 }
980
981 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)
;
982
983 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
984}
985
986/* Is the parsing being done for a visible proto_tree or an invisible one?
987 * By setting this correctly, the proto_tree creation is sped up by not
988 * having to call vsnprintf and copy strings around.
989 */
990bool_Bool
991proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
992{
993 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
994
995 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
996
997 return old_visible;
998}
999
1000void
1001proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
1002{
1003 if (tree)
1004 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
1005}
1006
1007/* Assume dissector set only its protocol fields.
1008 This function is called by dissectors and allows the speeding up of filtering
1009 in wireshark; if this function returns false it is safe to reset tree to NULL
1010 and thus skip calling most of the expensive proto_tree_add_...()
1011 functions.
1012 If the tree is visible we implicitly assume the field is referenced.
1013*/
1014bool_Bool
1015proto_field_is_referenced(proto_tree *tree, int proto_id)
1016{
1017 register header_field_info *hfinfo;
1018
1019
1020 if (!tree)
1021 return false0;
1022
1023 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1024 return true1;
1025
1026 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", 1026, __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", 1026,
"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", 1026, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1027 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1028 return true1;
1029
1030 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1031 return true1;
1032
1033 return false0;
1034}
1035
1036
1037/* Finds a record in the hfinfo array by id. */
1038header_field_info *
1039proto_registrar_get_nth(unsigned hfindex)
1040{
1041 register header_field_info *hfinfo;
1042
1043 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", 1043, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1043,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1043, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1044 return hfinfo;
1045}
1046
1047
1048/* Prefix initialization
1049 * this allows for a dissector to register a display filter name prefix
1050 * so that it can delay the initialization of the hf array as long as
1051 * possible.
1052 */
1053
1054/* compute a hash for the part before the dot of a display filter */
1055static unsigned
1056prefix_hash (const void *key) {
1057 /* end the string at the dot and compute its hash */
1058 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1059 char* c = copy;
1060 unsigned tmp;
1061
1062 for (; *c; c++) {
1063 if (*c == '.') {
1064 *c = 0;
1065 break;
1066 }
1067 }
1068
1069 tmp = wmem_str_hash(copy);
1070 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1071 return tmp;
1072}
1073
1074/* are both strings equal up to the end or the dot? */
1075static gboolean
1076prefix_equal (const void *ap, const void *bp) {
1077 const char* a = (const char *)ap;
1078 const char* b = (const char *)bp;
1079
1080 do {
1081 char ac = *a++;
1082 char bc = *b++;
1083
1084 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1085
1086 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1087 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1088
1089 if (ac != bc) return FALSE(0);
1090 } while (1);
1091
1092 return FALSE(0);
1093}
1094
1095/* Register a new prefix for "delayed" initialization of field arrays */
1096void
1097proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1098 if (! prefixes ) {
1099 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1100 }
1101
1102 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1103}
1104
1105/* helper to call all prefix initializers */
1106static gboolean
1107initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1108 ((prefix_initializer_t)v)((const char *)k);
1109 return TRUE(!(0));
1110}
1111
1112/** Initialize every remaining uninitialized prefix. */
1113void
1114proto_initialize_all_prefixes(void) {
1115 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1116}
1117
1118/* Finds a record in the hfinfo array by name.
1119 * If it fails to find it in the already registered fields,
1120 * it tries to find and call an initializer in the prefixes
1121 * table and if so it looks again.
1122 */
1123
1124header_field_info *
1125proto_registrar_get_byname(const char *field_name)
1126{
1127 header_field_info *hfinfo;
1128 prefix_initializer_t pi;
1129
1130 if (!field_name)
1131 return NULL((void*)0);
1132
1133 if (g_strcmp0(field_name, last_field_name) == 0) {
1134 return last_hfinfo;
1135 }
1136
1137 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1138
1139 if (hfinfo) {
1140 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)
;
1141 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1142 last_hfinfo = hfinfo;
1143 return hfinfo;
1144 }
1145
1146 if (!prefixes)
1147 return NULL((void*)0);
1148
1149 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1150 pi(field_name);
1151 g_hash_table_remove(prefixes, field_name);
1152 } else {
1153 return NULL((void*)0);
1154 }
1155
1156 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1157
1158 if (hfinfo) {
1159 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)
;
1160 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1161 last_hfinfo = hfinfo;
1162 }
1163 return hfinfo;
1164}
1165
1166header_field_info*
1167proto_registrar_get_byalias(const char *alias_name)
1168{
1169 if (!alias_name) {
1170 return NULL((void*)0);
1171 }
1172
1173 /* Find our aliased protocol. */
1174 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1175 char *dot = strchr(an_copy, '.');
1176 if (dot) {
1177 *dot = '\0';
1178 }
1179 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1180 if (!proto_pfx) {
1181 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)
;
1182 return NULL((void*)0);
1183 }
1184
1185 /* Construct our aliased field and look it up. */
1186 GString *filter_name = g_string_new(proto_pfx);
1187 if (dot) {
1188 g_string_append_printf(filter_name, ".%s", dot+1);
1189 }
1190 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
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 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)))))
;
1193
1194 return hfinfo;
1195}
1196
1197int
1198proto_registrar_get_id_byname(const char *field_name)
1199{
1200 header_field_info *hfinfo;
1201
1202 hfinfo = proto_registrar_get_byname(field_name);
1203
1204 if (!hfinfo)
1205 return -1;
1206
1207 return hfinfo->id;
1208}
1209
1210static int
1211label_strcat_flags(const header_field_info *hfinfo)
1212{
1213 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1214 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1215
1216 return 0;
1217}
1218
1219static char *
1220format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1221 const uint8_t *bytes, unsigned length, size_t max_str_len)
1222{
1223 char *str = NULL((void*)0);
1224 const uint8_t *p;
1225 bool_Bool is_printable;
1226
1227 if (bytes) {
1228 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1229 /*
1230 * If all bytes are valid and printable UTF-8, show the
1231 * bytes as a string - in quotes to indicate that it's
1232 * a string.
1233 */
1234 if (isprint_utf8_string((const char*)bytes, length)) {
1235 str = wmem_strdup_printf(scope, "\"%.*s\"",
1236 (int)length, bytes);
1237 return str;
1238 }
1239 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1240 /*
1241 * Check whether all bytes are printable.
1242 */
1243 is_printable = true1;
1244 for (p = bytes; p < bytes+length; p++) {
1245 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1246 /* Not printable. */
1247 is_printable = false0;
1248 break;
1249 }
1250 }
1251
1252 /*
1253 * If all bytes are printable ASCII, show the bytes
1254 * as a string - in quotes to indicate that it's
1255 * a string.
1256 */
1257 if (is_printable) {
1258 str = wmem_strdup_printf(scope, "\"%.*s\"",
1259 (int)length, bytes);
1260 return str;
1261 }
1262 }
1263
1264 /*
1265 * Either it's not printable ASCII, or we don't care whether
1266 * it's printable ASCII; show it as hex bytes.
1267 */
1268 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1269 case SEP_DOT:
1270 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1271 break;
1272 case SEP_DASH:
1273 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1274 break;
1275 case SEP_COLON:
1276 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1277 break;
1278 case SEP_SPACE:
1279 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1280 break;
1281 case BASE_NONE:
1282 default:
1283 if (prefs.display_byte_fields_with_spaces) {
1284 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1285 } else {
1286 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1287 }
1288 break;
1289 }
1290 }
1291 else {
1292 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1293 str = wmem_strdup(scope, "<none>");
1294 } else {
1295 str = wmem_strdup(scope, "<MISSING>");
1296 }
1297 }
1298 return str;
1299}
1300
1301static char *
1302format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1303 const uint8_t *bytes, unsigned length)
1304{
1305 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1306}
1307
1308static void
1309ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1310{
1311 subtree_lvl *pushed_tree;
1312
1313 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"
, 1313, "ptvc->pushed_tree_max <= 256-8"))))
;
1314 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1315
1316 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1317 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1317, "pushed_tree != ((void*)0)"
))))
;
1318 ptvc->pushed_tree = pushed_tree;
1319}
1320
1321static void
1322ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1323{
1324 ptvc->pushed_tree = NULL((void*)0);
1325 ptvc->pushed_tree_max = 0;
1326 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", 1326, "ptvc->pushed_tree_index == 0"
))))
;
1327 ptvc->pushed_tree_index = 0;
1328}
1329
1330/* Allocates an initializes a ptvcursor_t with 3 variables:
1331 * proto_tree, tvbuff, and offset. */
1332ptvcursor_t *
1333ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1334{
1335 ptvcursor_t *ptvc;
1336
1337 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1338 ptvc->scope = scope;
1339 ptvc->tree = tree;
1340 ptvc->tvb = tvb;
1341 ptvc->offset = offset;
1342 ptvc->pushed_tree = NULL((void*)0);
1343 ptvc->pushed_tree_max = 0;
1344 ptvc->pushed_tree_index = 0;
1345 return ptvc;
1346}
1347
1348
1349/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1350void
1351ptvcursor_free(ptvcursor_t *ptvc)
1352{
1353 ptvcursor_free_subtree_levels(ptvc);
1354 wmem_free(ptvc->scope, ptvc);
1355}
1356
1357/* Returns tvbuff. */
1358tvbuff_t *
1359ptvcursor_tvbuff(ptvcursor_t *ptvc)
1360{
1361 return ptvc->tvb;
1362}
1363
1364/* Returns current offset. */
1365unsigned
1366ptvcursor_current_offset(ptvcursor_t *ptvc)
1367{
1368 return ptvc->offset;
1369}
1370
1371proto_tree *
1372ptvcursor_tree(ptvcursor_t *ptvc)
1373{
1374 if (!ptvc)
1375 return NULL((void*)0);
1376
1377 return ptvc->tree;
1378}
1379
1380void
1381ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1382{
1383 ptvc->tree = tree;
1384}
1385
1386/* creates a subtree, sets it as the working tree and pushes the old working tree */
1387proto_tree *
1388ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1389{
1390 subtree_lvl *subtree;
1391 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1392 ptvcursor_new_subtree_levels(ptvc);
1393
1394 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1395 subtree->tree = ptvc->tree;
1396 subtree->it= NULL((void*)0);
1397 ptvc->pushed_tree_index++;
1398 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1399}
1400
1401/* pops a subtree */
1402void
1403ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1404{
1405 subtree_lvl *subtree;
1406
1407 if (ptvc->pushed_tree_index <= 0)
1408 return;
1409
1410 ptvc->pushed_tree_index--;
1411 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1412 if (subtree->it != NULL((void*)0))
1413 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1414
1415 ptvc->tree = subtree->tree;
1416}
1417
1418/* saves the current tvb offset and the item in the current subtree level */
1419static void
1420ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1421{
1422 subtree_lvl *subtree;
1423
1424 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", 1424, "ptvc->pushed_tree_index > 0"
))))
;
1425
1426 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1427 subtree->it = it;
1428 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1429}
1430
1431/* Creates a subtree and adds it to the cursor as the working tree but does not
1432 * save the old working tree */
1433proto_tree *
1434ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1435{
1436 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1437 return ptvc->tree;
1438}
1439
1440static proto_tree *
1441ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1442{
1443 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1444 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1445 ptvcursor_subtree_set_item(ptvc, it);
1446 return ptvcursor_tree(ptvc);
1447}
1448
1449/* Add an item to the tree and create a subtree
1450 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1451 * In this case, when the subtree will be closed, the parent item length will
1452 * be equal to the advancement of the cursor since the creation of the subtree.
1453 */
1454proto_tree *
1455ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1456 const unsigned encoding, int ett_subtree)
1457{
1458 proto_item *it;
1459
1460 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1461 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1462}
1463
1464static proto_item *
1465proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1466
1467/* Add a text node to the tree and create a subtree
1468 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1469 * In this case, when the subtree will be closed, the item length will be equal
1470 * to the advancement of the cursor since the creation of the subtree.
1471 */
1472proto_tree *
1473ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1474 int ett_subtree, const char *format, ...)
1475{
1476 proto_item *pi;
1477 va_list ap;
1478 header_field_info *hfinfo;
1479 proto_tree *tree;
1480
1481 tree = ptvcursor_tree(ptvc);
1482
1483 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1484
1485 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", 1485
, __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", 1485, "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", 1485, "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", 1485, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1486
1487 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1488 ptvcursor_current_offset(ptvc), length);
1489
1490 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1490, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1491
1492 va_start(ap, format)__builtin_va_start(ap, format);
1493 proto_tree_set_representation(pi, format, ap);
1494 va_end(ap)__builtin_va_end(ap);
1495
1496 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1497}
1498
1499/* Add a text-only node, leaving it to our caller to fill the text in */
1500static proto_item *
1501proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1502{
1503 proto_item *pi;
1504
1505 if (tree == NULL((void*)0))
1506 return NULL((void*)0);
1507
1508 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1509
1510 return pi;
1511}
1512
1513/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1514proto_item *
1515proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1516 const char *format, ...)
1517{
1518 proto_item *pi;
1519 va_list ap;
1520 header_field_info *hfinfo;
1521
1522 tvb_ensure_bytes_exist(tvb, start, length);
1523
1524 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1525
1526 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", 1526
, __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", 1526, "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", 1526, "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", 1526, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1527
1528 pi = proto_tree_add_text_node(tree, tvb, start, length);
1529
1530 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1530, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1531
1532 va_start(ap, format)__builtin_va_start(ap, format);
1533 proto_tree_set_representation(pi, format, ap);
1534 va_end(ap)__builtin_va_end(ap);
1535
1536 return pi;
1537}
1538
1539/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1540proto_item *
1541proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1542 unsigned length, const char *format, va_list ap)
1543{
1544 proto_item *pi;
1545 header_field_info *hfinfo;
1546
1547 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1548 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1549 * the length to be what's in the tvbuff if length is -1, and the
1550 * minimum of length and what's in the tvbuff if not.
1551 */
1552
1553 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1554
1555 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", 1555
, __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", 1555, "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", 1555, "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", 1555, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1556
1557 pi = proto_tree_add_text_node(tree, tvb, start, length);
1558
1559 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1559, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1560
1561 proto_tree_set_representation(pi, format, ap);
1562
1563 return pi;
1564}
1565
1566/* Add a text-only node that creates a subtree underneath.
1567 */
1568proto_tree *
1569proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1570{
1571 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1572}
1573
1574/* Add a text-only node that creates a subtree underneath.
1575 */
1576proto_tree *
1577proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1578{
1579 proto_tree *pt;
1580 proto_item *pi;
1581 va_list ap;
1582
1583 if (length == -1) {
1584 length = tvb_captured_length_remaining(tvb, start);
1585 }
1586
1587 va_start(ap, format)__builtin_va_start(ap, format);
1588 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1589 va_end(ap)__builtin_va_end(ap);
1590
1591 if (tree_item != NULL((void*)0))
1592 *tree_item = pi;
1593
1594 pt = proto_item_add_subtree(pi, idx);
1595
1596 return pt;
1597}
1598
1599/* Add a text-only node for debugging purposes. The caller doesn't need
1600 * to worry about tvbuff, start, or length. Debug message gets sent to
1601 * STDOUT, too */
1602proto_item *
1603proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1604{
1605 proto_item *pi;
1606 va_list ap;
1607
1608 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1609
1610 if (pi) {
1611 va_start(ap, format)__builtin_va_start(ap, format);
1612 proto_tree_set_representation(pi, format, ap);
1613 va_end(ap)__builtin_va_end(ap);
1614 }
1615 va_start(ap, format)__builtin_va_start(ap, format);
1616 vprintf(format, ap);
1617 va_end(ap)__builtin_va_end(ap);
1618 printf("\n");
1619
1620 return pi;
1621}
1622
1623proto_item *
1624proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1625{
1626 proto_item *pi;
1627 header_field_info *hfinfo;
1628
1629 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1630
1631 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", 1631
, __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", 1631, "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", 1631, "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", 1631, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1632
1633 pi = proto_tree_add_text_node(tree, tvb, start, length);
1634
1635 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1635, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1636
1637 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1638
1639 return pi;
1640}
1641
1642proto_item *
1643proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1644{
1645 proto_item *pi;
1646 header_field_info *hfinfo;
1647 char *str;
1648
1649 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1650
1651 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", 1651
, __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", 1651, "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", 1651, "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", 1651, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1652
1653 pi = proto_tree_add_text_node(tree, tvb, start, length);
1654
1655 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1655, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1656
1657 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1658 proto_item_set_text(pi, "%s", str);
1659 wmem_free(NULL((void*)0), str);
1660
1661 return pi;
1662}
1663
1664void proto_report_dissector_bug(const char *format, ...)
1665{
1666 va_list args;
1667
1668 if (wireshark_abort_on_dissector_bug) {
1669 /*
1670 * Try to have the error message show up in the crash
1671 * information.
1672 */
1673 va_start(args, format)__builtin_va_start(args, format);
1674 ws_vadd_crash_info(format, args);
1675 va_end(args)__builtin_va_end(args);
1676
1677 /*
1678 * Print the error message.
1679 */
1680 va_start(args, format)__builtin_va_start(args, format);
1681 vfprintf(stderrstderr, format, args);
1682 va_end(args)__builtin_va_end(args);
1683 putc('\n', stderrstderr);
1684
1685 /*
1686 * And crash.
1687 */
1688 abort();
1689 } else {
1690 va_start(args, format)__builtin_va_start(args, format);
1691 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1692 va_end(args)__builtin_va_end(args);
1693 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1693
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1694 }
1695}
1696
1697/* We could probably get away with changing is_error to a minimum length value. */
1698static void
1699report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1700{
1701 if (is_error) {
1702 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1703 } else {
1704 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1705 }
1706
1707 if (is_error) {
1708 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1709 }
1710}
1711
1712static uint32_t
1713get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1714{
1715 uint32_t value;
1716 bool_Bool length_error;
1717
1718 switch (length) {
1719
1720 case 1:
1721 value = tvb_get_uint8(tvb, offset);
1722 if (encoding & ENC_ZIGBEE0x40000000) {
1723 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1724 value = 0;
1725 }
1726 }
1727 break;
1728
1729 case 2:
1730 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1731 : tvb_get_ntohs(tvb, offset);
1732 if (encoding & ENC_ZIGBEE0x40000000) {
1733 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1734 value = 0;
1735 }
1736 }
1737 break;
1738
1739 case 3:
1740 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1741 : tvb_get_ntoh24(tvb, offset);
1742 break;
1743
1744 case 4:
1745 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1746 : tvb_get_ntohl(tvb, offset);
1747 break;
1748
1749 default:
1750 if (length < 1) {
1751 length_error = true1;
1752 value = 0;
1753 } else {
1754 length_error = false0;
1755 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1756 : tvb_get_ntohl(tvb, offset);
1757 }
1758 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1759 break;
1760 }
1761 return value;
1762}
1763
1764static inline uint64_t
1765get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1766{
1767 uint64_t value;
1768
1769 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1770
1771 if (length < 1 || length > 8) {
1772 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1773 }
1774
1775 return value;
1776}
1777
1778static int32_t
1779get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1780{
1781 int32_t value;
1782 bool_Bool length_error;
1783
1784 switch (length) {
1785
1786 case 1:
1787 value = tvb_get_int8(tvb, offset);
1788 break;
1789
1790 case 2:
1791 value = encoding ? tvb_get_letohis(tvb, offset)
1792 : tvb_get_ntohis(tvb, offset);
1793 break;
1794
1795 case 3:
1796 value = encoding ? tvb_get_letohi24(tvb, offset)
1797 : tvb_get_ntohi24(tvb, offset);
1798 break;
1799
1800 case 4:
1801 value = encoding ? tvb_get_letohil(tvb, offset)
1802 : tvb_get_ntohil(tvb, offset);
1803 break;
1804
1805 default:
1806 if (length < 1) {
1807 length_error = true1;
1808 value = 0;
1809 } else {
1810 length_error = false0;
1811 value = encoding ? tvb_get_letohil(tvb, offset)
1812 : tvb_get_ntohil(tvb, offset);
1813 }
1814 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1815 break;
1816 }
1817 return value;
1818}
1819
1820/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1821 * be cast-able as a int64_t. This is weird, but what the code has always done.
1822 */
1823static inline uint64_t
1824get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1825{
1826 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1827
1828 switch (length) {
1829 case 7:
1830 value = ws_sign_ext64(value, 56);
1831 break;
1832 case 6:
1833 value = ws_sign_ext64(value, 48);
1834 break;
1835 case 5:
1836 value = ws_sign_ext64(value, 40);
1837 break;
1838 case 4:
1839 value = ws_sign_ext64(value, 32);
1840 break;
1841 case 3:
1842 value = ws_sign_ext64(value, 24);
1843 break;
1844 case 2:
1845 value = ws_sign_ext64(value, 16);
1846 break;
1847 case 1:
1848 value = ws_sign_ext64(value, 8);
1849 break;
1850 }
1851
1852 return value;
1853}
1854
1855/* For FT_STRING */
1856static inline const uint8_t *
1857get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1858 int length, unsigned *ret_length, const unsigned encoding)
1859{
1860 if (length == -1) {
1861 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1862 } else {
1863 *ret_length = length;
1864 }
1865 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1866}
1867
1868/* For FT_STRINGZ */
1869static inline const uint8_t *
1870get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1871 unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1872{
1873 const uint8_t *value;
1874
1875 if (length < -1) {
1876 report_type_length_mismatch(tree, "a string", length, true1);
1877 }
1878
1879 /* XXX - Ideally, every "null-terminated string which fits into a
1880 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1881 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1882 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1883 * as unknown length as well (since there is a trailing '\0', the real
1884 * length is never zero), allowing switching to unsigned lengths.
1885 */
1886 if (length == -1) {
1887 /* This can throw an exception */
1888 value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1889 } else {
1890 /* In this case, length signifies the length of the string.
1891 *
1892 * This could either be a null-padded string, which doesn't
1893 * necessarily have a '\0' at the end, or a null-terminated
1894 * string, with a trailing '\0'. (Yes, there are cases
1895 * where you have a string that's both counted and null-
1896 * terminated.)
1897 *
1898 * In the first case, we must allocate a buffer of length
1899 * "length+1", to make room for a trailing '\0'.
1900 *
1901 * In the second case, we don't assume that there is a
1902 * trailing '\0' there, as the packet might be malformed.
1903 * (XXX - should we throw an exception if there's no
1904 * trailing '\0'?) Therefore, we allocate a buffer of
1905 * length "length+1", and put in a trailing '\0', just to
1906 * be safe.
1907 *
1908 * (XXX - this would change if we made string values counted
1909 * rather than null-terminated.)
1910 */
1911 *ret_length = length;
1912 value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1913 }
1914 return value;
1915}
1916
1917/* For FT_UINT_STRING */
1918static inline const uint8_t *
1919get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1920 tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1921 const unsigned encoding)
1922{
1923 uint32_t n;
1924 const uint8_t *value;
1925
1926 /* I believe it's ok if this is called with a NULL tree */
1927 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1928 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1929 *ret_length = length + n;
1930 return value;
1931}
1932
1933/* For FT_STRINGZPAD */
1934static inline const uint8_t *
1935get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1936 int length, unsigned *ret_length, const unsigned encoding)
1937{
1938 /*
1939 * XXX - currently, string values are null-
1940 * terminated, so a "zero-padded" string
1941 * isn't special. If we represent string
1942 * values as something that includes a counted
1943 * array of bytes, we'll need to strip the
1944 * trailing NULs.
1945 */
1946 if (length == -1) {
1947 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1948 } else {
1949 *ret_length = length;
1950 }
1951 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1952}
1953
1954/* For FT_STRINGZTRUNC */
1955static inline const uint8_t *
1956get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1957 int length, unsigned *ret_length, const unsigned encoding)
1958{
1959 /*
1960 * XXX - currently, string values are null-
1961 * terminated, so a "zero-truncated" string
1962 * isn't special. If we represent string
1963 * values as something that includes a counted
1964 * array of bytes, we'll need to strip everything
1965 * starting with the terminating NUL.
1966 */
1967 if (length == -1) {
1968 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1969 } else {
1970 *ret_length = length;
1971 }
1972 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1973}
1974
1975/*
1976 * Deltas between the epochs for various non-UN*X time stamp formats and
1977 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1978 * stamp format.
1979 */
1980
1981/*
1982 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1983 * XXX - if it's OK if this is unsigned, can we just use
1984 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1985 */
1986#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1987
1988/*
1989 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1990 */
1991#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1992
1993/* this can be called when there is no tree, so tree may be null */
1994static void
1995get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1996 const int length, const unsigned encoding, nstime_t *time_stamp,
1997 const bool_Bool is_relative)
1998{
1999 uint32_t tmpsecs;
2000 uint64_t tmp64secs;
2001 uint64_t todusecs;
2002
2003 switch (encoding) {
2004
2005 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
2006 /*
2007 * If the length is 16, 8-byte seconds, followed
2008 * by 8-byte fractional time in nanoseconds,
2009 * both big-endian.
2010 *
2011 * If the length is 12, 8-byte seconds, followed
2012 * by 4-byte fractional time in nanoseconds,
2013 * both big-endian.
2014 *
2015 * If the length is 8, 4-byte seconds, followed
2016 * by 4-byte fractional time in nanoseconds,
2017 * both big-endian.
2018 *
2019 * For absolute times, the seconds are seconds
2020 * since the UN*X epoch.
2021 */
2022 if (length == 16) {
2023 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2024 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2025 } else if (length == 12) {
2026 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2027 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2028 } else if (length == 8) {
2029 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2030 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2031 } else if (length == 4) {
2032 /*
2033 * Backwards compatibility.
2034 * ENC_TIME_SECS_NSECS is 0; using
2035 * ENC_BIG_ENDIAN by itself with a 4-byte
2036 * time-in-seconds value was done in the
2037 * past.
2038 */
2039 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2040 time_stamp->nsecs = 0;
2041 } else {
2042 time_stamp->secs = 0;
2043 time_stamp->nsecs = 0;
2044 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2045 }
2046 break;
2047
2048 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2049 /*
2050 * If the length is 16, 8-byte seconds, followed
2051 * by 8-byte fractional time in nanoseconds,
2052 * both little-endian.
2053 *
2054 * If the length is 12, 8-byte seconds, followed
2055 * by 4-byte fractional time in nanoseconds,
2056 * both little-endian.
2057 *
2058 * If the length is 8, 4-byte seconds, followed
2059 * by 4-byte fractional time in nanoseconds,
2060 * both little-endian.
2061 *
2062 * For absolute times, the seconds are seconds
2063 * since the UN*X epoch.
2064 */
2065 if (length == 16) {
2066 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2067 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2068 } else if (length == 12) {
2069 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2070 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2071 } else if (length == 8) {
2072 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2073 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2074 } else if (length == 4) {
2075 /*
2076 * Backwards compatibility.
2077 * ENC_TIME_SECS_NSECS is 0; using
2078 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2079 * time-in-seconds value was done in the
2080 * past.
2081 */
2082 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2083 time_stamp->nsecs = 0;
2084 } else {
2085 time_stamp->secs = 0;
2086 time_stamp->nsecs = 0;
2087 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2088 }
2089 break;
2090
2091 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2092 /*
2093 * NTP time stamp, big-endian.
2094 * Only supported for absolute times.
2095 */
2096 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2096, "!is_relative"
))))
;
2097
2098 /* We need a temporary variable here so the unsigned math
2099 * works correctly (for years > 2036 according to RFC 2030
2100 * chapter 3).
2101 *
2102 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2103 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2104 * If bit 0 is not set, the time is in the range 2036-2104 and
2105 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2106 */
2107 tmpsecs = tvb_get_ntohl(tvb, start);
2108 if ((tmpsecs & 0x80000000) != 0)
2109 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2110 else
2111 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2112
2113 if (length == 8) {
2114 tmp64secs = tvb_get_ntoh64(tvb, start);
2115 if (tmp64secs == 0) {
2116 //This is "NULL" time
2117 time_stamp->secs = 0;
2118 time_stamp->nsecs = 0;
2119 } else {
2120 /*
2121 * Convert 1/2^32s of a second to
2122 * nanoseconds.
2123 */
2124 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2125 }
2126 } else if (length == 4) {
2127 /*
2128 * Backwards compatibility.
2129 */
2130 if (tmpsecs == 0) {
2131 //This is "NULL" time
2132 time_stamp->secs = 0;
2133 }
2134 time_stamp->nsecs = 0;
2135 } else {
2136 time_stamp->secs = 0;
2137 time_stamp->nsecs = 0;
2138 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2139 }
2140 break;
2141
2142 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2143 /*
2144 * NTP time stamp, little-endian.
2145 * Only supported for absolute times.
2146 *
2147 * NTP doesn't use this, because it's an Internet format
2148 * and hence big-endian. Any implementation must decide
2149 * whether the NTP timestamp is a 64-bit unsigned fixed
2150 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2151 * with a 32-bit unsigned seconds field followed by a
2152 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2153 * the previous two).
2154 *
2155 * XXX: We do the latter, but no dissector uses this format.
2156 * OTOH, ERF timestamps do the former, so perhaps we
2157 * should switch the interpretation so that packet-erf.c
2158 * could use this directly? (ENC_TIME_RTPS is this 64-bit
2159 * struct with two 32-bit fields, but with the UN*X epoch.)
2160 */
2161 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2161, "!is_relative"
))))
;
2162
2163 /* We need a temporary variable here so the unsigned math
2164 * works correctly (for years > 2036 according to RFC 2030
2165 * chapter 3).
2166 *
2167 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2168 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2169 * If bit 0 is not set, the time is in the range 2036-2104 and
2170 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2171 */
2172 tmpsecs = tvb_get_letohl(tvb, start);
2173 if ((tmpsecs & 0x80000000) != 0)
2174 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2175 else
2176 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2177
2178 if (length == 8) {
2179 tmp64secs = tvb_get_letoh64(tvb, start);
2180 if (tmp64secs == 0) {
2181 //This is "NULL" time
2182 time_stamp->secs = 0;
2183 time_stamp->nsecs = 0;
2184 } else {
2185 /*
2186 * Convert 1/2^32s of a second to
2187 * nanoseconds.
2188 */
2189 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2190 }
2191 } else if (length == 4) {
2192 /*
2193 * Backwards compatibility.
2194 */
2195 if (tmpsecs == 0) {
2196 //This is "NULL" time
2197 time_stamp->secs = 0;
2198 }
2199 time_stamp->nsecs = 0;
2200 } else {
2201 time_stamp->secs = 0;
2202 time_stamp->nsecs = 0;
2203 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2204 }
2205 break;
2206
2207 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2208 /*
2209 * S/3x0 and z/Architecture TOD clock time stamp,
2210 * big-endian. The epoch is January 1, 1900,
2211 * 00:00:00 (proleptic?) UTC.
2212 *
2213 * Only supported for absolute times.
2214 */
2215 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2215, "!is_relative"
))))
;
2216 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2216, "length == 8"
))))
;
2217
2218 if (length == 8) {
2219 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2220 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2221 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2222 } else {
2223 time_stamp->secs = 0;
2224 time_stamp->nsecs = 0;
2225 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2226 }
2227 break;
2228
2229 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2230 /*
2231 * S/3x0 and z/Architecture TOD clock time stamp,
2232 * little-endian. The epoch is January 1, 1900,
2233 * 00:00:00 (proleptic?) UTC.
2234 *
2235 * Only supported for absolute times.
2236 */
2237 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2237, "!is_relative"
))))
;
2238
2239 if (length == 8) {
2240 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2241 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2242 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2243 } else {
2244 time_stamp->secs = 0;
2245 time_stamp->nsecs = 0;
2246 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2247 }
2248 break;
2249
2250 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2251 /*
2252 * Time stamp using the same seconds/fraction format
2253 * as NTP, but with the origin of the time stamp being
2254 * the UNIX epoch rather than the NTP epoch; big-
2255 * endian.
2256 *
2257 * Only supported for absolute times.
2258 */
2259 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2259, "!is_relative"
))))
;
2260
2261 if (length == 8) {
2262 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2263 /*
2264 * Convert 1/2^32s of a second to nanoseconds.
2265 */
2266 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2267 } else {
2268 time_stamp->secs = 0;
2269 time_stamp->nsecs = 0;
2270 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2271 }
2272 break;
2273
2274 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2275 /*
2276 * Time stamp using the same seconds/fraction format
2277 * as NTP, but with the origin of the time stamp being
2278 * the UNIX epoch rather than the NTP epoch; little-
2279 * endian.
2280 *
2281 * Only supported for absolute times.
2282 *
2283 * The RTPS specification explicitly supports Little
2284 * Endian encoding. In one place, it states that its
2285 * Time_t representation "is the one defined by ...
2286 * RFC 1305", but in another explicitly defines it as
2287 * a struct consisting of an 32 bit unsigned seconds
2288 * field and a 32 bit unsigned fraction field, not a 64
2289 * bit fixed point, so we do that here.
2290 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2291 */
2292 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2292, "!is_relative"
))))
;
2293
2294 if (length == 8) {
2295 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2296 /*
2297 * Convert 1/2^32s of a second to nanoseconds.
2298 */
2299 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2300 } else {
2301 time_stamp->secs = 0;
2302 time_stamp->nsecs = 0;
2303 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2304 }
2305 break;
2306
2307 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2308 /*
2309 * MIP6 time stamp, big-endian.
2310 * A 64-bit unsigned integer field containing a timestamp. The
2311 * value indicates the number of seconds since January 1, 1970,
2312 * 00:00 UTC, by using a fixed point format. In this format, the
2313 * integer number of seconds is contained in the first 48 bits of
2314 * the field, and the remaining 16 bits indicate the number of
2315 * 1/65536 fractions of a second.
2316
2317 * Only supported for absolute times.
2318 */
2319 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2319, "!is_relative"
))))
;
2320
2321 if (length == 8) {
2322 /* We need a temporary variable here so the casting and fractions
2323 * of a second work correctly.
2324 */
2325 tmp64secs = tvb_get_ntoh48(tvb, start);
2326 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2327 tmpsecs <<= 16;
2328
2329 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2330 //This is "NULL" time
2331 time_stamp->secs = 0;
2332 time_stamp->nsecs = 0;
2333 } else {
2334 time_stamp->secs = (time_t)tmp64secs;
2335 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2336 }
2337 } else {
2338 time_stamp->secs = 0;
2339 time_stamp->nsecs = 0;
2340 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2341 }
2342 break;
2343
2344 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2345 /*
2346 * If the length is 16, 8-byte seconds, followed
2347 * by 8-byte fractional time in microseconds,
2348 * both big-endian.
2349 *
2350 * If the length is 12, 8-byte seconds, followed
2351 * by 4-byte fractional time in microseconds,
2352 * both big-endian.
2353 *
2354 * If the length is 8, 4-byte seconds, followed
2355 * by 4-byte fractional time in microseconds,
2356 * both big-endian.
2357 *
2358 * For absolute times, the seconds are seconds
2359 * since the UN*X epoch.
2360 */
2361 if (length == 16) {
2362 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2363 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2364 } else if (length == 12) {
2365 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2366 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2367 } else if (length == 8) {
2368 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2369 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2370 } else {
2371 time_stamp->secs = 0;
2372 time_stamp->nsecs = 0;
2373 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2374 }
2375 break;
2376
2377 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2378 /*
2379 * If the length is 16, 8-byte seconds, followed
2380 * by 8-byte fractional time in microseconds,
2381 * both little-endian.
2382 *
2383 * If the length is 12, 8-byte seconds, followed
2384 * by 4-byte fractional time in microseconds,
2385 * both little-endian.
2386 *
2387 * If the length is 8, 4-byte seconds, followed
2388 * by 4-byte fractional time in microseconds,
2389 * both little-endian.
2390 *
2391 * For absolute times, the seconds are seconds
2392 * since the UN*X epoch.
2393 */
2394 if (length == 16) {
2395 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2396 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2397 } else if (length == 12) {
2398 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2399 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2400 } else if (length == 8) {
2401 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2402 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2403 } else {
2404 time_stamp->secs = 0;
2405 time_stamp->nsecs = 0;
2406 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2407 }
2408 break;
2409
2410 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2411 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2412 /*
2413 * Seconds, 1 to 8 bytes.
2414 * For absolute times, it's seconds since the
2415 * UN*X epoch.
2416 */
2417 if (length >= 1 && length <= 8) {
2418 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2419 time_stamp->nsecs = 0;
2420 } else {
2421 time_stamp->secs = 0;
2422 time_stamp->nsecs = 0;
2423 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2424 }
2425 break;
2426
2427 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2428 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2429 /*
2430 * Milliseconds, 1 to 8 bytes.
2431 * For absolute times, it's milliseconds since the
2432 * UN*X epoch.
2433 */
2434 if (length >= 1 && length <= 8) {
2435 uint64_t msecs;
2436
2437 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2438 time_stamp->secs = (time_t)(msecs / 1000);
2439 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2440 } else {
2441 time_stamp->secs = 0;
2442 time_stamp->nsecs = 0;
2443 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2444 }
2445 break;
2446
2447 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2448 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2449 /*
2450 * Microseconds, 1 to 8 bytes.
2451 * For absolute times, it's microseconds since the
2452 * UN*X epoch.
2453 */
2454 if (length >= 1 && length <= 8) {
2455 uint64_t usecs;
2456
2457 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2458 time_stamp->secs = (time_t)(usecs / 1000000);
2459 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2460 } else {
2461 time_stamp->secs = 0;
2462 time_stamp->nsecs = 0;
2463 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2464 }
2465 break;
2466
2467 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2468 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2469 /*
2470 * nanoseconds, 1 to 8 bytes.
2471 * For absolute times, it's nanoseconds since the
2472 * UN*X epoch.
2473 */
2474
2475 if (length >= 1 && length <= 8) {
2476 uint64_t nsecs;
2477
2478 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2479 time_stamp->secs = (time_t)(nsecs / 1000000000);
2480 time_stamp->nsecs = (int)(nsecs % 1000000000);
2481 } else {
2482 time_stamp->secs = 0;
2483 time_stamp->nsecs = 0;
2484 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2485 }
2486 break;
2487
2488 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2489 /*
2490 * 1/64ths of a second since the UN*X epoch,
2491 * big-endian.
2492 *
2493 * Only supported for absolute times.
2494 */
2495 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2495, "!is_relative"
))))
;
2496
2497 if (length == 8) {
2498 /*
2499 * The upper 48 bits are seconds since the
2500 * UN*X epoch.
2501 */
2502 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2503 /*
2504 * The lower 16 bits are 1/2^16s of a second;
2505 * convert them to nanoseconds.
2506 *
2507 * XXX - this may give the impression of higher
2508 * precision than you actually get.
2509 */
2510 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2511 } else {
2512 time_stamp->secs = 0;
2513 time_stamp->nsecs = 0;
2514 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2515 }
2516 break;
2517
2518 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2519 /*
2520 * 1/64ths of a second since the UN*X epoch,
2521 * little-endian.
2522 *
2523 * Only supported for absolute times.
2524 */
2525 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2525, "!is_relative"
))))
;
2526
2527 if (length == 8) {
2528 /*
2529 * XXX - this is assuming that, if anybody
2530 * were ever to use this format - RFC 3971
2531 * doesn't, because that's an Internet
2532 * protocol, and those use network byte
2533 * order, i.e. big-endian - they'd treat it
2534 * as a 64-bit count of 1/2^16s of a second,
2535 * putting the upper 48 bits at the end.
2536 *
2537 * The lower 48 bits are seconds since the
2538 * UN*X epoch.
2539 */
2540 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2541 /*
2542 * The upper 16 bits are 1/2^16s of a second;
2543 * convert them to nanoseconds.
2544 *
2545 * XXX - this may give the impression of higher
2546 * precision than you actually get.
2547 */
2548 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2549 } else {
2550 time_stamp->secs = 0;
2551 time_stamp->nsecs = 0;
2552 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2553 }
2554 break;
2555
2556 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2557 /*
2558 * NTP time stamp, with 1-second resolution (i.e.,
2559 * seconds since the NTP epoch), big-endian.
2560 * Only supported for absolute times.
2561 */
2562 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2562, "!is_relative"
))))
;
2563
2564 if (length == 4) {
2565 /*
2566 * We need a temporary variable here so the unsigned math
2567 * works correctly (for years > 2036 according to RFC 2030
2568 * chapter 3).
2569 *
2570 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2571 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2572 * If bit 0 is not set, the time is in the range 2036-2104 and
2573 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2574 */
2575 tmpsecs = tvb_get_ntohl(tvb, start);
2576 if ((tmpsecs & 0x80000000) != 0)
2577 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2578 else
2579 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2580 time_stamp->nsecs = 0;
2581 } else {
2582 time_stamp->secs = 0;
2583 time_stamp->nsecs = 0;
2584 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2585 }
2586 break;
2587
2588 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2589 /*
2590 * NTP time stamp, with 1-second resolution (i.e.,
2591 * seconds since the NTP epoch), little-endian.
2592 * Only supported for absolute times.
2593 */
2594 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2594, "!is_relative"
))))
;
2595
2596 /*
2597 * We need a temporary variable here so the unsigned math
2598 * works correctly (for years > 2036 according to RFC 2030
2599 * chapter 3).
2600 *
2601 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2602 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2603 * If bit 0 is not set, the time is in the range 2036-2104 and
2604 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2605 */
2606 if (length == 4) {
2607 tmpsecs = tvb_get_letohl(tvb, start);
2608 if ((tmpsecs & 0x80000000) != 0)
2609 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2610 else
2611 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2612 time_stamp->nsecs = 0;
2613 } else {
2614 time_stamp->secs = 0;
2615 time_stamp->nsecs = 0;
2616 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2617 }
2618 break;
2619
2620 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2621 /*
2622 * Milliseconds, 6 to 8 bytes.
2623 * For absolute times, it's milliseconds since the
2624 * NTP epoch.
2625 *
2626 * ETSI TS 129.274 8.119 defines this as:
2627 * "a 48 bit unsigned integer in network order format
2628 * ...encoded as the number of milliseconds since
2629 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2630 * rounded value of 1000 x the value of the 64-bit
2631 * timestamp (Seconds + (Fraction / (1<<32))) defined
2632 * in clause 6 of IETF RFC 5905."
2633 *
2634 * Taken literally, the part after "i.e." would
2635 * mean that the value rolls over before reaching
2636 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2637 * when the 64 bit timestamp rolls over, and we have
2638 * to pick an NTP Era equivalence class to support
2639 * (such as 1968-01-20 to 2104-02-06).
2640 *
2641 * OTOH, the extra room might be used to store Era
2642 * information instead, in which case times until
2643 * 10819-08-03 can be represented with 6 bytes without
2644 * ambiguity. We handle both implementations, and assume
2645 * that times before 1968-01-20 are not represented.
2646 *
2647 * Only 6 bytes or more makes sense as an absolute
2648 * time. 5 bytes or fewer could express a span of
2649 * less than 35 years, either 1900-1934 or 2036-2070.
2650 */
2651 if (length >= 6 && length <= 8) {
2652 uint64_t msecs;
2653
2654 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2655 tmp64secs = (msecs / 1000);
2656 /*
2657 * Assume that times in the first half of NTP
2658 * Era 0 really represent times in the NTP
2659 * Era 1.
2660 */
2661 if (tmp64secs >= 0x80000000)
2662 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2663 else
2664 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2665 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2666 }
2667 else {
2668 time_stamp->secs = 0;
2669 time_stamp->nsecs = 0;
2670 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2671 }
2672 break;
2673
2674 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2675 /*
2676 * MP4 file time stamps, big-endian.
2677 * Only supported for absolute times.
2678 */
2679 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2679, "!is_relative"
))))
;
2680
2681 if (length == 8) {
2682 tmp64secs = tvb_get_ntoh64(tvb, start);
2683 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2684 time_stamp->nsecs = 0;
2685 } else if (length == 4) {
2686 tmpsecs = tvb_get_ntohl(tvb, start);
2687 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2688 time_stamp->nsecs = 0;
2689 } else {
2690 time_stamp->secs = 0;
2691 time_stamp->nsecs = 0;
2692 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2693 }
2694 break;
2695
2696 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2697 /*
2698 * Zigbee ZCL time stamps, big-endian.
2699 * Only supported for absolute times.
2700 */
2701 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2701, "!is_relative"
))))
;
2702
2703 if (length == 8) {
2704 tmp64secs = tvb_get_ntoh64(tvb, start);
2705 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))
) {
2706 /* There are several other possible choices for what to do
2707 * with overflow; make sure to coordinate with whatever
2708 * packet-zbee-zcl.h does. */
2709 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))))))
;
2710 }
2711 time_stamp->nsecs = 0;
2712 } else if (length == 4) {
2713 tmpsecs = tvb_get_ntohl(tvb, start);
2714 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))
) {
2715 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))))))
;
2716 }
2717 time_stamp->nsecs = 0;
2718 } else {
2719 time_stamp->secs = 0;
2720 time_stamp->nsecs = 0;
2721 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2722 }
2723 break;
2724
2725 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2726 /*
2727 * Zigbee ZCL time stamps, little-endian.
2728 * Only supported for absolute times.
2729 */
2730 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2730, "!is_relative"
))))
;
2731
2732 if (length == 8) {
2733 tmp64secs = tvb_get_letoh64(tvb, start);
2734 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))
) {
2735 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))))))
;
2736 }
2737 time_stamp->nsecs = 0;
2738 } else if (length == 4) {
2739 tmpsecs = tvb_get_letohl(tvb, start);
2740 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))
) {
2741 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))))))
;
2742 }
2743 time_stamp->nsecs = 0;
2744 } else {
2745 time_stamp->secs = 0;
2746 time_stamp->nsecs = 0;
2747 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2748 }
2749 break;
2750
2751 case ENC_TIME_WINDOWS0x00000034 | ENC_BIG_ENDIAN0x00000000:
2752 /*
2753 * WINDOWS FILETIME, big-endian.
2754 * Only supported for absolute times.
2755 * A FILETIME is a struct with the low 32-bits followed
2756 * by the high 32-bits:
2757 * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2758 * There exist cases where the value is stored in a
2759 * 64-bit integer:
2760 * (See epan/dissectors/pidl/samr/samr.idl "NTTIME_hyper last_password_change;"
2761 * which is confirmed as "LARGE_INTEGER PasswordLastSet;" in
2762 * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1cd138b9-cc1b-4706-b115-49e53189e32e
2763 * That doesn't make a difference when retrieving little-endian,
2764 * because tvb_get_letoh64 handles unaligned accesses and it's
2765 * otherwise the same. However, for big-endian, it does matter,
2766 * analogous to the ENC_TIME_NTP little-endian case. We use the
2767 * struct version, but that means that this MUST NOT be used
2768 * for dissect_nttime_hyper in packet-windows-common.h, at
2769 * least
2770 */
2771 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2771, "!is_relative"
))))
;
2772
2773 if (length == 8) {
2774 tmp64secs = tvb_get_ntoh64(tvb, start); // Really 100-ns units
2775 if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2776 // With 32-bit time_t, this could overflow in
2777 // either direction. We should probably add some
2778 // kind of time overflow expert item to all
2779 // encodings.
2780 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))))))
;
2781 time_stamp->nsecs = 0;
2782 }
2783 } else {
2784 time_stamp->secs = 0;
2785 time_stamp->nsecs = 0;
2786 report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2787 }
2788 break;
2789
2790 case ENC_TIME_WINDOWS0x00000034 | ENC_LITTLE_ENDIAN0x80000000:
2791 /*
2792 * WINDOWS FILETIME, big-endian.
2793 * Only supported for absolute times.
2794 * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2795 */
2796 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2796, "!is_relative"
))))
;
2797
2798 if (length == 8) {
2799 tmp64secs = tvb_get_letoh64(tvb, start); // Really 100-ns units
2800 if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2801 // With 32-bit time_t, this could overflow in
2802 // either direction. We should probably add some
2803 // kind of time overflow expert item to all
2804 // encodings.
2805 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))))))
;
2806 time_stamp->nsecs = 0;
2807 }
2808 } else {
2809 time_stamp->secs = 0;
2810 time_stamp->nsecs = 0;
2811 report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2812 }
2813 break;
2814 default:
2815 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2815))
;
2816 break;
2817 }
2818}
2819
2820static void
2821tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2822{
2823 const header_field_info *hfinfo = fi->hfinfo;
2824
2825 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2826 GPtrArray *ptrs = NULL((void*)0);
2827
2828 if (tree_data->interesting_hfids == NULL((void*)0)) {
2829 /* Initialize the hash because we now know that it is needed */
2830 tree_data->interesting_hfids =
2831 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2832 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2833 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2834 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2835 }
2836
2837 if (!ptrs) {
2838 /* First element triggers the creation of pointer array */
2839 ptrs = g_ptr_array_new();
2840 g_hash_table_insert(tree_data->interesting_hfids,
2841 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2842 }
2843
2844 g_ptr_array_add(ptrs, fi);
2845 }
2846}
2847
2848
2849/*
2850 * Validates that field length bytes are available starting from
2851 * start (pos/neg). Throws an exception if they aren't.
2852 */
2853static void
2854test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2855 unsigned start, int length, const unsigned encoding)
2856{
2857 int size = length;
2858
2859 if (!tvb)
2860 return;
2861
2862 if ((hfinfo->type == FT_STRINGZ) ||
2863 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2864 (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
))
))) {
2865 /* If we're fetching until the end of the TVB, only validate
2866 * that the offset is within range.
2867 */
2868 if (length == -1)
2869 size = 0;
2870 }
2871
2872 tvb_ensure_bytes_exist(tvb, start, size);
2873}
2874
2875static void
2876detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2877{
2878 bool_Bool found_stray_character = false0;
2879
2880 if (!string)
2881 return;
2882
2883 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2884 case ENC_ASCII0x00000000:
2885 case ENC_UTF_80x00000002:
2886 for (int i = (int)strlen(string); i < length; i++) {
2887 if (string[i] != '\0') {
2888 found_stray_character = true1;
2889 break;
2890 }
2891 }
2892 break;
2893
2894 default:
2895 break;
2896 }
2897
2898 if (found_stray_character) {
2899 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2900 }
2901}
2902
2903/* Add an item to a proto_tree, using the text label registered to that item;
2904 the item is extracted from the tvbuff handed to it. */
2905static proto_item *
2906proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2907 tvbuff_t *tvb, unsigned start, int length,
2908 unsigned encoding)
2909{
2910 proto_item *pi;
2911 uint32_t value, n;
2912 uint64_t value64;
2913 ws_in4_addr ipv4_value;
2914 float floatval;
2915 double doubleval;
2916 const char *stringval = NULL((void*)0);
2917 nstime_t time_stamp;
2918 bool_Bool length_error;
2919 unsigned item_length;
1
'item_length' declared without an initial value
2920
2921 // new_fi->value is allocated from the packet-scoped pool (see
2922 // new_field_info()), so if a tvbuff accessor below throws before the
2923 // node is added to the tree the fvalue_t structure is still reclaimed
2924 // when the pool is freed; no explicit cleanup handler is needed. This
2925 // relies on the invariant that the type-specific data an fvalue owns
2926 // (byte arrays, string buffers, ...) is only allocated *after* the
2927 // throwing tvbuff read that produced it succeeds, so nothing that would
2928 // need fvalue_cleanup() is ever leaked on the exception path.
2929 switch (new_fi->hfinfo->type) {
2
Control jumps to 'case FT_NONE:' at line 2930
2930 case FT_NONE:
2931 /* no value to set for FT_NONE */
2932 break;
2933
2934 case FT_PROTOCOL:
2935 /* Set the protocol_tvb via the start offset, but include
2936 * rest of the ds_tvb so that if finfo_set_len is called
2937 * later it can be lengthened as much as possible. */
2938 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);
2939 break;
2940
2941 case FT_BYTES:
2942 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2943 break;
2944
2945 case FT_UINT_BYTES:
2946 n = get_uint_value(tree, tvb, start, length, encoding);
2947 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2948
2949 /* Instead of calling proto_item_set_len(), since we don't yet
2950 * have a proto_item, we set the field_info's length ourselves. */
2951 new_fi->length = n + length;
2952 break;
2953
2954 case FT_BOOLEAN:
2955 /*
2956 * Map all non-zero values to little-endian for
2957 * backwards compatibility.
2958 */
2959 if (encoding)
2960 encoding = ENC_LITTLE_ENDIAN0x80000000;
2961 proto_tree_set_boolean(new_fi,
2962 get_uint64_value(tree, tvb, start, length, encoding));
2963 break;
2964
2965 case FT_CHAR:
2966 /* XXX - make these just FT_UINT? */
2967 case FT_UINT8:
2968 case FT_UINT16:
2969 case FT_UINT24:
2970 case FT_UINT32:
2971 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2972 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2973 value = (uint32_t)value64;
2974 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2975 new_fi->flags |= FI_VARINT0x00040000;
2976 }
2977 }
2978 else {
2979 /*
2980 * Map all non-zero values to little-endian for
2981 * backwards compatibility.
2982 */
2983 if (encoding)
2984 encoding = ENC_LITTLE_ENDIAN0x80000000;
2985
2986 value = get_uint_value(tree, tvb, start, length, encoding);
2987 }
2988 proto_tree_set_uint(new_fi, value);
2989 break;
2990
2991 case FT_UINT40:
2992 case FT_UINT48:
2993 case FT_UINT56:
2994 case FT_UINT64:
2995 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2996 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2997 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2998 new_fi->flags |= FI_VARINT0x00040000;
2999 }
3000 }
3001 else {
3002 /*
3003 * Map all other non-zero values to little-endian for
3004 * backwards compatibility.
3005 */
3006 if (encoding)
3007 encoding = ENC_LITTLE_ENDIAN0x80000000;
3008
3009 value64 = get_uint64_value(tree, tvb, start, length, encoding);
3010 }
3011 proto_tree_set_uint64(new_fi, value64);
3012 break;
3013
3014 /* XXX - make these just FT_INT? */
3015 case FT_INT8:
3016 case FT_INT16:
3017 case FT_INT24:
3018 case FT_INT32:
3019 /*
3020 * Map all non-zero values to little-endian for
3021 * backwards compatibility.
3022 */
3023 if (encoding)
3024 encoding = ENC_LITTLE_ENDIAN0x80000000;
3025 proto_tree_set_int(new_fi,
3026 get_int_value(tree, tvb, start, length, encoding));
3027 break;
3028
3029 case FT_INT40:
3030 case FT_INT48:
3031 case FT_INT56:
3032 case FT_INT64:
3033 /*
3034 * Map all non-zero values to little-endian for
3035 * backwards compatibility.
3036 */
3037 if (encoding)
3038 encoding = ENC_LITTLE_ENDIAN0x80000000;
3039 proto_tree_set_int64(new_fi,
3040 get_int64_value(tree, tvb, start, length, encoding));
3041 break;
3042
3043 case FT_IPv4:
3044 /*
3045 * Map all non-zero values to little-endian for
3046 * backwards compatibility.
3047 */
3048 if (encoding)
3049 encoding = ENC_LITTLE_ENDIAN0x80000000;
3050 if (length != FT_IPv4_LEN4) {
3051 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
3052 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
3053 }
3054 ipv4_value = tvb_get_ipv4(tvb, start);
3055 /*
3056 * NOTE: to support code written when
3057 * proto_tree_add_item() took a bool as its
3058 * last argument, with false meaning "big-endian"
3059 * and true meaning "little-endian", we treat any
3060 * non-zero value of "encoding" as meaning
3061 * "little-endian".
3062 */
3063 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);
3064 break;
3065
3066 case FT_IPXNET:
3067 if (length != FT_IPXNET_LEN4) {
3068 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
3069 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
3070 }
3071 proto_tree_set_ipxnet(new_fi,
3072 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
3073 break;
3074
3075 case FT_IPv6:
3076 if (length != FT_IPv6_LEN16) {
3077 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
3078 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3079 }
3080 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3081 break;
3082
3083 case FT_FCWWN:
3084 if (length != FT_FCWWN_LEN8) {
3085 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3086 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3087 }
3088 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3089 break;
3090
3091 case FT_AX25:
3092 if (length != 7) {
3093 length_error = length < 7 ? true1 : false0;
3094 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3095 }
3096 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3097 break;
3098
3099 case FT_VINES:
3100 if (length != VINES_ADDR_LEN6) {
3101 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3102 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3103 }
3104 proto_tree_set_vines_tvb(new_fi, tvb, start);
3105 break;
3106
3107 case FT_ETHER:
3108 if (length != FT_ETHER_LEN6) {
3109 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3110 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3111 }
3112 proto_tree_set_ether_tvb(new_fi, tvb, start);
3113 break;
3114
3115 case FT_EUI64:
3116 /*
3117 * Map all non-zero values to little-endian for
3118 * backwards compatibility.
3119 */
3120 if (encoding)
3121 encoding = ENC_LITTLE_ENDIAN0x80000000;
3122 if (length != FT_EUI64_LEN8) {
3123 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3124 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3125 }
3126 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3127 break;
3128 case FT_GUID:
3129 /*
3130 * Map all non-zero values to little-endian for
3131 * backwards compatibility.
3132 */
3133 if (encoding)
3134 encoding = ENC_LITTLE_ENDIAN0x80000000;
3135 if (length != FT_GUID_LEN16) {
3136 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3137 report_type_length_mismatch(tree, "a GUID", length, length_error);
3138 }
3139 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3140 break;
3141
3142 case FT_OID:
3143 case FT_REL_OID:
3144 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3145 break;
3146
3147 case FT_SYSTEM_ID:
3148 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3149 break;
3150
3151 case FT_FLOAT:
3152 /*
3153 * NOTE: to support code written when
3154 * proto_tree_add_item() took a bool as its
3155 * last argument, with false meaning "big-endian"
3156 * and true meaning "little-endian", we treat any
3157 * non-zero value of "encoding" as meaning
3158 * "little-endian".
3159 *
3160 * At some point in the future, we might
3161 * support non-IEEE-binary floating-point
3162 * formats in the encoding as well
3163 * (IEEE decimal, System/3x0, VAX).
3164 */
3165 if (encoding)
3166 encoding = ENC_LITTLE_ENDIAN0x80000000;
3167 if (length != 4) {
3168 length_error = length < 4 ? true1 : false0;
3169 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3170 }
3171 if (encoding)
3172 floatval = tvb_get_letohieee_float(tvb, start);
3173 else
3174 floatval = tvb_get_ntohieee_float(tvb, start);
3175 proto_tree_set_float(new_fi, floatval);
3176 break;
3177
3178 case FT_DOUBLE:
3179 /*
3180 * NOTE: to support code written when
3181 * proto_tree_add_item() took a bool as its
3182 * last argument, with false meaning "big-endian"
3183 * and true meaning "little-endian", we treat any
3184 * non-zero value of "encoding" as meaning
3185 * "little-endian".
3186 *
3187 * At some point in the future, we might
3188 * support non-IEEE-binary floating-point
3189 * formats in the encoding as well
3190 * (IEEE decimal, System/3x0, VAX).
3191 */
3192 if (encoding == true1)
3193 encoding = ENC_LITTLE_ENDIAN0x80000000;
3194 if (length != 8) {
3195 length_error = length < 8 ? true1 : false0;
3196 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3197 }
3198 if (encoding)
3199 doubleval = tvb_get_letohieee_double(tvb, start);
3200 else
3201 doubleval = tvb_get_ntohieee_double(tvb, start);
3202 proto_tree_set_double(new_fi, doubleval);
3203 break;
3204
3205 case FT_STRING:
3206 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3207 tvb, start, length, &item_length, encoding);
3208 proto_tree_set_string(new_fi, stringval);
3209
3210 /* Instead of calling proto_item_set_len(), since we
3211 * don't yet have a proto_item, we set the
3212 * field_info's length ourselves.
3213 *
3214 * XXX - our caller can't use that length to
3215 * advance an offset unless they arrange that
3216 * there always be a protocol tree into which
3217 * we're putting this item.
3218 */
3219 new_fi->length = item_length;
3220 break;
3221
3222 case FT_STRINGZ:
3223 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3224 tree, tvb, start, length, &item_length, encoding);
3225 proto_tree_set_string(new_fi, stringval);
3226
3227 /* Instead of calling proto_item_set_len(),
3228 * since we don't yet have a proto_item, we
3229 * set the field_info's length ourselves.
3230 *
3231 * XXX - our caller can't use that length to
3232 * advance an offset unless they arrange that
3233 * there always be a protocol tree into which
3234 * we're putting this item.
3235 */
3236 new_fi->length = item_length;
3237 break;
3238
3239 case FT_UINT_STRING:
3240 /*
3241 * NOTE: to support code written when
3242 * proto_tree_add_item() took a bool as its
3243 * last argument, with false meaning "big-endian"
3244 * and true meaning "little-endian", if the
3245 * encoding value is true, treat that as
3246 * ASCII with a little-endian length.
3247 *
3248 * This won't work for code that passes
3249 * arbitrary non-zero values; that code
3250 * will need to be fixed.
3251 */
3252 if (encoding == true1)
3253 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3254 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3255 tree, tvb, start, length, &item_length, encoding);
3256 proto_tree_set_string(new_fi, stringval);
3257
3258 /* Instead of calling proto_item_set_len(), since we
3259 * don't yet have a proto_item, we set the
3260 * field_info's length ourselves.
3261 *
3262 * XXX - our caller can't use that length to
3263 * advance an offset unless they arrange that
3264 * there always be a protocol tree into which
3265 * we're putting this item.
3266 */
3267 new_fi->length = item_length;
3268 break;
3269
3270 case FT_STRINGZPAD:
3271 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3272 tvb, start, length, &item_length, encoding);
3273 proto_tree_set_string(new_fi, stringval);
3274
3275 /* Instead of calling proto_item_set_len(), since we
3276 * don't yet have a proto_item, we set the
3277 * field_info's length ourselves.
3278 *
3279 * XXX - our caller can't use that length to
3280 * advance an offset unless they arrange that
3281 * there always be a protocol tree into which
3282 * we're putting this item.
3283 */
3284 new_fi->length = item_length;
3285 break;
3286
3287 case FT_STRINGZTRUNC:
3288 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3289 tvb, start, length, &item_length, encoding);
3290 proto_tree_set_string(new_fi, stringval);
3291
3292 /* Instead of calling proto_item_set_len(), since we
3293 * don't yet have a proto_item, we set the
3294 * field_info's length ourselves.
3295 *
3296 * XXX - our caller can't use that length to
3297 * advance an offset unless they arrange that
3298 * there always be a protocol tree into which
3299 * we're putting this item.
3300 */
3301 new_fi->length = item_length;
3302 break;
3303
3304 case FT_ABSOLUTE_TIME:
3305 /*
3306 * Absolute times can be in any of a number of
3307 * formats, and they can be big-endian or
3308 * little-endian.
3309 *
3310 * Historically FT_TIMEs were only timespecs;
3311 * the only question was whether they were stored
3312 * in big- or little-endian format.
3313 *
3314 * For backwards compatibility, we interpret an
3315 * encoding of 1 as meaning "little-endian timespec",
3316 * so that passing true is interpreted as that.
3317 */
3318 if (encoding == true1)
3319 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3320
3321 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3322
3323 proto_tree_set_time(new_fi, &time_stamp);
3324 break;
3325
3326 case FT_RELATIVE_TIME:
3327 /*
3328 * Relative times can be in any of a number of
3329 * formats, and they can be big-endian or
3330 * little-endian.
3331 *
3332 * Historically FT_TIMEs were only timespecs;
3333 * the only question was whether they were stored
3334 * in big- or little-endian format.
3335 *
3336 * For backwards compatibility, we interpret an
3337 * encoding of 1 as meaning "little-endian timespec",
3338 * so that passing true is interpreted as that.
3339 */
3340 if (encoding == true1)
3341 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3342
3343 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3344
3345 proto_tree_set_time(new_fi, &time_stamp);
3346 break;
3347 case FT_IEEE_11073_SFLOAT:
3348 if (encoding)
3349 encoding = ENC_LITTLE_ENDIAN0x80000000;
3350 if (length != 2) {
3351 length_error = length < 2 ? true1 : false0;
3352 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3353 }
3354
3355 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3356
3357 break;
3358 case FT_IEEE_11073_FLOAT:
3359 if (encoding)
3360 encoding = ENC_LITTLE_ENDIAN0x80000000;
3361 if (length != 4) {
3362 length_error = length < 4 ? true1 : false0;
3363 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3364 }
3365 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3366
3367 break;
3368 default:
3369 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))
3370 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))
3371 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))
3372 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))
;
3373 break;
3374 }
3375 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 3375
4
Taking true branch
5
Assuming the condition is false
6
'?' condition is false
7
Loop condition is false. Exiting loop
3376
3377 /* Don't add new node to proto_tree until now so that any exceptions
3378 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3379 /* XXX. wouldn't be better to add this item to tree, with some special
3380 * flag (FI_EXCEPTION?) to know which item caused exception? For
3381 * strings and bytes, we would have to set new_fi->value to something
3382 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3383 * could handle NULL values. */
3384 pi = proto_tree_add_node(tree, new_fi);
3385
3386 switch (new_fi->hfinfo->type) {
8
Control jumps to 'case FT_STRING:' at line 3388
3387
3388 case FT_STRING:
3389 /* XXX: trailing stray character detection should be done
3390 * _before_ conversion to UTF-8, because conversion can change
3391 * the length, or else get_string_length should return a value
3392 * for the "length in bytes of the string after conversion
3393 * including internal nulls." (Noting that we do, for other
3394 * reasons, still need the "length in bytes in the field",
3395 * especially for FT_STRINGZ.)
3396 *
3397 * This is true even for ASCII and UTF-8, because
3398 * substituting REPLACEMENT CHARACTERS for illegal characters
3399 * can also do so (and for UTF-8 possibly even make the
3400 * string _shorter_).
3401 */
3402 detect_trailing_stray_characters(encoding, stringval, item_length, pi);
9
3rd function call argument is an uninitialized value
3403 break;
3404
3405 default:
3406 break;
3407 }
3408
3409 return pi;
3410}
3411
3412proto_item *
3413proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3414 const unsigned start, unsigned length,
3415 const unsigned encoding, int32_t *retval)
3416{
3417 header_field_info *hfinfo;
3418 field_info *new_fi;
3419 int32_t value;
3420
3421 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", 3421, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3421,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3421, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3422
3423 switch (hfinfo->type) {
3424 case FT_INT8:
3425 case FT_INT16:
3426 case FT_INT24:
3427 case FT_INT32:
3428 break;
3429 case FT_INT64:
3430 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)
3431 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3432 default:
3433 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)
3434 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3435 }
3436
3437 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3438 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3439 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3440 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3441 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3442 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3443 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3444
3445 if (encoding & ENC_STRING0x07000000) {
3446 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3447 }
3448 /* I believe it's ok if this is called with a NULL tree */
3449 value = get_int_value(tree, tvb, start, length, encoding);
3450
3451 if (retval) {
3452 int no_of_bits;
3453 *retval = value;
3454 if (hfinfo->bitmask) {
3455 /* Mask out irrelevant portions */
3456 *retval &= (uint32_t)(hfinfo->bitmask);
3457 /* Shift bits */
3458 *retval >>= hfinfo_bitshift(hfinfo);
3459 }
3460 no_of_bits = ws_count_ones(hfinfo->bitmask);
3461 *retval = ws_sign_ext32(*retval, no_of_bits);
3462 }
3463
3464 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3465
3466 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", 3466
, __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", 3466, "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", 3466, "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", 3466, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3467
3468 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3469
3470 proto_tree_set_int(new_fi, value);
3471
3472 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3473
3474 return proto_tree_add_node(tree, new_fi);
3475}
3476
3477proto_item *
3478proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3479 const unsigned start, unsigned length,
3480 const unsigned encoding, uint32_t *retval)
3481{
3482 header_field_info *hfinfo;
3483 field_info *new_fi;
3484 uint32_t value;
3485
3486 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", 3486, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3486,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3486, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3487
3488 switch (hfinfo->type) {
3489 case FT_CHAR:
3490 case FT_UINT8:
3491 case FT_UINT16:
3492 case FT_UINT24:
3493 case FT_UINT32:
3494 break;
3495 default:
3496 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)
3497 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)
;
3498 }
3499
3500 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3501 {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3502 if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3503 *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3504 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3505 return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3506 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3507 )if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
;
3508
3509 if (encoding & ENC_STRING0x07000000) {
3510 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3511 }
3512 /* I believe it's ok if this is called with a NULL tree */
3513 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3514 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3515 uint64_t temp64;
3516 tvb_get_varint(tvb, start, length, &temp64, encoding);
3517 value = (uint32_t)temp64;
3518 } else {
3519 value = get_uint_value(tree, tvb, start, length, encoding);
3520 }
3521
3522 if (retval) {
3523 *retval = value;
3524 if (hfinfo->bitmask) {
3525 /* Mask out irrelevant portions */
3526 *retval &= (uint32_t)(hfinfo->bitmask);
3527 /* Shift bits */
3528 *retval >>= hfinfo_bitshift(hfinfo);
3529 }
3530 }
3531
3532 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3533
3534 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", 3534
, __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", 3534, "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", 3534, "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", 3534, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3535
3536 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3537
3538 proto_tree_set_uint(new_fi, value);
3539
3540 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3541 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3542 new_fi->flags |= FI_VARINT0x00040000;
3543 }
3544 return proto_tree_add_node(tree, new_fi);
3545}
3546
3547proto_item *
3548proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3549 const unsigned start, unsigned length,
3550 const unsigned encoding, uint32_t *retval)
3551{
3552 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3553}
3554
3555proto_item *
3556proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3557 const unsigned start, unsigned length,
3558 const unsigned encoding, uint8_t *retval)
3559{
3560 /* TODO: further restrict by hfinfo->type ? */
3561 uint32_t val32;
3562 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3563 *retval = (uint8_t)val32;
3564 return item;
3565}
3566
3567proto_item *
3568proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3569 const unsigned start, unsigned length,
3570 const unsigned encoding, uint16_t *retval)
3571{
3572 /* TODO: further restrict by hfinfo->type ? */
3573 uint32_t val32;
3574 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3575 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3576 return item;
3577}
3578
3579
3580/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3581 * and returns proto_item* and uint value retrieved*/
3582proto_item *
3583ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3584 const unsigned encoding, uint32_t *retval)
3585{
3586 field_info *new_fi;
3587 header_field_info *hfinfo;
3588 unsigned item_length;
3589 unsigned offset;
3590 uint32_t value;
3591
3592 offset = ptvc->offset;
3593 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", 3593, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3593,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3593, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3594
3595 switch (hfinfo->type) {
3596 case FT_CHAR:
3597 case FT_UINT8:
3598 case FT_UINT16:
3599 case FT_UINT24:
3600 case FT_UINT32:
3601 break;
3602 default:
3603 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)
3604 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)
;
3605 }
3606
3607 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3608 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3609
3610 /* I believe it's ok if this is called with a NULL tree */
3611 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3612 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3613
3614 if (retval) {
3615 *retval = value;
3616 if (hfinfo->bitmask) {
3617 /* Mask out irrelevant portions */
3618 *retval &= (uint32_t)(hfinfo->bitmask);
3619 /* Shift bits */
3620 *retval >>= hfinfo_bitshift(hfinfo);
3621 }
3622 }
3623
3624 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3625
3626 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3627
3628 /* Coast clear. Try and fake it */
3629 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", 3629
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3629, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3629, "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", 3629, __func__, "Adding %s would put more than %d 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); } } }
;
3630
3631 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3632
3633 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3634 offset, length, encoding);
3635}
3636
3637/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3638 * and returns proto_item* and int value retrieved*/
3639proto_item *
3640ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3641 const unsigned encoding, int32_t *retval)
3642{
3643 field_info *new_fi;
3644 header_field_info *hfinfo;
3645 unsigned item_length;
3646 unsigned offset;
3647 uint32_t value;
3648
3649 offset = ptvc->offset;
3650 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", 3650, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3650,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3650, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3651
3652 switch (hfinfo->type) {
3653 case FT_INT8:
3654 case FT_INT16:
3655 case FT_INT24:
3656 case FT_INT32:
3657 break;
3658 default:
3659 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)
3660 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3661 }
3662
3663 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3664 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3665
3666 /* I believe it's ok if this is called with a NULL tree */
3667 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3668 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3669
3670 if (retval) {
3671 int no_of_bits;
3672 *retval = value;
3673 if (hfinfo->bitmask) {
3674 /* Mask out irrelevant portions */
3675 *retval &= (uint32_t)(hfinfo->bitmask);
3676 /* Shift bits */
3677 *retval >>= hfinfo_bitshift(hfinfo);
3678 }
3679 no_of_bits = ws_count_ones(hfinfo->bitmask);
3680 *retval = ws_sign_ext32(*retval, no_of_bits);
3681 }
3682
3683 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3684
3685 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3686
3687 /* Coast clear. Try and fake it */
3688 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", 3688
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3688, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3688, "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", 3688, __func__, "Adding %s would put more than %d 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); } } }
;
3689
3690 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3691
3692 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3693 offset, length, encoding);
3694}
3695
3696/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3697 * and returns proto_item* and string value retrieved */
3698proto_item*
3699ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3700{
3701 header_field_info *hfinfo;
3702 field_info *new_fi;
3703 const uint8_t *value;
3704 unsigned item_length;
3705 unsigned offset;
3706
3707 offset = ptvc->offset;
3708
3709 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", 3709
, __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", 3709, "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", 3709, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3710
3711 switch (hfinfo->type) {
3712 case FT_STRING:
3713 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3714 break;
3715 case FT_STRINGZ:
3716 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3717 break;
3718 case FT_UINT_STRING:
3719 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3720 break;
3721 case FT_STRINGZPAD:
3722 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3723 break;
3724 case FT_STRINGZTRUNC:
3725 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3726 break;
3727 default:
3728 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)
3729 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)
;
3730 }
3731
3732 if (retval)
3733 *retval = value;
3734
3735 ptvcursor_advance(ptvc, item_length);
3736
3737 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3738
3739 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", 3739, __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", 3739,
"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", 3739, "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", 3739
, __func__, "Adding %s would put more than %d 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); } } }
;
3740
3741 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3742
3743 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3744 offset, length, encoding);
3745}
3746
3747/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3748 * and returns proto_item* and boolean value retrieved */
3749proto_item*
3750ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3751{
3752 header_field_info *hfinfo;
3753 field_info *new_fi;
3754 unsigned item_length;
3755 unsigned offset;
3756 uint64_t value, bitval;
3757
3758 offset = ptvc->offset;
3759 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", 3759, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3759,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3759, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3760
3761 if (hfinfo->type != FT_BOOLEAN) {
3762 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)
3763 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3764 }
3765
3766 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3767 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3768 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3769 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3770 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3771 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3772 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3773
3774 if (encoding & ENC_STRING0x07000000) {
3775 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3776 }
3777
3778 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3779 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3780
3781 /* I believe it's ok if this is called with a NULL tree */
3782 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3783
3784 if (retval) {
3785 bitval = value;
3786 if (hfinfo->bitmask) {
3787 /* Mask out irrelevant portions */
3788 bitval &= hfinfo->bitmask;
3789 }
3790 *retval = (bitval != 0);
3791 }
3792
3793 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3794
3795 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3796
3797 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", 3797, __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", 3797,
"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", 3797, "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", 3797
, __func__, "Adding %s would put more than %d 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); } } }
;
3798
3799 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3800
3801 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3802 offset, length, encoding);
3803}
3804
3805proto_item *
3806proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3807 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3808{
3809 header_field_info *hfinfo;
3810 field_info *new_fi;
3811 uint64_t value;
3812
3813 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", 3813, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3813,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3813, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3814
3815 switch (hfinfo->type) {
3816 case FT_UINT40:
3817 case FT_UINT48:
3818 case FT_UINT56:
3819 case FT_UINT64:
3820 break;
3821 default:
3822 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)
3823 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3824 }
3825
3826 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3827 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3828 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3829 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3830 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3831 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3832 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3833
3834 if (encoding & ENC_STRING0x07000000) {
3835 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3836 }
3837 /* I believe it's ok if this is called with a NULL tree */
3838 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3839 tvb_get_varint(tvb, start, length, &value, encoding);
3840 } else {
3841 value = get_uint64_value(tree, tvb, start, length, encoding);
3842 }
3843
3844 if (retval) {
3845 *retval = value;
3846 if (hfinfo->bitmask) {
3847 /* Mask out irrelevant portions */
3848 *retval &= hfinfo->bitmask;
3849 /* Shift bits */
3850 *retval >>= hfinfo_bitshift(hfinfo);
3851 }
3852 }
3853
3854 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3855
3856 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", 3856
, __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", 3856, "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", 3856, "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", 3856, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3857
3858 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3859
3860 proto_tree_set_uint64(new_fi, value);
3861
3862 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3863 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3864 new_fi->flags |= FI_VARINT0x00040000;
3865 }
3866
3867 return proto_tree_add_node(tree, new_fi);
3868}
3869
3870proto_item *
3871proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3872 const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3873{
3874 header_field_info *hfinfo;
3875 field_info *new_fi;
3876 int64_t value;
3877
3878 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", 3878, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3878,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3878, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3879
3880 switch (hfinfo->type) {
3881 case FT_INT40:
3882 case FT_INT48:
3883 case FT_INT56:
3884 case FT_INT64:
3885 break;
3886 default:
3887 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)
3888 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3889 }
3890
3891 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3892 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3893 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3894 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3895 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3896 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3897 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3898
3899 if (encoding & ENC_STRING0x07000000) {
3900 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3901 }
3902 /* I believe it's ok if this is called with a NULL tree */
3903 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3904 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3905 }
3906 else {
3907 value = get_int64_value(tree, tvb, start, length, encoding);
3908 }
3909
3910 if (retval) {
3911 *retval = value;
3912 }
3913
3914 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3915
3916 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", 3916
, __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", 3916, "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", 3916, "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", 3916, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3917
3918 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3919
3920 proto_tree_set_int64(new_fi, value);
3921
3922 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3923 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3924 new_fi->flags |= FI_VARINT0x00040000;
3925 }
3926
3927 return proto_tree_add_node(tree, new_fi);
3928}
3929
3930proto_item *
3931proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3932 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3933{
3934 header_field_info *hfinfo;
3935 field_info *new_fi;
3936 uint64_t value;
3937
3938 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", 3938, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3938,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3938, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3939
3940 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
))
)) {
3941 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)
3942 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3943 }
3944
3945 if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3946 REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3947 }
3948
3949 if (encoding & ENC_STRING0x07000000) {
3950 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3951 }
3952
3953 /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3954 * It also handles length 0, setting both return values to 0.
3955 * XXX - Should the max length be affected by the field type and/or
3956 * encoding, e.g. 5 for FT_[U]INT32?
3957 * XXX - Should there be separate _varint and _varuint versions to
3958 * avoid the changing the sign when casting the return value?
3959 * XXX - Do we even need the length parameter? Every user of this
3960 * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3961 * separate function, but unlike some field types, variable length
3962 * is the typical case here, not the exception, and the typical
3963 * case should have the shorter, more convenient function name.
3964 * Having the length makes the signature more similar to other
3965 * functions, though. */
3966 length = tvb_get_varint(tvb, start, length, &value, encoding);
3967
3968 if (length == 0) {
3969 expert_add_info(NULL((void*)0), tree, &ei_varint_decoding_failed_error);
3970 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3971 }
3972
3973 if (retval) {
3974 *retval = value;
3975 if (hfinfo->bitmask) {
3976 /* Mask out irrelevant portions */
3977 *retval &= hfinfo->bitmask;
3978 /* Shift bits */
3979 *retval >>= hfinfo_bitshift(hfinfo);
3980 }
3981 }
3982
3983 if (lenretval) {
3984 *lenretval = length;
3985 }
3986
3987 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3988
3989 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", 3989
, __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", 3989, "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", 3989, "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", 3989, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3990
3991 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3992
3993 proto_tree_set_uint64(new_fi, value);
3994
3995 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3996 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3997 new_fi->flags |= FI_VARINT0x00040000;
3998 }
3999
4000 return proto_tree_add_node(tree, new_fi);
4001
4002}
4003
4004proto_item *
4005proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4006 const unsigned start, unsigned length,
4007 const unsigned encoding, bool_Bool *retval)
4008{
4009 header_field_info *hfinfo;
4010 field_info *new_fi;
4011 uint64_t value, bitval;
4012
4013 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", 4013, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4013,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4013, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4014
4015 if (hfinfo->type != FT_BOOLEAN) {
4016 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)
4017 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
4018 }
4019
4020 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4021 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4022 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4023 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4024 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4025 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4026 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
4027
4028 if (encoding & ENC_STRING0x07000000) {
4029 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4030 }
4031 /* I believe it's ok if this is called with a NULL tree */
4032 value = get_uint64_value(tree, tvb, start, length, encoding);
4033
4034 if (retval) {
4035 bitval = value;
4036 if (hfinfo->bitmask) {
4037 /* Mask out irrelevant portions */
4038 bitval &= hfinfo->bitmask;
4039 }
4040 *retval = (bitval != 0);
4041 }
4042
4043 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4044
4045 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", 4045
, __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", 4045, "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", 4045, "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", 4045, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4046
4047 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4048
4049 proto_tree_set_boolean(new_fi, value);
4050
4051 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4052
4053 return proto_tree_add_node(tree, new_fi);
4054}
4055
4056proto_item *
4057proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4058 const unsigned start, unsigned length,
4059 const unsigned encoding, float *retval)
4060{
4061 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4062 field_info *new_fi;
4063 float value;
4064
4065 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", 4065,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4066
4067 if (hfinfo->type != FT_FLOAT) {
4068 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)
;
4069 }
4070
4071 if (length != 4) {
4072 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
4073 }
4074
4075 /* treat any nonzero encoding as little endian for backwards compatibility */
4076 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
4077 if (retval) {
4078 *retval = value;
4079 }
4080
4081 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4082
4083 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", 4083
, __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", 4083, "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", 4083, "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", 4083, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4084
4085 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4086 if (encoding) {
4087 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4088 }
4089
4090 proto_tree_set_float(new_fi, value);
4091
4092 return proto_tree_add_node(tree, new_fi);
4093}
4094
4095proto_item *
4096proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4097 const unsigned start, unsigned length,
4098 const unsigned encoding, double *retval)
4099{
4100 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4101 field_info *new_fi;
4102 double value;
4103
4104 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", 4104,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4105
4106 if (hfinfo->type != FT_DOUBLE) {
4107 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)
;
4108 }
4109
4110 if (length != 8) {
4111 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4112 }
4113
4114 /* treat any nonzero encoding as little endian for backwards compatibility */
4115 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4116 if (retval) {
4117 *retval = value;
4118 }
4119
4120 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4121
4122 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", 4122
, __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", 4122, "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", 4122, "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", 4122, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4123
4124 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4125 if (encoding) {
4126 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4127 }
4128
4129 proto_tree_set_double(new_fi, value);
4130
4131 return proto_tree_add_node(tree, new_fi);
4132}
4133
4134proto_item *
4135proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4136 const unsigned start, unsigned length,
4137 const unsigned encoding, ws_in4_addr *retval)
4138{
4139 header_field_info *hfinfo;
4140 field_info *new_fi;
4141 ws_in4_addr value;
4142
4143 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", 4143, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4143,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4143, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4144
4145 switch (hfinfo->type) {
4146 case FT_IPv4:
4147 break;
4148 default:
4149 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)
4150 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4151 }
4152
4153 if (length != FT_IPv4_LEN4)
4154 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)
4155 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4156
4157 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4158 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4159 }
4160
4161 /*
4162 * NOTE: to support code written when proto_tree_add_item() took
4163 * a bool as its last argument, with false meaning "big-endian"
4164 * and true meaning "little-endian", we treat any non-zero value
4165 * of "encoding" as meaning "little-endian".
4166 */
4167 value = tvb_get_ipv4(tvb, start);
4168 if (encoding)
4169 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))))
;
4170
4171 if (retval) {
4172 *retval = value;
4173 }
4174
4175 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4176
4177 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", 4177
, __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", 4177, "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", 4177, "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", 4177, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4178
4179 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4180
4181 proto_tree_set_ipv4(new_fi, value);
4182
4183 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4184 return proto_tree_add_node(tree, new_fi);
4185}
4186
4187proto_item *
4188proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4189 const unsigned start, unsigned length,
4190 const unsigned encoding, ws_in6_addr *addr)
4191{
4192 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4193 field_info *new_fi;
4194
4195 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", 4195,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4196
4197 switch (hfinfo->type) {
4198 case FT_IPv6:
4199 break;
4200 default:
4201 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)
4202 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4203 }
4204
4205 if (length != FT_IPv6_LEN16)
4206 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)
4207 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4208
4209 if (encoding) {
4210 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"
)
;
4211 }
4212
4213 tvb_get_ipv6(tvb, start, addr);
4214
4215 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4216
4217 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", 4217
, __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", 4217, "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", 4217, "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", 4217, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4218
4219 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4220
4221 proto_tree_set_ipv6(new_fi, addr);
4222
4223 return proto_tree_add_node(tree, new_fi);
4224}
4225
4226proto_item *
4227proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4228 const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4229
4230 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4231 field_info *new_fi;
4232
4233 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", 4233,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4234
4235 switch (hfinfo->type) {
4236 case FT_ETHER:
4237 break;
4238 default:
4239 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)
4240 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4241 }
4242
4243 if (length != FT_ETHER_LEN6)
4244 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)
4245 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4246
4247 if (encoding) {
4248 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"
)
;
4249 }
4250
4251 tvb_memcpy(tvb, retval, start, length);
4252
4253 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4254
4255 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", 4255
, __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", 4255, "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", 4255, "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", 4255, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4256
4257 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4258
4259 proto_tree_set_ether(new_fi, retval);
4260
4261 return proto_tree_add_node(tree, new_fi);
4262}
4263
4264
4265proto_item *
4266proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4267 tvbuff_t *tvb,
4268 const unsigned start, int length,
4269 const unsigned encoding,
4270 wmem_allocator_t *scope,
4271 const uint8_t **retval,
4272 unsigned *lenretval)
4273{
4274 proto_item *pi;
4275 header_field_info *hfinfo;
4276 field_info *new_fi;
4277 const uint8_t *value;
4278
4279 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", 4279, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4279,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4279, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4280
4281 switch (hfinfo->type) {
4282 case FT_STRING:
4283 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4284 break;
4285 case FT_STRINGZ:
4286 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4287 break;
4288 case FT_UINT_STRING:
4289 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4290 break;
4291 case FT_STRINGZPAD:
4292 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4293 break;
4294 case FT_STRINGZTRUNC:
4295 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4296 break;
4297 default:
4298 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)
4299 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)
;
4300 }
4301
4302 if (retval)
4303 *retval = value;
4304
4305 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4306
4307 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", 4307
, __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", 4307, "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", 4307, "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", 4307, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4308
4309 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4310
4311 proto_tree_set_string(new_fi, (const char*)value);
4312
4313 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4314
4315 pi = proto_tree_add_node(tree, new_fi);
4316
4317 switch (hfinfo->type) {
4318
4319 case FT_STRINGZ:
4320 case FT_STRINGZPAD:
4321 case FT_STRINGZTRUNC:
4322 case FT_UINT_STRING:
4323 break;
4324
4325 case FT_STRING:
4326 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4327 break;
4328
4329 default:
4330 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4330
, __func__, "assertion \"not reached\" failed")
;
4331 }
4332
4333 return pi;
4334}
4335
4336proto_item *
4337proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4338 const unsigned start, int length,
4339 const unsigned encoding, wmem_allocator_t *scope,
4340 const uint8_t **retval)
4341{
4342 unsigned item_length; // Param cannot be NULL in function below
4343 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4344 tvb, start, length, encoding, scope, retval, &item_length);
4345}
4346
4347proto_item *
4348proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4349 tvbuff_t *tvb,
4350 const unsigned start, int length,
4351 const unsigned encoding,
4352 wmem_allocator_t *scope,
4353 char **retval,
4354 unsigned *lenretval)
4355{
4356 proto_item *pi;
4357 header_field_info *hfinfo;
4358 field_info *new_fi;
4359 const uint8_t *value;
4360 uint32_t n = 0;
4361
4362 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", 4362, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4362,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4362, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4363
4364 switch (hfinfo->type) {
4365 case FT_STRING:
4366 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4367 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4368 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4369 break;
4370 case FT_STRINGZ:
4371 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4372 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4373 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4374 break;
4375 case FT_UINT_STRING:
4376 value = get_uint_string_value(scope, tree, 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_STRINGZPAD:
4381 value = get_stringzpad_value(scope, 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_STRINGZTRUNC:
4386 value = get_stringztrunc_value(scope, 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_BYTES:
4391 tvb_ensure_bytes_exist(tvb, start, length);
4392 value = tvb_get_ptr(tvb, start, length);
4393 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4394 *lenretval = length;
4395 break;
4396 case FT_UINT_BYTES:
4397 n = get_uint_value(tree, tvb, start, length, encoding);
4398 tvb_ensure_bytes_exist(tvb, start + length, n);
4399 value = tvb_get_ptr(tvb, start + length, n);
4400 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4401 *lenretval = length + n;
4402 break;
4403 default:
4404 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)
4405 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)
;
4406 }
4407
4408 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4409
4410 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", 4410
, __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", 4410, "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", 4410, "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", 4410, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4411
4412 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4413
4414 switch (hfinfo->type) {
4415
4416 case FT_STRING:
4417 case FT_STRINGZ:
4418 case FT_UINT_STRING:
4419 case FT_STRINGZPAD:
4420 case FT_STRINGZTRUNC:
4421 proto_tree_set_string(new_fi, (const char*)value);
4422 break;
4423
4424 case FT_BYTES:
4425 proto_tree_set_bytes(new_fi, value, length);
4426 break;
4427
4428 case FT_UINT_BYTES:
4429 proto_tree_set_bytes(new_fi, value, n);
4430 break;
4431
4432 default:
4433 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4433
, __func__, "assertion \"not reached\" failed")
;
4434 }
4435
4436 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4437
4438 pi = proto_tree_add_node(tree, new_fi);
4439
4440 switch (hfinfo->type) {
4441
4442 case FT_STRINGZ:
4443 case FT_STRINGZPAD:
4444 case FT_STRINGZTRUNC:
4445 case FT_UINT_STRING:
4446 break;
4447
4448 case FT_STRING:
4449 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4450 break;
4451
4452 case FT_BYTES:
4453 case FT_UINT_BYTES:
4454 break;
4455
4456 default:
4457 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4457
, __func__, "assertion \"not reached\" failed")
;
4458 }
4459
4460 return pi;
4461}
4462
4463proto_item *
4464proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4465 tvbuff_t *tvb,
4466 const unsigned start, int length,
4467 const unsigned encoding,
4468 wmem_allocator_t *scope,
4469 char **retval)
4470{
4471 unsigned item_length; // Param cannot be NULL in function below
4472 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4473 tvb, start, length, encoding, scope, retval, &item_length);
4474}
4475
4476proto_item *
4477proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4478 tvbuff_t *tvb,
4479 const unsigned start, int length, const unsigned encoding,
4480 wmem_allocator_t *scope, char **retval)
4481{
4482 header_field_info *hfinfo;
4483 field_info *new_fi;
4484 nstime_t time_stamp;
4485 int flags;
4486
4487 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", 4487, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4487,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4487, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4488
4489 switch (hfinfo->type) {
4490 case FT_ABSOLUTE_TIME:
4491 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4492 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4493 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4494 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4495 }
4496 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4497 break;
4498 case FT_RELATIVE_TIME:
4499 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4500 *retval = rel_time_to_secs_str(scope, &time_stamp);
4501 break;
4502 default:
4503 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)
4504 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4505 }
4506
4507 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4508
4509 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", 4509
, __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", 4509, "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", 4509, "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", 4509, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4510
4511 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4512
4513 switch (hfinfo->type) {
4514
4515 case FT_ABSOLUTE_TIME:
4516 case FT_RELATIVE_TIME:
4517 proto_tree_set_time(new_fi, &time_stamp);
4518 break;
4519 default:
4520 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4520
, __func__, "assertion \"not reached\" failed")
;
4521 }
4522
4523 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4524
4525 return proto_tree_add_node(tree, new_fi);
4526}
4527
4528/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4529 and returns proto_item* */
4530proto_item *
4531ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4532 const unsigned encoding)
4533{
4534 field_info *new_fi;
4535 header_field_info *hfinfo;
4536 int item_length;
4537 unsigned offset;
4538
4539 offset = ptvc->offset;
4540 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", 4540, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4540,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4540, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4541 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4542 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4543
4544 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4545
4546 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4547
4548 /* Coast clear. Try and fake it */
4549 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", 4549
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4549, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4549, "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", 4549, __func__, "Adding %s would put more than %d 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); } } }
;
4550
4551 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4552
4553 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4554 offset, length, encoding);
4555}
4556
4557/* Add an item to a proto_tree, using the text label registered to that item;
4558 the item is extracted from the tvbuff handed to it. */
4559proto_item *
4560proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4561 const unsigned start, int length, const unsigned encoding)
4562{
4563 field_info *new_fi;
4564 int item_length;
4565
4566 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", 4566,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4567
4568 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4569 test_length(hfinfo, tvb, start, item_length, encoding);
4570
4571 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4572
4573 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", 4573
, __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", 4573, "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", 4573, "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", 4573, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4574
4575 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4576
4577 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4578}
4579
4580proto_item *
4581proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4582 const unsigned start, int length, const unsigned encoding)
4583{
4584 register header_field_info *hfinfo;
4585
4586 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", 4586, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4586,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4586, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4587 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4588}
4589
4590/* Add an item to a proto_tree, using the text label registered to that item;
4591 the item is extracted from the tvbuff handed to it.
4592
4593 Return the length of the item through the pointer. */
4594proto_item *
4595proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4596 tvbuff_t *tvb, const unsigned start,
4597 int length, const unsigned encoding,
4598 unsigned *lenretval)
4599{
4600 field_info *new_fi;
4601 int item_length;
4602 proto_item *item;
4603
4604 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", 4604,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4605
4606 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4607 test_length(hfinfo, tvb, start, item_length, encoding);
4608
4609 if (!tree) {
4610 /*
4611 * We need to get the correct item length here.
4612 * That's normally done by proto_tree_new_item(),
4613 * but we won't be calling it.
4614 */
4615 *lenretval = get_full_length(hfinfo, tvb, start, length,
4616 item_length, encoding);
4617 return NULL((void*)0);
4618 }
4619
4620 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", 4627
, __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", 4627, "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", 4627, "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", 4627
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4621 /*((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", 4627
, __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", 4627, "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", 4627, "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", 4627
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4622 * 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", 4627
, __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", 4627, "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", 4627, "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", 4627
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4623 * 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", 4627
, __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", 4627, "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", 4627, "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", 4627
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4624 */((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", 4627
, __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", 4627, "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", 4627, "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", 4627
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4625 *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", 4627
, __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", 4627, "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", 4627, "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", 4627
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4626 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", 4627
, __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", 4627, "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", 4627, "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", 4627
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4627 })((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", 4627
, __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", 4627, "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", 4627, "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", 4627
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4628
4629 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4630
4631 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4632 *lenretval = new_fi->length;
4633 return item;
4634}
4635
4636proto_item *
4637proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4638 const unsigned start, int length,
4639 const unsigned encoding, unsigned *lenretval)
4640{
4641 register header_field_info *hfinfo;
4642
4643 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", 4643, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4643,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4643, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4644 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4645}
4646
4647/* which FT_ types can use proto_tree_add_bytes_item() */
4648static inline bool_Bool
4649validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4650{
4651 return (type == FT_BYTES ||
4652 type == FT_UINT_BYTES ||
4653 type == FT_OID ||
4654 type == FT_REL_OID ||
4655 type == FT_SYSTEM_ID );
4656}
4657
4658/* Note: this does no validation that the byte array of an FT_OID or
4659 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4660 so I think it's ok to continue not validating it?
4661 */
4662proto_item *
4663proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4664 const unsigned start, unsigned length,
4665 const unsigned encoding,
4666 GByteArray *retval, unsigned *endoff, int *err)
4667{
4668 field_info *new_fi;
4669 GByteArray *bytes = retval;
4670 GByteArray *created_bytes = NULL((void*)0);
4671 bool_Bool failed = false0;
4672 uint32_t n = 0;
4673 header_field_info *hfinfo;
4674 bool_Bool generate = (bytes || tree) ? true1 : false0;
4675
4676 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", 4676, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4676,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4676, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4677
4678 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", 4678,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4679
4680 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", 4681, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4681 "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", 4681, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4682
4683 if (length == 0) {
4684 return NULL((void*)0);
4685 }
4686
4687 if (encoding & ENC_STR_NUM0x01000000) {
4688 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"
)
;
4689 }
4690
4691 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4692 if (hfinfo->type == FT_UINT_BYTES) {
4693 /* can't decode FT_UINT_BYTES from strings */
4694 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")
4695 "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")
;
4696 }
4697
4698 unsigned hex_encoding = encoding;
4699 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4700 /* If none of the separator values are used,
4701 * assume no separator (the common case). */
4702 hex_encoding |= ENC_SEP_NONE0x00010000;
4703#if 0
4704 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")
4705 "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")
;
4706#endif
4707 }
4708
4709 if (!bytes) {
4710 /* caller doesn't care about return value, but we need it to
4711 call tvb_get_string_bytes() and set the tree later */
4712 bytes = created_bytes = g_byte_array_new();
4713 }
4714
4715 /*
4716 * bytes might be NULL after this, but can't add expert
4717 * error until later; if it's NULL, just note that
4718 * it failed.
4719 */
4720 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4721 if (bytes == NULL((void*)0))
4722 failed = true1;
4723 }
4724 else if (generate) {
4725 tvb_ensure_bytes_exist(tvb, start, length);
4726
4727 if (hfinfo->type == FT_UINT_BYTES) {
4728 n = length; /* n is now the "header" length */
4729 length = get_uint_value(tree, tvb, start, n, encoding);
4730 /* length is now the value's length; only store the value in the array */
4731 tvb_ensure_bytes_exist(tvb, start + n, length);
4732 if (!bytes) {
4733 /* caller doesn't care about return value, but
4734 * we may need it to set the tree later */
4735 bytes = created_bytes = g_byte_array_new();
4736 }
4737 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4738 }
4739 else if (length > 0) {
4740 if (!bytes) {
4741 /* caller doesn't care about return value, but
4742 * we may need it to set the tree later */
4743 bytes = created_bytes = g_byte_array_new();
4744 }
4745 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4746 }
4747
4748 if (endoff)
4749 *endoff = start + n + length;
4750 }
4751
4752 if (err)
4753 *err = failed ? EINVAL22 : 0;
4754
4755 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); }
4756 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4757 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); }
4758 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); }
4759 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); }
4760 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4761 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4762
4763 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", 4769
, __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", 4769, "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", 4769, "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", 4769
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4764 {((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", 4769
, __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", 4769, "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", 4769, "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", 4769
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4765 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", 4769
, __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", 4769, "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", 4769, "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", 4769
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4766 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", 4769
, __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", 4769, "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", 4769, "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", 4769
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4767 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", 4769
, __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", 4769, "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", 4769, "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", 4769
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4768 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", 4769
, __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", 4769, "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", 4769, "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", 4769
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4769 } )((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", 4769
, __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", 4769, "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", 4769, "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", 4769
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4770
4771 /* n will be zero except when it's a FT_UINT_BYTES */
4772 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4773
4774 if (encoding & ENC_STRING0x07000000) {
4775 if (failed)
4776 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4777
4778 if (bytes)
4779 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4780 else
4781 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4782
4783 if (created_bytes)
4784 g_byte_array_free(created_bytes, true1);
4785 }
4786 else {
4787 /* n will be zero except when it's a FT_UINT_BYTES */
4788 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4789
4790 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4791 * use the byte array created above in this case.
4792 */
4793 if (created_bytes)
4794 g_byte_array_free(created_bytes, true1);
4795
4796 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4797 (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)
;
4798 }
4799
4800 return proto_tree_add_node(tree, new_fi);
4801}
4802
4803
4804proto_item *
4805proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4806 const unsigned start, const unsigned length,
4807 const unsigned encoding,
4808 nstime_t *retval, unsigned *endoff, int *err)
4809{
4810 field_info *new_fi;
4811 nstime_t time_stamp;
4812 int saved_err = 0;
4813 header_field_info *hfinfo;
4814
4815 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", 4815, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4815,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4815, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4816
4817 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", 4817,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4818
4819 if (length == 0) {
4820 if(retval) {
4821 nstime_set_zero(retval);
4822 }
4823 return NULL((void*)0);
4824 }
4825
4826 nstime_set_zero(&time_stamp);
4827
4828 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4829 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", 4829, ((hfinfo))->abbrev))))
;
4830 /* The only string format that could be a relative time is
4831 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4832 * relative to "now" currently.
4833 */
4834 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4835 saved_err = EINVAL22;
4836 }
4837 else {
4838 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", 4838, ((hfinfo))->abbrev))))
;
4839 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4840
4841 tvb_ensure_bytes_exist(tvb, start, length);
4842 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4843 if (endoff) *endoff = start + length;
4844 }
4845
4846 if (err) *err = saved_err;
4847
4848 if (retval) {
4849 retval->secs = time_stamp.secs;
4850 retval->nsecs = time_stamp.nsecs;
4851 }
4852
4853 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4854
4855 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", 4855
, __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", 4855, "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", 4855, "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", 4855, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4856
4857 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4858
4859 proto_tree_set_time(new_fi, &time_stamp);
4860
4861 if (encoding & ENC_STRING0x07000000) {
4862 if (saved_err)
4863 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4864 }
4865 else {
4866 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4867 (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)
;
4868 }
4869
4870 return proto_tree_add_node(tree, new_fi);
4871}
4872
4873/* Add a FT_NONE to a proto_tree */
4874proto_item *
4875proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4876 const unsigned start, int length, const char *format,
4877 ...)
4878{
4879 proto_item *pi;
4880 va_list ap;
4881 header_field_info *hfinfo;
4882
4883 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4884
4885 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", 4885
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4885, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4885, "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", 4885, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4886
4887 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", 4887
, ((hfinfo))->abbrev))))
;
4888
4889 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4890
4891 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4891, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4892
4893 va_start(ap, format)__builtin_va_start(ap, format);
4894 proto_tree_set_representation(pi, format, ap);
4895 va_end(ap)__builtin_va_end(ap);
4896
4897 /* no value to set for FT_NONE */
4898 return pi;
4899}
4900
4901/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4902 * offset, and returns proto_item* */
4903proto_item *
4904ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4905 const unsigned encoding)
4906{
4907 proto_item *item;
4908
4909 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4910 length, encoding);
4911
4912 return item;
4913}
4914
4915/* Advance the ptvcursor's offset within its tvbuff without
4916 * adding anything to the proto_tree. */
4917void
4918ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4919{
4920 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4921 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4922 }
4923}
4924
4925
4926static void
4927proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4928{
4929 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4929, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4930 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4931}
4932
4933/* Add a FT_PROTOCOL to a proto_tree */
4934proto_item *
4935proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4936 unsigned start, int length, const char *format, ...)
4937{
4938 proto_item *pi;
4939 field_info *new_fi;
4940 tvbuff_t *protocol_tvb;
4941 va_list ap;
4942 header_field_info *hfinfo;
4943 char* protocol_rep;
4944
4945 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4946
4947 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", 4947
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4947, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4947, "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", 4947, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4948
4949 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"
, 4949, ((hfinfo))->abbrev))))
;
4950
4951 /*
4952 * This can throw an exception when it calls get_hfi_length before
4953 * it allocates anything, if length is nonzero and start is past
4954 * the end of the tvb. Afterwards it can't throw an exception,
4955 * as length is clamped to the captured length remaining.
4956 */
4957 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4958 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4959 /* Start the protocol_tvb at the correct start offset, but allow it
4960 * to be lengthened later via finfo_set_len. */
4961 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4962
4963 va_start(ap, format)__builtin_va_start(ap, format);
4964 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4965 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4966 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)
;
4967 va_end(ap)__builtin_va_end(ap);
4968
4969 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4969, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4970
4971 va_start(ap, format)__builtin_va_start(ap, format);
4972 proto_tree_set_representation(pi, format, ap);
4973 va_end(ap)__builtin_va_end(ap);
4974
4975 return pi;
4976}
4977
4978/* Add a FT_BYTES to a proto_tree */
4979proto_item *
4980proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4981 int length, const uint8_t *start_ptr)
4982{
4983 proto_item *pi;
4984 header_field_info *hfinfo;
4985 int item_length;
4986
4987 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", 4987, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4987,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4987, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4988 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4989 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4990
4991 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4992
4993 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", 4993
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4993, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4993, "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", 4993, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4994
4995 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",
4995, ((hfinfo))->abbrev))))
;
4996
4997 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4998 start_ptr = tvb_get_ptr(tvb, start, length);
4999
5000 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5001 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
5002
5003 return pi;
5004}
5005
5006/* Add a FT_BYTES to a proto_tree */
5007proto_item *
5008proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5009 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
5010{
5011 proto_item *pi;
5012 header_field_info *hfinfo;
5013 int item_length;
5014
5015 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", 5015, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5015,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5015, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5016 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
5017 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5018
5019 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5020
5021 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", 5021
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5021, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5021, "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", 5021, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5022
5023 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",
5023, ((hfinfo))->abbrev))))
;
5024
5025 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
5026 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
5027
5028 return pi;
5029}
5030
5031proto_item *
5032proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5033 unsigned start, int length,
5034 const uint8_t *start_ptr,
5035 const char *format, ...)
5036{
5037 proto_item *pi;
5038 va_list ap;
5039
5040 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5041
5042 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; }
;
5043
5044 va_start(ap, format)__builtin_va_start(ap, format);
5045 proto_tree_set_representation_value(pi, format, ap);
5046 va_end(ap)__builtin_va_end(ap);
5047
5048 return pi;
5049}
5050
5051proto_item *
5052proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5053 unsigned start, int length, const uint8_t *start_ptr,
5054 const char *format, ...)
5055{
5056 proto_item *pi;
5057 va_list ap;
5058
5059 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5060
5061 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; }
;
5062
5063 va_start(ap, format)__builtin_va_start(ap, format);
5064 proto_tree_set_representation(pi, format, ap);
5065 va_end(ap)__builtin_va_end(ap);
5066
5067 return pi;
5068}
5069
5070static void
5071proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
5072{
5073 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5073, "length >= 0"
))))
;
5074 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", 5074, "start_ptr != ((void*)0) || length == 0"
))))
;
5075
5076 fvalue_set_bytes_data(fi->value, start_ptr, length);
5077}
5078
5079
5080static void
5081proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5082{
5083 tvb_ensure_bytes_exist(tvb, offset, length);
5084 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5085}
5086
5087static void
5088proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5089{
5090 GByteArray *bytes;
5091
5092 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5092, "value != ((void*)0)"
))))
;
5093
5094 bytes = byte_array_dup(value);
5095
5096 fvalue_set_byte_array(fi->value, bytes);
5097}
5098
5099/* Add a FT_*TIME to a proto_tree */
5100proto_item *
5101proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5102 unsigned length, const nstime_t *value_ptr)
5103{
5104 proto_item *pi;
5105 header_field_info *hfinfo;
5106
5107 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5108
5109 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", 5109
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5109, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5109, "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", 5109, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5110
5111 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", 5111, ((hfinfo))->abbrev))))
;
5112
5113 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5114 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5115
5116 return pi;
5117}
5118
5119proto_item *
5120proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5121 unsigned start, unsigned length, nstime_t *value_ptr,
5122 const char *format, ...)
5123{
5124 proto_item *pi;
5125 va_list ap;
5126
5127 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5128 if (pi != tree) {
5129 va_start(ap, format)__builtin_va_start(ap, format);
5130 proto_tree_set_representation_value(pi, format, ap);
5131 va_end(ap)__builtin_va_end(ap);
5132 }
5133
5134 return pi;
5135}
5136
5137proto_item *
5138proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5139 unsigned start, unsigned length, nstime_t *value_ptr,
5140 const char *format, ...)
5141{
5142 proto_item *pi;
5143 va_list ap;
5144
5145 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5146 if (pi != tree) {
5147 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5147, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5148
5149 va_start(ap, format)__builtin_va_start(ap, format);
5150 proto_tree_set_representation(pi, format, ap);
5151 va_end(ap)__builtin_va_end(ap);
5152 }
5153
5154 return pi;
5155}
5156
5157/* Set the FT_*TIME value */
5158static void
5159proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5160{
5161 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5161, "value_ptr != ((void*)0)"
))))
;
5162
5163 fvalue_set_time(fi->value, value_ptr);
5164}
5165
5166/* Add a FT_IPXNET to a proto_tree */
5167proto_item *
5168proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5169 unsigned length, uint32_t value)
5170{
5171 proto_item *pi;
5172 header_field_info *hfinfo;
5173
5174 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5175
5176 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", 5176
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5176, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5176, "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", 5176, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5177
5178 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"
, 5178, ((hfinfo))->abbrev))))
;
5179
5180 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5181 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5182
5183 return pi;
5184}
5185
5186proto_item *
5187proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5188 unsigned start, unsigned length, uint32_t value,
5189 const char *format, ...)
5190{
5191 proto_item *pi;
5192 va_list ap;
5193
5194 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5195 if (pi != tree) {
5196 va_start(ap, format)__builtin_va_start(ap, format);
5197 proto_tree_set_representation_value(pi, format, ap);
5198 va_end(ap)__builtin_va_end(ap);
5199 }
5200
5201 return pi;
5202}
5203
5204proto_item *
5205proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5206 unsigned start, unsigned length, uint32_t value,
5207 const char *format, ...)
5208{
5209 proto_item *pi;
5210 va_list ap;
5211
5212 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5213 if (pi != tree) {
5214 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5214, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5215
5216 va_start(ap, format)__builtin_va_start(ap, format);
5217 proto_tree_set_representation(pi, format, ap);
5218 va_end(ap)__builtin_va_end(ap);
5219 }
5220
5221 return pi;
5222}
5223
5224/* Set the FT_IPXNET value */
5225static void
5226proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5227{
5228 fvalue_set_uinteger(fi->value, value);
5229}
5230
5231/* Add a FT_IPv4 to a proto_tree */
5232proto_item *
5233proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5234 unsigned length, ws_in4_addr value)
5235{
5236 proto_item *pi;
5237 header_field_info *hfinfo;
5238
5239 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5240
5241 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", 5241
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5241, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5241, "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", 5241, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5242
5243 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", 5243
, ((hfinfo))->abbrev))))
;
5244
5245 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5246 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5247
5248 return pi;
5249}
5250
5251proto_item *
5252proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5253 unsigned start, unsigned length, ws_in4_addr value,
5254 const char *format, ...)
5255{
5256 proto_item *pi;
5257 va_list ap;
5258
5259 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5260 if (pi != tree) {
5261 va_start(ap, format)__builtin_va_start(ap, format);
5262 proto_tree_set_representation_value(pi, format, ap);
5263 va_end(ap)__builtin_va_end(ap);
5264 }
5265
5266 return pi;
5267}
5268
5269proto_item *
5270proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5271 unsigned start, unsigned length, ws_in4_addr value,
5272 const char *format, ...)
5273{
5274 proto_item *pi;
5275 va_list ap;
5276
5277 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5278 if (pi != tree) {
5279 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5279, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5280
5281 va_start(ap, format)__builtin_va_start(ap, format);
5282 proto_tree_set_representation(pi, format, ap);
5283 va_end(ap)__builtin_va_end(ap);
5284 }
5285
5286 return pi;
5287}
5288
5289/* Set the FT_IPv4 value */
5290static void
5291proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5292{
5293 ipv4_addr_and_mask ipv4;
5294 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5295 fvalue_set_ipv4(fi->value, &ipv4);
5296}
5297
5298/* Add a FT_IPv6 to a proto_tree */
5299proto_item *
5300proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5301 unsigned length, const ws_in6_addr *value)
5302{
5303 proto_item *pi;
5304 header_field_info *hfinfo;
5305
5306 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5307
5308 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", 5308
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5308, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5308, "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", 5308, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5309
5310 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", 5310
, ((hfinfo))->abbrev))))
;
5311
5312 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5313 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5314
5315 return pi;
5316}
5317
5318proto_item *
5319proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5320 unsigned start, unsigned length,
5321 const ws_in6_addr *value_ptr,
5322 const char *format, ...)
5323{
5324 proto_item *pi;
5325 va_list ap;
5326
5327 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5328 if (pi != tree) {
5329 va_start(ap, format)__builtin_va_start(ap, format);
5330 proto_tree_set_representation_value(pi, format, ap);
5331 va_end(ap)__builtin_va_end(ap);
5332 }
5333
5334 return pi;
5335}
5336
5337proto_item *
5338proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5339 unsigned start, unsigned length,
5340 const ws_in6_addr *value_ptr,
5341 const char *format, ...)
5342{
5343 proto_item *pi;
5344 va_list ap;
5345
5346 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5347 if (pi != tree) {
5348 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5348, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5349
5350 va_start(ap, format)__builtin_va_start(ap, format);
5351 proto_tree_set_representation(pi, format, ap);
5352 va_end(ap)__builtin_va_end(ap);
5353 }
5354
5355 return pi;
5356}
5357
5358/* Set the FT_IPv6 value */
5359static void
5360proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5361{
5362 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5362, "value != ((void*)0)"
))))
;
5363 ipv6_addr_and_prefix ipv6;
5364 ipv6.addr = *value;
5365 ipv6.prefix = 128;
5366 fvalue_set_ipv6(fi->value, &ipv6);
5367}
5368
5369static void
5370proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5371{
5372 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5373}
5374
5375/* Set the FT_FCWWN value */
5376static void
5377proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5378{
5379 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5379, "value_ptr != ((void*)0)"
))))
;
5380 fvalue_set_fcwwn(fi->value, value_ptr);
5381}
5382
5383static void
5384proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5385{
5386 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5387}
5388
5389/* Add a FT_GUID to a proto_tree */
5390proto_item *
5391proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5392 unsigned length, const e_guid_t *value_ptr)
5393{
5394 proto_item *pi;
5395 header_field_info *hfinfo;
5396
5397 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5398
5399 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", 5399
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5399, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5399, "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", 5399, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5400
5401 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", 5401
, ((hfinfo))->abbrev))))
;
5402
5403 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5404 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5405
5406 return pi;
5407}
5408
5409proto_item *
5410proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5411 unsigned start, unsigned length,
5412 const e_guid_t *value_ptr,
5413 const char *format, ...)
5414{
5415 proto_item *pi;
5416 va_list ap;
5417
5418 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5419 if (pi != tree) {
5420 va_start(ap, format)__builtin_va_start(ap, format);
5421 proto_tree_set_representation_value(pi, format, ap);
5422 va_end(ap)__builtin_va_end(ap);
5423 }
5424
5425 return pi;
5426}
5427
5428proto_item *
5429proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5430 unsigned start, unsigned length, const e_guid_t *value_ptr,
5431 const char *format, ...)
5432{
5433 proto_item *pi;
5434 va_list ap;
5435
5436 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5437 if (pi != tree) {
5438 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5438, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5439
5440 va_start(ap, format)__builtin_va_start(ap, format);
5441 proto_tree_set_representation(pi, format, ap);
5442 va_end(ap)__builtin_va_end(ap);
5443 }
5444
5445 return pi;
5446}
5447
5448/* Set the FT_GUID value */
5449static void
5450proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5451{
5452 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5452, "value_ptr != ((void*)0)"
))))
;
5453 fvalue_set_guid(fi->value, value_ptr);
5454}
5455
5456static void
5457proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5458 const unsigned encoding)
5459{
5460 e_guid_t guid;
5461
5462 tvb_get_guid(tvb, start, &guid, encoding);
5463 proto_tree_set_guid(fi, &guid);
5464}
5465
5466/* Add a FT_OID to a proto_tree */
5467proto_item *
5468proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5469 unsigned length, const uint8_t* value_ptr)
5470{
5471 proto_item *pi;
5472 header_field_info *hfinfo;
5473
5474 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5475
5476 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", 5476
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5476, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5476, "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", 5476, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5477
5478 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", 5478
, ((hfinfo))->abbrev))))
;
5479
5480 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5481 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5482
5483 return pi;
5484}
5485
5486proto_item *
5487proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5488 unsigned start, unsigned length,
5489 const uint8_t* value_ptr,
5490 const char *format, ...)
5491{
5492 proto_item *pi;
5493 va_list ap;
5494
5495 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5496 if (pi != tree) {
5497 va_start(ap, format)__builtin_va_start(ap, format);
5498 proto_tree_set_representation_value(pi, format, ap);
5499 va_end(ap)__builtin_va_end(ap);
5500 }
5501
5502 return pi;
5503}
5504
5505proto_item *
5506proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5507 unsigned start, unsigned length, const uint8_t* value_ptr,
5508 const char *format, ...)
5509{
5510 proto_item *pi;
5511 va_list ap;
5512
5513 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5514 if (pi != tree) {
5515 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5515, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5516
5517 va_start(ap, format)__builtin_va_start(ap, format);
5518 proto_tree_set_representation(pi, format, ap);
5519 va_end(ap)__builtin_va_end(ap);
5520 }
5521
5522 return pi;
5523}
5524
5525/* Set the FT_OID value */
5526static void
5527proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5528{
5529 GByteArray *bytes;
5530
5531 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", 5531, "value_ptr != ((void*)0) || length == 0"
))))
;
5532
5533 bytes = g_byte_array_new();
5534 if (length > 0) {
5535 g_byte_array_append(bytes, value_ptr, length);
5536 }
5537 fvalue_set_byte_array(fi->value, bytes);
5538}
5539
5540static void
5541proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5542{
5543 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5544}
5545
5546/* Set the FT_SYSTEM_ID value */
5547static void
5548proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5549{
5550 GByteArray *bytes;
5551
5552 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", 5552, "value_ptr != ((void*)0) || length == 0"
))))
;
5553
5554 bytes = g_byte_array_new();
5555 if (length > 0) {
5556 g_byte_array_append(bytes, value_ptr, length);
5557 }
5558 fvalue_set_byte_array(fi->value, bytes);
5559}
5560
5561static void
5562proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5563{
5564 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5565}
5566
5567/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5568 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5569 * is destroyed. */
5570proto_item *
5571proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5572 int length, const char* value)
5573{
5574 proto_item *pi;
5575 header_field_info *hfinfo;
5576 int item_length;
5577
5578 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", 5578, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5578,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5578, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5579 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5580 /*
5581 * Special case - if the length is 0, skip the test, so that
5582 * we can have an empty string right after the end of the
5583 * packet. (This handles URL-encoded forms where the last field
5584 * has no value so the form ends right after the =.)
5585 *
5586 * XXX - length zero makes sense for FT_STRING, and more or less
5587 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5588 * for FT_STRINGZ (except that a number of fields that should be
5589 * one of the others are actually registered as FT_STRINGZ.)
5590 */
5591 if (item_length != 0)
5592 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5593
5594 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5595
5596 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", 5596
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5596, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5596, "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", 5596, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5597
5598 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", 5598, ((hfinfo))->abbrev))))
;
5599
5600 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5601 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5601, "length >= 0"
))))
;
5602
5603 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", 5603, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5604 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5605
5606 return pi;
5607}
5608
5609proto_item *
5610proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5611 unsigned start, int length, const char* value,
5612 const char *format,
5613 ...)
5614{
5615 proto_item *pi;
5616 va_list ap;
5617
5618 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5619 if (pi != tree) {
5620 va_start(ap, format)__builtin_va_start(ap, format);
5621 proto_tree_set_representation_value(pi, format, ap);
5622 va_end(ap)__builtin_va_end(ap);
5623 }
5624
5625 return pi;
5626}
5627
5628proto_item *
5629proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5630 unsigned start, int length, const char* value,
5631 const char *format, ...)
5632{
5633 proto_item *pi;
5634 va_list ap;
5635
5636 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5637 if (pi != tree) {
5638 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5638, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5639
5640 va_start(ap, format)__builtin_va_start(ap, format);
5641 proto_tree_set_representation(pi, format, ap);
5642 va_end(ap)__builtin_va_end(ap);
5643 }
5644
5645 return pi;
5646}
5647
5648/* Set the FT_STRING value */
5649static void
5650proto_tree_set_string(field_info *fi, const char* value)
5651{
5652 if (value) {
5653 fvalue_set_string(fi->value, value);
5654 } else {
5655 /*
5656 * XXX - why is a null value for a string field
5657 * considered valid?
5658 */
5659 fvalue_set_string(fi->value, "[ Null ]");
5660 }
5661}
5662
5663/* Set the FT_AX25 value */
5664static void
5665proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5666{
5667 fvalue_set_ax25(fi->value, value);
5668}
5669
5670static void
5671proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5672{
5673 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5674}
5675
5676/* Set the FT_VINES value */
5677static void
5678proto_tree_set_vines(field_info *fi, const uint8_t* value)
5679{
5680 fvalue_set_vines(fi->value, value);
5681}
5682
5683static void
5684proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5685{
5686 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5687}
5688
5689/* Add a FT_ETHER to a proto_tree */
5690proto_item *
5691proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5692 unsigned length, const uint8_t* value)
5693{
5694 proto_item *pi;
5695 header_field_info *hfinfo;
5696
5697 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5698
5699 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", 5699
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5699, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5699, "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", 5699, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5700
5701 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",
5701, ((hfinfo))->abbrev))))
;
5702
5703 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5704 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5705
5706 return pi;
5707}
5708
5709proto_item *
5710proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5711 unsigned start, unsigned length, const uint8_t* value,
5712 const char *format, ...)
5713{
5714 proto_item *pi;
5715 va_list ap;
5716
5717 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5718 if (pi != tree) {
5719 va_start(ap, format)__builtin_va_start(ap, format);
5720 proto_tree_set_representation_value(pi, format, ap);
5721 va_end(ap)__builtin_va_end(ap);
5722 }
5723
5724 return pi;
5725}
5726
5727proto_item *
5728proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5729 unsigned start, unsigned length, const uint8_t* value,
5730 const char *format, ...)
5731{
5732 proto_item *pi;
5733 va_list ap;
5734
5735 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5736 if (pi != tree) {
5737 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5737, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5738
5739 va_start(ap, format)__builtin_va_start(ap, format);
5740 proto_tree_set_representation(pi, format, ap);
5741 va_end(ap)__builtin_va_end(ap);
5742 }
5743
5744 return pi;
5745}
5746
5747/* Set the FT_ETHER value */
5748static void
5749proto_tree_set_ether(field_info *fi, const uint8_t* value)
5750{
5751 fvalue_set_ether(fi->value, value);
5752}
5753
5754static void
5755proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5756{
5757 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5758}
5759
5760/* Add a FT_BOOLEAN to a proto_tree */
5761proto_item *
5762proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5763 unsigned length, uint64_t value)
5764{
5765 proto_item *pi;
5766 header_field_info *hfinfo;
5767
5768 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5769
5770 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", 5770
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5770, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5770, "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", 5770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5771
5772 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"
, 5772, ((hfinfo))->abbrev))))
;
5773
5774 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5775 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5776
5777 return pi;
5778}
5779
5780proto_item *
5781proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5782 tvbuff_t *tvb, unsigned start, unsigned length,
5783 uint64_t value, const char *format, ...)
5784{
5785 proto_item *pi;
5786 va_list ap;
5787
5788 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5789 if (pi != tree) {
5790 va_start(ap, format)__builtin_va_start(ap, format);
5791 proto_tree_set_representation_value(pi, format, ap);
5792 va_end(ap)__builtin_va_end(ap);
5793 }
5794
5795 return pi;
5796}
5797
5798proto_item *
5799proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5800 unsigned start, unsigned length, uint64_t value,
5801 const char *format, ...)
5802{
5803 proto_item *pi;
5804 va_list ap;
5805
5806 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5807 if (pi != tree) {
5808 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5808, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5809
5810 va_start(ap, format)__builtin_va_start(ap, format);
5811 proto_tree_set_representation(pi, format, ap);
5812 va_end(ap)__builtin_va_end(ap);
5813 }
5814
5815 return pi;
5816}
5817
5818/* Set the FT_BOOLEAN value */
5819static void
5820proto_tree_set_boolean(field_info *fi, uint64_t value)
5821{
5822 proto_tree_set_uint64(fi, value);
5823}
5824
5825/* Generate, into "buf", a string showing the bits of a bitfield.
5826 Return a pointer to the character after that string. */
5827static char *
5828other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5829{
5830 int i = 0;
5831 uint64_t bit;
5832 char *p;
5833
5834 p = buf;
5835
5836 /* This is a devel error. It is safer to stop here. */
5837 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5837, "width >= 1"
))))
;
5838
5839 bit = UINT64_C(1)1UL << (width - 1);
5840 for (;;) {
5841 if (mask & bit) {
5842 /* This bit is part of the field. Show its value. */
5843 if (val & bit)
5844 *p++ = '1';
5845 else
5846 *p++ = '0';
5847 } else {
5848 /* This bit is not part of the field. */
5849 *p++ = '.';
5850 }
5851 bit >>= 1;
5852 i++;
5853 if (i >= width)
5854 break;
5855 if (i % 4 == 0)
5856 *p++ = ' ';
5857 }
5858 *p = '\0';
5859 return p;
5860}
5861
5862static char *
5863decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5864{
5865 char *p;
5866
5867 p = other_decode_bitfield_value(buf, val, mask, width);
5868 p = g_stpcpy(p, " = ");
5869
5870 return p;
5871}
5872
5873static char *
5874other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5875{
5876 int i = 0;
5877 uint64_t bit;
5878 char *p;
5879
5880 p = buf;
5881
5882 /* This is a devel error. It is safer to stop here. */
5883 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5883, "width >= 1"
))))
;
5884
5885 bit = UINT64_C(1)1UL << (width - 1);
5886 for (;;) {
5887 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5888 (mask & bit)) {
5889 /* This bit is part of the field. Show its value. */
5890 if (val & bit)
5891 *p++ = '1';
5892 else
5893 *p++ = '0';
5894 } else {
5895 /* This bit is not part of the field. */
5896 *p++ = '.';
5897 }
5898 bit >>= 1;
5899 i++;
5900 if (i >= width)
5901 break;
5902 if (i % 4 == 0)
5903 *p++ = ' ';
5904 }
5905
5906 *p = '\0';
5907 return p;
5908}
5909
5910static char *
5911decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5912{
5913 char *p;
5914
5915 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5916 p = g_stpcpy(p, " = ");
5917
5918 return p;
5919}
5920
5921/* Add a FT_FLOAT to a proto_tree */
5922proto_item *
5923proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5924 unsigned length, float value)
5925{
5926 proto_item *pi;
5927 header_field_info *hfinfo;
5928
5929 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5930
5931 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", 5931
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5931, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5931, "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", 5931, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5932
5933 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",
5933, ((hfinfo))->abbrev))))
;
5934
5935 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5936 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5937
5938 return pi;
5939}
5940
5941proto_item *
5942proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5943 unsigned start, unsigned length, float value,
5944 const char *format, ...)
5945{
5946 proto_item *pi;
5947 va_list ap;
5948
5949 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5950 if (pi != tree) {
5951 va_start(ap, format)__builtin_va_start(ap, format);
5952 proto_tree_set_representation_value(pi, format, ap);
5953 va_end(ap)__builtin_va_end(ap);
5954 }
5955
5956 return pi;
5957}
5958
5959proto_item *
5960proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5961 unsigned start, unsigned length, float value,
5962 const char *format, ...)
5963{
5964 proto_item *pi;
5965 va_list ap;
5966
5967 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5968 if (pi != tree) {
5969 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5969, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5970
5971 va_start(ap, format)__builtin_va_start(ap, format);
5972 proto_tree_set_representation(pi, format, ap);
5973 va_end(ap)__builtin_va_end(ap);
5974 }
5975
5976 return pi;
5977}
5978
5979/* Set the FT_FLOAT value */
5980static void
5981proto_tree_set_float(field_info *fi, float value)
5982{
5983 fvalue_set_floating(fi->value, value);
5984}
5985
5986/* Add a FT_DOUBLE to a proto_tree */
5987proto_item *
5988proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5989 unsigned length, double value)
5990{
5991 proto_item *pi;
5992 header_field_info *hfinfo;
5993
5994 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5995
5996 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", 5996
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5996, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5996, "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", 5996, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5997
5998 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"
, 5998, ((hfinfo))->abbrev))))
;
5999
6000 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6001 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
6002
6003 return pi;
6004}
6005
6006proto_item *
6007proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6008 unsigned start, unsigned length, double value,
6009 const char *format, ...)
6010{
6011 proto_item *pi;
6012 va_list ap;
6013
6014 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6015 if (pi != tree) {
6016 va_start(ap, format)__builtin_va_start(ap, format);
6017 proto_tree_set_representation_value(pi, format, ap);
6018 va_end(ap)__builtin_va_end(ap);
6019 }
6020
6021 return pi;
6022}
6023
6024proto_item *
6025proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6026 unsigned start, unsigned length, double value,
6027 const char *format, ...)
6028{
6029 proto_item *pi;
6030 va_list ap;
6031
6032 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6033 if (pi != tree) {
6034 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6034, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6035
6036 va_start(ap, format)__builtin_va_start(ap, format);
6037 proto_tree_set_representation(pi, format, ap);
6038 va_end(ap)__builtin_va_end(ap);
6039 }
6040
6041 return pi;
6042}
6043
6044/* Set the FT_DOUBLE value */
6045static void
6046proto_tree_set_double(field_info *fi, double value)
6047{
6048 fvalue_set_floating(fi->value, value);
6049}
6050
6051/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
6052proto_item *
6053proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6054 unsigned length, uint32_t value)
6055{
6056 proto_item *pi = NULL((void*)0);
6057 header_field_info *hfinfo;
6058
6059 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6060
6061 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", 6061
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6061, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6061, "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", 6061, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6062
6063 switch (hfinfo->type) {
6064 case FT_CHAR:
6065 case FT_UINT8:
6066 case FT_UINT16:
6067 case FT_UINT24:
6068 case FT_UINT32:
6069 case FT_FRAMENUM:
6070 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6071 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
6072 break;
6073
6074 default:
6075 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)
6076 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)
;
6077 }
6078
6079 return pi;
6080}
6081
6082proto_item *
6083proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6084 unsigned start, unsigned length, uint32_t value,
6085 const char *format, ...)
6086{
6087 proto_item *pi;
6088 va_list ap;
6089
6090 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6091 if (pi != tree) {
6092 va_start(ap, format)__builtin_va_start(ap, format);
6093 proto_tree_set_representation_value(pi, format, ap);
6094 va_end(ap)__builtin_va_end(ap);
6095 }
6096
6097 return pi;
6098}
6099
6100proto_item *
6101proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6102 unsigned start, unsigned length, uint32_t value,
6103 const char *format, ...)
6104{
6105 proto_item *pi;
6106 va_list ap;
6107
6108 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6109 if (pi != tree) {
6110 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6110, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6111
6112 va_start(ap, format)__builtin_va_start(ap, format);
6113 proto_tree_set_representation(pi, format, ap);
6114 va_end(ap)__builtin_va_end(ap);
6115 }
6116
6117 return pi;
6118}
6119
6120/* Set the FT_UINT{8,16,24,32} value */
6121static void
6122proto_tree_set_uint(field_info *fi, uint32_t value)
6123{
6124 const header_field_info *hfinfo;
6125 uint32_t integer;
6126
6127 hfinfo = fi->hfinfo;
6128 integer = value;
6129
6130 if (hfinfo->bitmask) {
6131 /* Mask out irrelevant portions */
6132 integer &= (uint32_t)(hfinfo->bitmask);
6133
6134 /* Shift bits */
6135 integer >>= hfinfo_bitshift(hfinfo);
6136
6137 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6138 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)
;
6139 }
6140
6141 fvalue_set_uinteger(fi->value, integer);
6142}
6143
6144/* Add FT_UINT{40,48,56,64} to a proto_tree */
6145proto_item *
6146proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6147 unsigned length, uint64_t value)
6148{
6149 proto_item *pi = NULL((void*)0);
6150 header_field_info *hfinfo;
6151
6152 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6153
6154 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", 6154
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6154, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6154, "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", 6154, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6155
6156 switch (hfinfo->type) {
6157 case FT_UINT40:
6158 case FT_UINT48:
6159 case FT_UINT56:
6160 case FT_UINT64:
6161 case FT_FRAMENUM:
6162 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6163 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6164 break;
6165
6166 default:
6167 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)
6168 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)
;
6169 }
6170
6171 return pi;
6172}
6173
6174proto_item *
6175proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6176 unsigned start, unsigned length, uint64_t value,
6177 const char *format, ...)
6178{
6179 proto_item *pi;
6180 va_list ap;
6181
6182 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6183 if (pi != tree) {
6184 va_start(ap, format)__builtin_va_start(ap, format);
6185 proto_tree_set_representation_value(pi, format, ap);
6186 va_end(ap)__builtin_va_end(ap);
6187 }
6188
6189 return pi;
6190}
6191
6192proto_item *
6193proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6194 unsigned start, unsigned length, uint64_t value,
6195 const char *format, ...)
6196{
6197 proto_item *pi;
6198 va_list ap;
6199
6200 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6201 if (pi != tree) {
6202 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6202, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6203
6204 va_start(ap, format)__builtin_va_start(ap, format);
6205 proto_tree_set_representation(pi, format, ap);
6206 va_end(ap)__builtin_va_end(ap);
6207 }
6208
6209 return pi;
6210}
6211
6212/* Set the FT_UINT{40,48,56,64} value */
6213static void
6214proto_tree_set_uint64(field_info *fi, uint64_t value)
6215{
6216 const header_field_info *hfinfo;
6217 uint64_t integer;
6218
6219 hfinfo = fi->hfinfo;
6220 integer = value;
6221
6222 if (hfinfo->bitmask) {
6223 /* Mask out irrelevant portions */
6224 integer &= hfinfo->bitmask;
6225
6226 /* Shift bits */
6227 integer >>= hfinfo_bitshift(hfinfo);
6228
6229 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6230 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)
;
6231 }
6232
6233 fvalue_set_uinteger64(fi->value, integer);
6234}
6235
6236/* Add FT_INT{8,16,24,32} to a proto_tree */
6237proto_item *
6238proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6239 unsigned length, int32_t value)
6240{
6241 proto_item *pi = NULL((void*)0);
6242 header_field_info *hfinfo;
6243
6244 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6245
6246 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", 6246
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6246, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6246, "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", 6246, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6247
6248 switch (hfinfo->type) {
6249 case FT_INT8:
6250 case FT_INT16:
6251 case FT_INT24:
6252 case FT_INT32:
6253 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6254 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6255 break;
6256
6257 default:
6258 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)
6259 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6260 }
6261
6262 return pi;
6263}
6264
6265proto_item *
6266proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6267 unsigned start, unsigned length, int32_t value,
6268 const char *format, ...)
6269{
6270 proto_item *pi;
6271 va_list ap;
6272
6273 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6274 if (pi != tree) {
6275 va_start(ap, format)__builtin_va_start(ap, format);
6276 proto_tree_set_representation_value(pi, format, ap);
6277 va_end(ap)__builtin_va_end(ap);
6278 }
6279
6280 return pi;
6281}
6282
6283proto_item *
6284proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6285 unsigned start, unsigned length, int32_t value,
6286 const char *format, ...)
6287{
6288 proto_item *pi;
6289 va_list ap;
6290
6291 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6292 if (pi != tree) {
6293 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6293, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6294
6295 va_start(ap, format)__builtin_va_start(ap, format);
6296 proto_tree_set_representation(pi, format, ap);
6297 va_end(ap)__builtin_va_end(ap);
6298 }
6299
6300 return pi;
6301}
6302
6303/* Set the FT_INT{8,16,24,32} value */
6304static void
6305proto_tree_set_int(field_info *fi, int32_t value)
6306{
6307 const header_field_info *hfinfo;
6308 uint32_t integer;
6309 int no_of_bits;
6310
6311 hfinfo = fi->hfinfo;
6312 integer = (uint32_t) value;
6313
6314 if (hfinfo->bitmask) {
6315 /* Mask out irrelevant portions */
6316 integer &= (uint32_t)(hfinfo->bitmask);
6317
6318 /* Shift bits */
6319 integer >>= hfinfo_bitshift(hfinfo);
6320
6321 no_of_bits = ws_count_ones(hfinfo->bitmask);
6322 integer = ws_sign_ext32(integer, no_of_bits);
6323
6324 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6325 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)
;
6326 }
6327
6328 fvalue_set_sinteger(fi->value, integer);
6329}
6330
6331/* Add FT_INT{40,48,56,64} to a proto_tree */
6332proto_item *
6333proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6334 unsigned length, int64_t value)
6335{
6336 proto_item *pi = NULL((void*)0);
6337 header_field_info *hfinfo;
6338
6339 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6340
6341 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", 6341
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6341, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6341, "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", 6341, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6342
6343 switch (hfinfo->type) {
6344 case FT_INT40:
6345 case FT_INT48:
6346 case FT_INT56:
6347 case FT_INT64:
6348 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6349 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6350 break;
6351
6352 default:
6353 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)
6354 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6355 }
6356
6357 return pi;
6358}
6359
6360proto_item *
6361proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6362 unsigned start, unsigned length, int64_t value,
6363 const char *format, ...)
6364{
6365 proto_item *pi;
6366 va_list ap;
6367
6368 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6369 if (pi != tree) {
6370 va_start(ap, format)__builtin_va_start(ap, format);
6371 proto_tree_set_representation_value(pi, format, ap);
6372 va_end(ap)__builtin_va_end(ap);
6373 }
6374
6375 return pi;
6376}
6377
6378/* Set the FT_INT{40,48,56,64} value */
6379static void
6380proto_tree_set_int64(field_info *fi, int64_t value)
6381{
6382 const header_field_info *hfinfo;
6383 uint64_t integer;
6384 int no_of_bits;
6385
6386 hfinfo = fi->hfinfo;
6387 integer = value;
6388
6389 if (hfinfo->bitmask) {
6390 /* Mask out irrelevant portions */
6391 integer &= hfinfo->bitmask;
6392
6393 /* Shift bits */
6394 integer >>= hfinfo_bitshift(hfinfo);
6395
6396 no_of_bits = ws_count_ones(hfinfo->bitmask);
6397 integer = ws_sign_ext64(integer, no_of_bits);
6398
6399 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6400 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)
;
6401 }
6402
6403 fvalue_set_sinteger64(fi->value, integer);
6404}
6405
6406proto_item *
6407proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6408 unsigned start, unsigned length, int64_t value,
6409 const char *format, ...)
6410{
6411 proto_item *pi;
6412 va_list ap;
6413
6414 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6415 if (pi != tree) {
6416 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6416, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6417
6418 va_start(ap, format)__builtin_va_start(ap, format);
6419 proto_tree_set_representation(pi, format, ap);
6420 va_end(ap)__builtin_va_end(ap);
6421 }
6422
6423 return pi;
6424}
6425
6426/* Add a FT_EUI64 to a proto_tree */
6427proto_item *
6428proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6429 unsigned length, const uint64_t value)
6430{
6431 proto_item *pi;
6432 header_field_info *hfinfo;
6433
6434 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6435
6436 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", 6436
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6436, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6436, "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", 6436, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6437
6438 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",
6438, ((hfinfo))->abbrev))))
;
6439
6440 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6441 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6442
6443 return pi;
6444}
6445
6446proto_item *
6447proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6448 unsigned start, unsigned length, const uint64_t value,
6449 const char *format, ...)
6450{
6451 proto_item *pi;
6452 va_list ap;
6453
6454 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6455 if (pi != tree) {
6456 va_start(ap, format)__builtin_va_start(ap, format);
6457 proto_tree_set_representation_value(pi, format, ap);
6458 va_end(ap)__builtin_va_end(ap);
6459 }
6460
6461 return pi;
6462}
6463
6464proto_item *
6465proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6466 unsigned start, unsigned length, const uint64_t value,
6467 const char *format, ...)
6468{
6469 proto_item *pi;
6470 va_list ap;
6471
6472 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6473 if (pi != tree) {
6474 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6474, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6475
6476 va_start(ap, format)__builtin_va_start(ap, format);
6477 proto_tree_set_representation(pi, format, ap);
6478 va_end(ap)__builtin_va_end(ap);
6479 }
6480
6481 return pi;
6482}
6483
6484/* Set the FT_EUI64 value */
6485static void
6486proto_tree_set_eui64(field_info *fi, const uint64_t value)
6487{
6488 uint8_t v[FT_EUI64_LEN8];
6489 phtonu64(v, value);
6490 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6491}
6492
6493static void
6494proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6495{
6496 if (encoding)
6497 {
6498 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6499 } else {
6500 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6501 }
6502}
6503
6504proto_item *
6505proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6506 const mac_hf_list_t *list_generic,
6507 int idx, tvbuff_t *tvb,
6508 proto_tree *tree, unsigned offset)
6509{
6510 uint8_t addr[6];
6511 const char *addr_name = NULL((void*)0);
6512 const char *oui_name = NULL((void*)0);
6513 proto_item *addr_item = NULL((void*)0);
6514 proto_tree *addr_tree = NULL((void*)0);
6515 proto_item *ret_val = NULL((void*)0);
6516
6517 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6518 return NULL((void*)0);
6519 }
6520
6521 /* Resolve what we can of the address */
6522 tvb_memcpy(tvb, addr, offset, sizeof addr);
6523 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6524 addr_name = get_ether_name(addr);
6525 }
6526 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6527 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6528 }
6529
6530 /* Add the item for the specific address type */
6531 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6532 if (idx >= 0) {
6533 addr_tree = proto_item_add_subtree(ret_val, idx);
6534 }
6535 else {
6536 addr_tree = tree;
6537 }
6538
6539 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6540 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6541 tvb, offset, 6, addr_name);
6542 proto_item_set_generated(addr_item);
6543 proto_item_set_hidden(addr_item);
6544 }
6545
6546 if (list_specific->hf_oui != NULL((void*)0)) {
6547 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6548 proto_item_set_generated(addr_item);
6549 proto_item_set_hidden(addr_item);
6550
6551 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6552 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6553 proto_item_set_generated(addr_item);
6554 proto_item_set_hidden(addr_item);
6555 }
6556 }
6557
6558 if (list_specific->hf_lg != NULL((void*)0)) {
6559 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6560 }
6561 if (list_specific->hf_ig != NULL((void*)0)) {
6562 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6563 }
6564
6565 /* Were we given a list for generic address fields? If not, stop here */
6566 if (list_generic == NULL((void*)0)) {
6567 return ret_val;
6568 }
6569
6570 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6571 proto_item_set_hidden(addr_item);
6572
6573 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6574 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6575 tvb, offset, 6, addr_name);
6576 proto_item_set_generated(addr_item);
6577 proto_item_set_hidden(addr_item);
6578 }
6579
6580 if (list_generic->hf_oui != NULL((void*)0)) {
6581 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6582 proto_item_set_generated(addr_item);
6583 proto_item_set_hidden(addr_item);
6584
6585 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6586 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6587 proto_item_set_generated(addr_item);
6588 proto_item_set_hidden(addr_item);
6589 }
6590 }
6591
6592 if (list_generic->hf_lg != NULL((void*)0)) {
6593 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6594 proto_item_set_hidden(addr_item);
6595 }
6596 if (list_generic->hf_ig != NULL((void*)0)) {
6597 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6598 proto_item_set_hidden(addr_item);
6599 }
6600 return ret_val;
6601}
6602
6603static proto_item *
6604proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6605{
6606 proto_node *pnode, *tnode, *sibling;
6607 field_info *tfi;
6608 unsigned depth = 1;
6609
6610 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6610, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6611
6612 /*
6613 * Restrict our depth. proto_tree_traverse_pre_order and
6614 * proto_tree_traverse_post_order (and possibly others) are recursive
6615 * so we need to be mindful of our stack size.
6616 */
6617 if (tree->first_child == NULL((void*)0)) {
6618 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6619 depth++;
6620 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6621 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__)), 6624)))
6622 "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__)), 6624)))
6623 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__)), 6624)))
6624 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__)), 6624)))
;
6625 }
6626 }
6627 }
6628
6629 /*
6630 * Make sure "tree" is ready to have subtrees under it, by
6631 * checking whether it's been given an ett_ value.
6632 *
6633 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6634 * node of the protocol tree. That node is not displayed,
6635 * so it doesn't need an ett_ value to remember whether it
6636 * was expanded.
6637 */
6638 tnode = tree;
6639 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6640 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6641 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"
, 6642)
6642 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"
, 6642)
;
6643 /* XXX - is it safe to continue here? */
6644 }
6645
6646 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6647 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6648 pnode->parent = tnode;
6649 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6650 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6651 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6652
6653 if (tnode->last_child != NULL((void*)0)) {
6654 sibling = tnode->last_child;
6655 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6655, "sibling->next == ((void*)0)"
))))
;
6656 sibling->next = pnode;
6657 } else
6658 tnode->first_child = pnode;
6659 tnode->last_child = pnode;
6660
6661 /* We should not be adding a fake node for an interesting field */
6662 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", 6662, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6663
6664 /* XXX - Should the proto_item have a header_field_info member, at least
6665 * for faked items, to know what hfi was faked? (Some dissectors look at
6666 * the tree items directly.)
6667 */
6668 return (proto_item *)pnode;
6669}
6670
6671/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6672static proto_item *
6673proto_tree_add_node(proto_tree *tree, field_info *fi)
6674{
6675 proto_node *pnode, *tnode, *sibling;
6676 field_info *tfi;
6677 unsigned depth = 1;
6678
6679 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6679, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6680
6681 /*
6682 * Restrict our depth. proto_tree_traverse_pre_order and
6683 * proto_tree_traverse_post_order (and possibly others) are recursive
6684 * so we need to be mindful of our stack size.
6685 */
6686 if (tree->first_child == NULL((void*)0)) {
6687 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6688 depth++;
6689 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6690 /* The fvalue_t is pool-allocated; just release the
6691 * type-specific data it owns (see new_field_info()). */
6692 fvalue_cleanup(fi->value);
6693 fi->value = NULL((void*)0);
6694 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__)), 6697)))
6695 "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__)), 6697)))
6696 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__)), 6697)))
6697 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__)), 6697)))
;
6698 }
6699 }
6700 }
6701
6702 /*
6703 * Make sure "tree" is ready to have subtrees under it, by
6704 * checking whether it's been given an ett_ value.
6705 *
6706 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6707 * node of the protocol tree. That node is not displayed,
6708 * so it doesn't need an ett_ value to remember whether it
6709 * was expanded.
6710 */
6711 tnode = tree;
6712 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6713 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6714 /* Since we are not adding fi to a node, its fvalue won't get
6715 * cleaned up by proto_tree_free_node(), so release the
6716 * type-specific data it owns now. The fvalue_t structure itself
6717 * is pool-allocated (see new_field_info()).
6718 */
6719 fvalue_cleanup(fi->value);
6720 fi->value = NULL((void*)0);
6721 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", 6722)
6722 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", 6722)
;
6723 /* XXX - is it safe to continue here? */
6724 }
6725
6726 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6727 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6728 pnode->parent = tnode;
6729 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6730 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6731 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6732
6733 if (tnode->last_child != NULL((void*)0)) {
6734 sibling = tnode->last_child;
6735 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6735, "sibling->next == ((void*)0)"
))))
;
6736 sibling->next = pnode;
6737 } else
6738 tnode->first_child = pnode;
6739 tnode->last_child = pnode;
6740
6741 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6742
6743 return (proto_item *)pnode;
6744}
6745
6746
6747/* Generic way to allocate field_info and add to proto_tree.
6748 * Sets *pfi to address of newly-allocated field_info struct */
6749static proto_item *
6750proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6751 int *length)
6752{
6753 proto_item *pi;
6754 field_info *fi;
6755 int item_length;
6756
6757 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6758 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6759 pi = proto_tree_add_node(tree, fi);
6760
6761 return pi;
6762}
6763
6764/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6765 * Eventually this should replace the other function.
6766 * Sets *pfi to address of newly-allocated field_info struct */
6767static proto_item *
6768proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6769 unsigned *length)
6770{
6771 proto_item *pi;
6772 field_info *fi;
6773 unsigned item_length;
6774
6775 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6776 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6777 pi = proto_tree_add_node(tree, fi);
6778
6779 return pi;
6780}
6781
6782static void
6783get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6784 int *item_length, const unsigned encoding)
6785{
6786 int length_remaining;
6787
6788 /*
6789 * We only allow a null tvbuff if the item has a zero length,
6790 * i.e. if there's no data backing it.
6791 */
6792 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", 6792, "tvb != ((void*)0) || *length == 0"
))))
;
6793
6794 /*
6795 * XXX - in some protocols, there are 32-bit unsigned length
6796 * fields, so lengths in protocol tree and tvbuff routines
6797 * should really be unsigned. We should have, for those
6798 * field types for which "to the end of the tvbuff" makes sense,
6799 * additional routines that take no length argument and
6800 * add fields that run to the end of the tvbuff.
6801 */
6802 if (*length == -1) {
6803 /*
6804 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6805 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6806 * of -1 means "set the length to what remains in the
6807 * tvbuff".
6808 *
6809 * The assumption is either that
6810 *
6811 * 1) the length of the item can only be determined
6812 * by dissection (typically true of items with
6813 * subitems, which are probably FT_NONE or
6814 * FT_PROTOCOL)
6815 *
6816 * or
6817 *
6818 * 2) if the tvbuff is "short" (either due to a short
6819 * snapshot length or due to lack of reassembly of
6820 * fragments/segments/whatever), we want to display
6821 * what's available in the field (probably FT_BYTES
6822 * or FT_STRING) and then throw an exception later
6823 *
6824 * or
6825 *
6826 * 3) the field is defined to be "what's left in the
6827 * packet"
6828 *
6829 * so we set the length to what remains in the tvbuff so
6830 * that, if we throw an exception while dissecting, it
6831 * has what is probably the right value.
6832 *
6833 * For FT_STRINGZ, it means "the string is null-terminated,
6834 * not null-padded; set the length to the actual length
6835 * of the string", and if the tvbuff if short, we just
6836 * throw an exception.
6837 *
6838 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6839 * it means "find the end of the string",
6840 * and if the tvbuff if short, we just throw an exception.
6841 *
6842 * It's not valid for any other type of field. For those
6843 * fields, we treat -1 the same way we treat other
6844 * negative values - we assume the length is a Really
6845 * Big Positive Number, and throw a ReportedBoundsError
6846 * exception, under the assumption that the Really Big
6847 * Length would run past the end of the packet.
6848 */
6849 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
))
)) {
6850 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6851 /*
6852 * Leave the length as -1, so our caller knows
6853 * it was -1.
6854 */
6855 *item_length = *length;
6856 return;
6857 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6858 switch (tvb_get_uint8(tvb, start) >> 6)
6859 {
6860 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6861 *item_length = 1;
6862 break;
6863 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6864 *item_length = 2;
6865 break;
6866 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6867 *item_length = 4;
6868 break;
6869 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6870 *item_length = 8;
6871 break;
6872 }
6873 }
6874 }
6875
6876 switch (hfinfo->type) {
6877
6878 case FT_PROTOCOL:
6879 case FT_NONE:
6880 case FT_BYTES:
6881 case FT_STRING:
6882 case FT_STRINGZPAD:
6883 case FT_STRINGZTRUNC:
6884 /*
6885 * We allow FT_PROTOCOLs to be zero-length -
6886 * for example, an ONC RPC NULL procedure has
6887 * neither arguments nor reply, so the
6888 * payload for that protocol is empty.
6889 *
6890 * We also allow the others to be zero-length -
6891 * because that's the way the code has been for a
6892 * long, long time.
6893 *
6894 * However, we want to ensure that the start
6895 * offset is not *past* the byte past the end
6896 * of the tvbuff: we throw an exception in that
6897 * case.
6898 */
6899 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6900 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6900, "*length >= 0"
))))
;
6901 break;
6902
6903 case FT_STRINGZ:
6904 /*
6905 * Leave the length as -1, so our caller knows
6906 * it was -1.
6907 */
6908 break;
6909
6910 default:
6911 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6912 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6912))
;
6913 }
6914 *item_length = *length;
6915 } else {
6916 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6917 /*
6918 * These types are for interior nodes of the
6919 * tree, and don't have data associated with
6920 * them; if the length is negative (XXX - see
6921 * above) or goes past the end of the tvbuff,
6922 * cut it short at the end of the tvbuff.
6923 * That way, if this field is selected in
6924 * Wireshark, we don't highlight stuff past
6925 * the end of the data.
6926 *
6927 * If we don't have a tvb, then length must be zero,
6928 * per the DISSECTOR_ASSERT() above.
6929 *
6930 * If we do have a tvb, and the length requested is
6931 * nonzero, we want to ensure that the start offset
6932 * is not *past* the byte past the end of the tvbuff
6933 * data: we throw an exception in that case as above.
6934 */
6935 if (tvb && *length) {
6936 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6937 if (*length < 0 ||
6938 (*length > 0 &&
6939 (length_remaining < *length)))
6940 *length = length_remaining;
6941 }
6942 }
6943 *item_length = *length;
6944 if (*item_length < 0) {
6945 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6946 }
6947 }
6948}
6949
6950static void
6951get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6952 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6953{
6954 unsigned length_remaining;
6955
6956 /*
6957 * We only allow a null tvbuff if the item has a zero length,
6958 * i.e. if there's no data backing it.
6959 */
6960 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", 6960, "tvb != ((void*)0) || *length == 0"
))))
;
6961
6962
6963 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6964 /*
6965 * These types are for interior nodes of the
6966 * tree, and don't have data associated with
6967 * them; if the length is negative (XXX - see
6968 * above) or goes past the end of the tvbuff,
6969 * cut it short at the end of the tvbuff.
6970 * That way, if this field is selected in
6971 * Wireshark, we don't highlight stuff past
6972 * the end of the data.
6973 *
6974 * If we don't have a tvb, then length must be zero,
6975 * per the DISSECTOR_ASSERT() above.
6976 *
6977 * If we do have a tvb, and the length requested is
6978 * nonzero, we want to ensure that the start offset
6979 * is not *past* the byte past the end of the tvbuff
6980 * data: we throw an exception in that case as above.
6981 * (If the length requested is zero, then it's quite
6982 * likely that the start offset is the byte past the
6983 * end, but that's ok.)
6984 */
6985 if (tvb && *length) {
6986 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6987 if (length_remaining < *length) {
6988 *length = length_remaining;
6989 }
6990 }
6991 }
6992 *item_length = *length;
6993}
6994
6995static int
6996get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6997 int length, unsigned item_length, const int encoding)
6998{
6999 uint32_t n;
7000
7001 /*
7002 * We need to get the correct item length here.
7003 * That's normally done by proto_tree_new_item(),
7004 * but we won't be calling it.
7005 */
7006 switch (hfinfo->type) {
7007
7008 case FT_NONE:
7009 case FT_PROTOCOL:
7010 case FT_BYTES:
7011 /*
7012 * The length is the specified length.
7013 */
7014 break;
7015
7016 case FT_UINT_BYTES:
7017 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
7018 item_length += n;
7019 if ((int)item_length < length) {
7020 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7021 }
7022 break;
7023
7024 /* XXX - make these just FT_UINT? */
7025 case FT_UINT8:
7026 case FT_UINT16:
7027 case FT_UINT24:
7028 case FT_UINT32:
7029 case FT_UINT40:
7030 case FT_UINT48:
7031 case FT_UINT56:
7032 case FT_UINT64:
7033 /* XXX - make these just FT_INT? */
7034 case FT_INT8:
7035 case FT_INT16:
7036 case FT_INT24:
7037 case FT_INT32:
7038 case FT_INT40:
7039 case FT_INT48:
7040 case FT_INT56:
7041 case FT_INT64:
7042 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
7043 if (length < -1) {
7044 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
7045 }
7046 if (length == -1) {
7047 uint64_t dummy;
7048 /* This can throw an exception */
7049 /* XXX - do this without fetching the varint? */
7050 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
7051 if (length == 0) {
7052 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7053 }
7054 }
7055 item_length = length;
7056 break;
7057 }
7058
7059 /*
7060 * The length is the specified length.
7061 */
7062 break;
7063
7064 case FT_BOOLEAN:
7065 case FT_CHAR:
7066 case FT_IPv4:
7067 case FT_IPXNET:
7068 case FT_IPv6:
7069 case FT_FCWWN:
7070 case FT_AX25:
7071 case FT_VINES:
7072 case FT_ETHER:
7073 case FT_EUI64:
7074 case FT_GUID:
7075 case FT_OID:
7076 case FT_REL_OID:
7077 case FT_SYSTEM_ID:
7078 case FT_FLOAT:
7079 case FT_DOUBLE:
7080 case FT_STRING:
7081 /*
7082 * The length is the specified length.
7083 */
7084 break;
7085
7086 case FT_STRINGZ:
7087 if (length < -1) {
7088 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7089 }
7090 if (length == -1) {
7091 /* This can throw an exception */
7092 item_length = tvb_strsize_enc(tvb, start, encoding);
7093 }
7094 break;
7095
7096 case FT_UINT_STRING:
7097 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7098 item_length += n;
7099 if ((int)item_length < length) {
7100 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7101 }
7102 break;
7103
7104 case FT_STRINGZPAD:
7105 case FT_STRINGZTRUNC:
7106 case FT_ABSOLUTE_TIME:
7107 case FT_RELATIVE_TIME:
7108 case FT_IEEE_11073_SFLOAT:
7109 case FT_IEEE_11073_FLOAT:
7110 /*
7111 * The length is the specified length.
7112 */
7113 break;
7114
7115 default:
7116 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
))
7117 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
))
7118 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
))
7119 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
))
;
7120 break;
7121 }
7122 return item_length;
7123}
7124
7125// This was arbitrarily chosen, but if you're adding 50K items to the tree
7126// without advancing the offset you should probably take a long, hard look
7127// at what you're doing.
7128// We *could* make this a configurable option, but I (Gerald) would like to
7129// avoid adding yet another nerd knob.
7130# define PROTO_TREE_MAX_IDLE50000 50000
7131static field_info *
7132new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7133 const unsigned start, const int item_length)
7134{
7135 field_info *fi;
7136
7137 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7138
7139 fi->hfinfo = hfinfo;
7140 fi->start = start;
7141 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7142 /* add the data source tvbuff */
7143 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7144
7145 // If our start offset hasn't advanced after adding many items it probably
7146 // means we're in a large or infinite loop.
7147 if (fi->start > 0) {
7148 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7149 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7150 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7151 if (wireshark_abort_on_too_many_items) {
7152 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", 7153
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7153 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7153
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7154 }
7155 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7156 * but if not, we should hit the max item error earlier,
7157 * so we shouldn't need to reset the tree count to
7158 * ensure that the exception handler can add the item. */
7159 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)))
7160 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)))
7161 "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)))
7162 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)))
;
7163 }
7164 } else {
7165 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7166 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7167 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7168 }
7169 }
7170 fi->length = item_length;
7171 fi->tree_type = -1;
7172 fi->flags = 0;
7173 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7174 /* If the tree is not visible, set the item hidden, unless we
7175 * need the representation or length and can't fake them.
7176 */
7177 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7178 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7179 }
7180 }
7181 fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7182 fi->rep = NULL((void*)0);
7183
7184 fi->appendix_start = 0;
7185 fi->appendix_length = 0;
7186
7187 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7188 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7189
7190 return fi;
7191}
7192
7193static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7194{
7195 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7196 return 0;
7197 }
7198
7199 /* Search for field name */
7200 char *ptr = strstr(representation, hfinfo->name);
7201 if (!ptr) {
7202 return 0;
7203 }
7204
7205 /* Check if field name ends with the ": " delimiter */
7206 ptr += strlen(hfinfo->name);
7207 if (strncmp(ptr, ": ", 2) == 0) {
7208 ptr += 2;
7209 }
7210
7211 /* Return offset to after field name */
7212 return ptr - representation;
7213}
7214
7215static size_t label_find_name_pos(const item_label_t *rep)
7216{
7217 size_t name_pos = 0;
7218
7219 /* If the value_pos is too small or too large, we can't find the expected format */
7220 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7221 return 0;
7222 }
7223
7224 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7225 if (rep->representation[rep->value_pos-2] == ':') {
7226 name_pos = rep->value_pos - 2;
7227 }
7228
7229 return name_pos;
7230}
7231
7232/* If the protocol tree is to be visible, set the representation of a
7233 proto_tree entry with the name of the field for the item and with
7234 the value formatted with the supplied printf-style format and
7235 argument list. */
7236static void
7237proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7238{
7239 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7239, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7240
7241 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7242 * items string representation */
7243 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7244 size_t name_pos, ret = 0;
7245 char *str;
7246 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7247 const header_field_info *hf;
7248
7249 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7249, "fi"))))
;
7250
7251 hf = fi->hfinfo;
7252
7253 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;
;
7254 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))
)) {
7255 uint64_t val;
7256 char *p;
7257
7258 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)
)
7259 val = fvalue_get_uinteger(fi->value);
7260 else
7261 val = fvalue_get_uinteger64(fi->value);
7262
7263 val <<= hfinfo_bitshift(hf);
7264
7265 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7266 ret = (p - fi->rep->representation);
7267 }
7268
7269 /* put in the hf name */
7270 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)
;
7271
7272 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7273 /* If possible, Put in the value of the string */
7274 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7275 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"
, 7275, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7276 fi->rep->value_pos = ret;
7277 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7278 if (ret >= ITEM_LABEL_LENGTH240) {
7279 /* Uh oh, we don't have enough room. Tell the user
7280 * that the field is truncated.
7281 */
7282 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7283 }
7284 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7285 }
7286}
7287
7288/* If the protocol tree is to be visible, set the representation of a
7289 proto_tree entry with the representation formatted with the supplied
7290 printf-style format and argument list. */
7291static void
7292proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7293{
7294 size_t ret; /*tmp return value */
7295 char *str;
7296 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7297
7298 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7298, "fi"))))
;
7299
7300 if (!proto_item_is_hidden(pi)) {
7301 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;
;
7302
7303 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7304 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"
, 7304, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7305 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7306 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7307 if (ret >= ITEM_LABEL_LENGTH240) {
7308 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7309 size_t name_pos = label_find_name_pos(fi->rep);
7310 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7311 }
7312 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7313 }
7314}
7315
7316static int
7317proto_strlcpy(char *dest, const char *src, size_t dest_size)
7318{
7319 if (dest_size == 0) return 0;
7320
7321 size_t res = g_strlcpy(dest, src, dest_size);
7322
7323 /* At most dest_size - 1 characters will be copied
7324 * (unless dest_size is 0). */
7325 if (res >= dest_size)
7326 res = dest_size - 1;
7327 return (int) res;
7328}
7329
7330static header_field_info *
7331hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7332{
7333 header_field_info *dup_hfinfo;
7334
7335 if (hfinfo->same_name_prev_id == -1)
7336 return NULL((void*)0);
7337 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", 7337
, __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", 7337, "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", 7337,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7338 return dup_hfinfo;
7339}
7340
7341static void
7342hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7343{
7344 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)
;
7345 last_field_name = NULL((void*)0);
7346
7347 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7348 /* No hfinfo with the same name */
7349 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7350 return;
7351 }
7352
7353 if (hfinfo->same_name_next) {
7354 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7355 }
7356
7357 if (hfinfo->same_name_prev_id != -1) {
7358 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7359 same_name_prev->same_name_next = hfinfo->same_name_next;
7360 if (!hfinfo->same_name_next) {
7361 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7362 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7363 }
7364 }
7365}
7366
7367int
7368proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7369{
7370 const header_field_info *hfinfo = finfo->hfinfo;
7371 int label_len = 0;
7372 char *tmp_str;
7373 const char *str;
7374 const uint8_t *bytes;
7375 uint32_t number;
7376 uint64_t number64;
7377 const char *hf_str_val;
7378 char number_buf[NUMBER_LABEL_LENGTH80];
7379 const char *number_out;
7380 address addr;
7381 const ipv4_addr_and_mask *ipv4;
7382 const ipv6_addr_and_prefix *ipv6;
7383
7384 switch (hfinfo->type) {
7385
7386 case FT_NONE:
7387 case FT_PROTOCOL:
7388 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7389
7390 case FT_UINT_BYTES:
7391 case FT_BYTES:
7392 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7393 hfinfo,
7394 fvalue_get_bytes_data(finfo->value),
7395 (unsigned)fvalue_length2(finfo->value),
7396 label_str_size);
7397 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7398 wmem_free(NULL((void*)0), tmp_str);
7399 break;
7400
7401 case FT_ABSOLUTE_TIME:
7402 {
7403 const nstime_t *value = fvalue_get_time(finfo->value);
7404 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7405 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7406 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7407 }
7408 if (hfinfo->strings) {
7409 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7410 if (time_string != NULL((void*)0)) {
7411 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7412 break;
7413 }
7414 }
7415 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7416 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7417 wmem_free(NULL((void*)0), tmp_str);
7418 break;
7419 }
7420
7421 case FT_RELATIVE_TIME:
7422 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7423 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7424 wmem_free(NULL((void*)0), tmp_str);
7425 break;
7426
7427 case FT_BOOLEAN:
7428 number64 = fvalue_get_uinteger64(finfo->value);
7429 label_len = proto_strlcpy(display_label_str,
7430 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7431 break;
7432
7433 case FT_CHAR:
7434 number = fvalue_get_uinteger(finfo->value);
7435
7436 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7437 char tmp[ITEM_LABEL_LENGTH240];
7438 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7439
7440 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7440, "fmtfunc"))))
;
7441 fmtfunc(tmp, number);
7442
7443 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7444
7445 } else if (hfinfo->strings) {
7446 number_out = hf_try_val_to_str(number, hfinfo);
7447
7448 if (!number_out) {
7449 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7450 }
7451
7452 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7453
7454 } else {
7455 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7456
7457 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7458 }
7459
7460 break;
7461
7462 /* XXX - make these just FT_NUMBER? */
7463 case FT_INT8:
7464 case FT_INT16:
7465 case FT_INT24:
7466 case FT_INT32:
7467 case FT_UINT8:
7468 case FT_UINT16:
7469 case FT_UINT24:
7470 case FT_UINT32:
7471 case FT_FRAMENUM:
7472 hf_str_val = NULL((void*)0);
7473 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
))
?
7474 (uint32_t) fvalue_get_sinteger(finfo->value) :
7475 fvalue_get_uinteger(finfo->value);
7476
7477 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7478 char tmp[ITEM_LABEL_LENGTH240];
7479 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7480
7481 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7481, "fmtfunc"))))
;
7482 fmtfunc(tmp, number);
7483
7484 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7485
7486 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7487 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7488 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7489 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7490 hf_str_val = hf_try_val_to_str(number, hfinfo);
7491 if (hf_str_val)
7492 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7493 } else {
7494 number_out = hf_try_val_to_str(number, hfinfo);
7495
7496 if (!number_out) {
7497 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7498 }
7499
7500 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7501 }
7502 } else {
7503 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7504
7505 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7506 }
7507
7508 break;
7509
7510 case FT_INT40:
7511 case FT_INT48:
7512 case FT_INT56:
7513 case FT_INT64:
7514 case FT_UINT40:
7515 case FT_UINT48:
7516 case FT_UINT56:
7517 case FT_UINT64:
7518 hf_str_val = NULL((void*)0);
7519 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
))
?
7520 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7521 fvalue_get_uinteger64(finfo->value);
7522
7523 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7524 char tmp[ITEM_LABEL_LENGTH240];
7525 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7526
7527 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7527, "fmtfunc64"
))))
;
7528 fmtfunc64(tmp, number64);
7529
7530 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7531 } else if (hfinfo->strings) {
7532 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7533 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7534 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7535 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7536 if (hf_str_val)
7537 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7538 } else {
7539 number_out = hf_try_val64_to_str(number64, hfinfo);
7540
7541 if (!number_out)
7542 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7543
7544 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7545 }
7546 } else {
7547 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7548
7549 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7550 }
7551
7552 break;
7553
7554 case FT_EUI64:
7555 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7556 tmp_str = address_to_display(NULL((void*)0), &addr);
7557 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7558 wmem_free(NULL((void*)0), tmp_str);
7559 break;
7560
7561 case FT_IPv4:
7562 ipv4 = fvalue_get_ipv4(finfo->value);
7563 //XXX: Should we ignore the mask?
7564 set_address_ipv4(&addr, ipv4);
7565 tmp_str = address_to_display(NULL((void*)0), &addr);
7566 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7567 wmem_free(NULL((void*)0), tmp_str);
7568 free_address(&addr);
7569 break;
7570
7571 case FT_IPv6:
7572 ipv6 = fvalue_get_ipv6(finfo->value);
7573 set_address_ipv6(&addr, ipv6);
7574 tmp_str = address_to_display(NULL((void*)0), &addr);
7575 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7576 wmem_free(NULL((void*)0), tmp_str);
7577 free_address(&addr);
7578 break;
7579
7580 case FT_FCWWN:
7581 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7582 tmp_str = address_to_display(NULL((void*)0), &addr);
7583 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7584 wmem_free(NULL((void*)0), tmp_str);
7585 break;
7586
7587 case FT_ETHER:
7588 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7589 tmp_str = address_to_display(NULL((void*)0), &addr);
7590 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7591 wmem_free(NULL((void*)0), tmp_str);
7592 break;
7593
7594 case FT_GUID:
7595 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7596 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7597 wmem_free(NULL((void*)0), tmp_str);
7598 break;
7599
7600 case FT_REL_OID:
7601 bytes = fvalue_get_bytes_data(finfo->value);
7602 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7603 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7604 wmem_free(NULL((void*)0), tmp_str);
7605 break;
7606
7607 case FT_OID:
7608 bytes = fvalue_get_bytes_data(finfo->value);
7609 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7610 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7611 wmem_free(NULL((void*)0), tmp_str);
7612 break;
7613
7614 case FT_SYSTEM_ID:
7615 bytes = fvalue_get_bytes_data(finfo->value);
7616 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7617 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7618 wmem_free(NULL((void*)0), tmp_str);
7619 break;
7620
7621 case FT_FLOAT:
7622 case FT_DOUBLE:
7623 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7624 break;
7625
7626 case FT_IEEE_11073_SFLOAT:
7627 case FT_IEEE_11073_FLOAT:
7628 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7629 break;
7630
7631 case FT_STRING:
7632 case FT_STRINGZ:
7633 case FT_UINT_STRING:
7634 case FT_STRINGZPAD:
7635 case FT_STRINGZTRUNC:
7636 str = fvalue_get_string(finfo->value);
7637 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7638 if (label_len >= label_str_size) {
7639 /* Truncation occurred. Get the real length
7640 * copied (not including '\0') */
7641 label_len = label_str_size ? label_str_size - 1 : 0;
7642 }
7643 break;
7644
7645 default:
7646 /* First try ftype string representation */
7647 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7648 if (!tmp_str) {
7649 /* Default to show as bytes */
7650 bytes = fvalue_get_bytes_data(finfo->value);
7651 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7652 }
7653 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7654 wmem_free(NULL((void*)0), tmp_str);
7655 break;
7656 }
7657 return label_len;
7658}
7659
7660const char *
7661proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7662 char *result, char *expr, const int size)
7663{
7664 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7665 GPtrArray *finfos;
7666 field_info *finfo = NULL((void*)0);
7667 header_field_info* hfinfo;
7668 const char *abbrev = NULL((void*)0);
7669
7670 char *str;
7671 col_custom_t *field_idx;
7672 int field_id;
7673 int ii = 0;
7674
7675 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7675, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7676 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7677 field_id = field_idx->field_id;
7678 if (field_id == 0) {
7679 GPtrArray *fvals = NULL((void*)0);
7680 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7681 if (fvals != NULL((void*)0)) {
7682
7683 // XXX - Handling occurrences is unusual when more
7684 // than one field is involved, e.g. there's four
7685 // results for tcp.port + tcp.port. We may really
7686 // want to apply it to the operands, not the output.
7687 // Note that occurrences are not quite the same as
7688 // the layer operator (should the grammar support
7689 // both?)
7690 /* Calculate single index or set outer boundaries */
7691 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7692 if (occurrence < 0) {
7693 i = occurrence + len;
7694 last = i;
7695 } else if (occurrence > 0) {
7696 i = occurrence - 1;
7697 last = i;
7698 } else {
7699 i = 0;
7700 last = len - 1;
7701 }
7702 if (i < 0 || i >= len) {
7703 g_ptr_array_unref(fvals);
7704 continue;
7705 }
7706 for (; i <= last; i++) {
7707 /* XXX - We could have a "resolved" result
7708 * for types where the value depends only
7709 * on the type, e.g. FT_IPv4, and not on
7710 * hfinfo->strings. Supporting the latter
7711 * requires knowing which hfinfo matched
7712 * if there are multiple with the same
7713 * abbreviation. In any case, we need to
7714 * know the expected return type of the
7715 * field expression.
7716 */
7717 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7718 if (offset_r && (offset_r < (size - 1)))
7719 result[offset_r++] = ',';
7720 if (offset_e && (offset_e < (size - 1)))
7721 expr[offset_e++] = ',';
7722 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7723 // col_{add,append,set}_* calls ws_label_strcpy
7724 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7725
7726 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7727 }
7728 g_ptr_array_unref(fvals);
7729 } else if (passed) {
7730 // XXX - Occurrence doesn't make sense for a test
7731 // output, it should be applied to the operands.
7732 if (offset_r && (offset_r < (size - 1)))
7733 result[offset_r++] = ',';
7734 if (offset_e && (offset_e < (size - 1)))
7735 expr[offset_e++] = ',';
7736 /* Prevent multiple check marks */
7737 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7738 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7739 } else {
7740 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7741 }
7742 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7743 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7744 } else {
7745 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7746 }
7747 }
7748 continue;
7749 }
7750 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", 7750
, __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", 7750,
"(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", 7750,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7751
7752 /* do we need to rewind ? */
7753 if (!hfinfo)
7754 return "";
7755
7756 if (occurrence < 0) {
7757 /* Search other direction */
7758 while (hfinfo->same_name_prev_id != -1) {
7759 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", 7759
, __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", 7759, "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", 7759,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7760 }
7761 }
7762
7763 prev_len = 0; /* Reset handled occurrences */
7764
7765 while (hfinfo) {
7766 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7767
7768 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7769 if (occurrence < 0) {
7770 hfinfo = hfinfo->same_name_next;
7771 } else {
7772 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7773 }
7774 continue;
7775 }
7776
7777 /* Are there enough occurrences of the field? */
7778 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7779 if (occurrence < 0) {
7780 hfinfo = hfinfo->same_name_next;
7781 } else {
7782 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7783 }
7784 prev_len += len;
7785 continue;
7786 }
7787
7788 /* Calculate single index or set outer boundaries */
7789 if (occurrence < 0) {
7790 i = occurrence + len + prev_len;
7791 last = i;
7792 } else if (occurrence > 0) {
7793 i = occurrence - 1 - prev_len;
7794 last = i;
7795 } else {
7796 i = 0;
7797 last = len - 1;
7798 }
7799
7800 prev_len += len; /* Count handled occurrences */
7801
7802 while (i <= last) {
7803 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7804
7805 if (offset_r && (offset_r < (size - 1)))
7806 result[offset_r++] = ',';
7807
7808 if (display_details) {
7809 char representation[ITEM_LABEL_LENGTH240];
7810 size_t offset = 0;
7811
7812 if (finfo->rep && finfo->rep->value_len) {
7813 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7814 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7815 } else {
7816 proto_item_fill_label(finfo, representation, &offset);
7817 }
7818 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7819 } else {
7820 switch (hfinfo->type) {
7821
7822 case FT_NONE:
7823 case FT_PROTOCOL:
7824 /* Prevent multiple check marks */
7825 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7826 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7827 } else {
7828 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7829 }
7830 break;
7831
7832 default:
7833 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7834 break;
7835 }
7836 }
7837
7838 if (offset_e && (offset_e < (size - 1)))
7839 expr[offset_e++] = ',';
7840
7841 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
))
)) {
7842 const char *hf_str_val;
7843 /* Integer types with BASE_NONE never get the numeric value. */
7844 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7845 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7846 } 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
)
) {
7847 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7848 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7849 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7850 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7851 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7852 }
7853 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7854 offset_e = (int)strlen(expr);
7855 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7856 /* Prevent multiple check marks */
7857 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7858 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7859 } else {
7860 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7861 }
7862 } else {
7863 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7864 // col_{add,append,set}_* calls ws_label_strcpy
7865 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7866 wmem_free(NULL((void*)0), str);
7867 }
7868 i++;
7869 }
7870
7871 /* XXX: Why is only the first abbreviation returned for a multifield
7872 * custom column? */
7873 if (!abbrev) {
7874 /* Store abbrev for return value */
7875 abbrev = hfinfo->abbrev;
7876 }
7877
7878 if (occurrence == 0) {
7879 /* Fetch next hfinfo with same name (abbrev) */
7880 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7881 } else {
7882 hfinfo = NULL((void*)0);
7883 }
7884 }
7885 }
7886
7887 if (offset_r >= (size - 1)) {
7888 mark_truncated(result, 0, size, NULL((void*)0));
7889 }
7890 if (offset_e >= (size - 1)) {
7891 mark_truncated(expr, 0, size, NULL((void*)0));
7892 }
7893 return abbrev ? abbrev : "";
7894}
7895
7896char *
7897proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7898{
7899 int len, prev_len, last, i;
7900 GPtrArray *finfos;
7901 field_info *finfo = NULL((void*)0);
7902 header_field_info* hfinfo;
7903
7904 char *filter = NULL((void*)0);
7905 GPtrArray *filter_array;
7906
7907 col_custom_t *col_custom;
7908 int field_id;
7909
7910 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7910, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7911 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7912 for (GSList *iter = field_ids; iter; iter = iter->next) {
7913 col_custom = (col_custom_t*)iter->data;
7914 field_id = col_custom->field_id;
7915 if (field_id == 0) {
7916 GPtrArray *fvals = NULL((void*)0);
7917 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7918 if (fvals != NULL((void*)0)) {
7919 // XXX - Handling occurrences is unusual when more
7920 // than one field is involved, e.g. there's four
7921 // results for tcp.port + tcp.port. We really
7922 // want to apply it to the operands, not the output.
7923 /* Calculate single index or set outer boundaries */
7924 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7925 if (occurrence < 0) {
7926 i = occurrence + len;
7927 last = i;
7928 } else if (occurrence > 0) {
7929 i = occurrence - 1;
7930 last = i;
7931 } else {
7932 i = 0;
7933 last = len - 1;
7934 }
7935 if (i < 0 || i >= len) {
7936 g_ptr_array_unref(fvals);
7937 continue;
7938 }
7939 for (; i <= last; i++) {
7940 /* XXX - Should multiple values for one
7941 * field use set membership to reduce
7942 * verbosity, here and below? */
7943 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7944 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7945 wmem_free(NULL((void*)0), str);
7946 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7947 g_ptr_array_add(filter_array, filter);
7948 }
7949 }
7950 g_ptr_array_unref(fvals);
7951 } else if (passed) {
7952 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7953 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7954 g_ptr_array_add(filter_array, filter);
7955 }
7956 } else {
7957 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7958 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7959 g_ptr_array_add(filter_array, filter);
7960 }
7961 }
7962 continue;
7963 }
7964
7965 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", 7965
, __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", 7965,
"(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", 7965,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7966
7967 /* do we need to rewind ? */
7968 if (!hfinfo)
7969 return NULL((void*)0);
7970
7971 if (occurrence < 0) {
7972 /* Search other direction */
7973 while (hfinfo->same_name_prev_id != -1) {
7974 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", 7974
, __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", 7974, "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", 7974,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7975 }
7976 }
7977
7978 prev_len = 0; /* Reset handled occurrences */
7979
7980 while (hfinfo) {
7981 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7982
7983 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7984 if (occurrence < 0) {
7985 hfinfo = hfinfo->same_name_next;
7986 } else {
7987 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7988 }
7989 continue;
7990 }
7991
7992 /* Are there enough occurrences of the field? */
7993 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7994 if (occurrence < 0) {
7995 hfinfo = hfinfo->same_name_next;
7996 } else {
7997 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7998 }
7999 prev_len += len;
8000 continue;
8001 }
8002
8003 /* Calculate single index or set outer boundaries */
8004 if (occurrence < 0) {
8005 i = occurrence + len + prev_len;
8006 last = i;
8007 } else if (occurrence > 0) {
8008 i = occurrence - 1 - prev_len;
8009 last = i;
8010 } else {
8011 i = 0;
8012 last = len - 1;
8013 }
8014
8015 prev_len += len; /* Count handled occurrences */
8016
8017 while (i <= last) {
8018 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
8019
8020 filter = proto_construct_match_selected_string(finfo, edt);
8021 if (filter) {
8022 /* Only add the same expression once (especially for FT_PROTOCOL).
8023 * The ptr array doesn't have NULL entries so g_str_equal is fine.
8024 */
8025 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
8026 g_ptr_array_add(filter_array, filter);
8027 }
8028 }
8029 i++;
8030 }
8031
8032 if (occurrence == 0) {
8033 /* Fetch next hfinfo with same name (abbrev) */
8034 hfinfo = hfinfo_same_name_get_prev(hfinfo);
8035 } else {
8036 hfinfo = NULL((void*)0);
8037 }
8038 }
8039 }
8040
8041 g_ptr_array_add(filter_array, NULL((void*)0));
8042
8043 /* XXX: Should this be || or && ? */
8044 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
8045
8046 g_ptr_array_free(filter_array, true1);
8047
8048 return output;
8049}
8050
8051/* Set text of proto_item after having already been created. */
8052void
8053proto_item_set_text(proto_item *pi, const char *format, ...)
8054{
8055 field_info *fi = NULL((void*)0);
8056 va_list ap;
8057
8058 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8059
8060 fi = PITEM_FINFO(pi)((pi)->finfo);
8061 if (fi == NULL((void*)0))
8062 return;
8063
8064 if (fi->rep) {
8065 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
8066 fi->rep = NULL((void*)0);
8067 }
8068
8069 va_start(ap, format)__builtin_va_start(ap, format);
8070 proto_tree_set_representation(pi, format, ap);
8071 va_end(ap)__builtin_va_end(ap);
8072}
8073
8074/* Append to text of proto_item after having already been created. */
8075void
8076proto_item_append_text(proto_item *pi, const char *format, ...)
8077{
8078 field_info *fi = NULL((void*)0);
8079 size_t curlen;
8080 char *str;
8081 va_list ap;
8082
8083 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8084
8085 fi = PITEM_FINFO(pi)((pi)->finfo);
8086 if (fi == NULL((void*)0)) {
8087 return;
8088 }
8089
8090 if (!proto_item_is_hidden(pi)) {
8091 /*
8092 * If we don't already have a representation,
8093 * generate the default representation.
8094 */
8095 if (fi->rep == NULL((void*)0)) {
8096 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;
;
8097 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8098 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8099 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8100 (strncmp(format, ": ", 2) == 0)) {
8101 fi->rep->value_pos += 2;
8102 }
8103 }
8104 if (fi->rep) {
8105 curlen = strlen(fi->rep->representation);
8106 /* curlen doesn't include the \0 byte.
8107 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8108 * the representation has already been truncated (of an up
8109 * to 4 byte UTF-8 character) or is just at the maximum length
8110 * unless we search for " [truncated]" (which may not be
8111 * at the start.)
8112 * It's safer to do nothing.
8113 */
8114 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8115 va_start(ap, format)__builtin_va_start(ap, format);
8116 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8117 va_end(ap)__builtin_va_end(ap);
8118 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"
, 8118, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8119 /* Keep fi->rep->value_pos */
8120 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8121 if (curlen >= ITEM_LABEL_LENGTH240) {
8122 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8123 size_t name_pos = label_find_name_pos(fi->rep);
8124 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8125 }
8126 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8127 }
8128 }
8129 }
8130}
8131
8132/* Prepend to text of proto_item after having already been created. */
8133void
8134proto_item_prepend_text(proto_item *pi, const char *format, ...)
8135{
8136 field_info *fi = NULL((void*)0);
8137 size_t pos;
8138 char representation[ITEM_LABEL_LENGTH240];
8139 char *str;
8140 va_list ap;
8141
8142 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8143
8144 fi = PITEM_FINFO(pi)((pi)->finfo);
8145 if (fi == NULL((void*)0)) {
8146 return;
8147 }
8148
8149 if (!proto_item_is_hidden(pi)) {
8150 /*
8151 * If we don't already have a representation,
8152 * generate the default representation.
8153 */
8154 if (fi->rep == NULL((void*)0)) {
8155 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;
;
8156 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8157 } else
8158 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8159
8160 va_start(ap, format)__builtin_va_start(ap, format);
8161 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8162 va_end(ap)__builtin_va_end(ap);
8163 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"
, 8163, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8164 fi->rep->value_pos += strlen(str);
8165 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8166 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8167 /* XXX: As above, if the old representation is close to the label
8168 * length, it might already be marked as truncated. */
8169 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8170 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8171 size_t name_pos = label_find_name_pos(fi->rep);
8172 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8173 }
8174 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8175 }
8176}
8177
8178static void
8179finfo_set_len(field_info *fi, const unsigned length)
8180{
8181 unsigned length_remaining;
8182
8183 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8184 if (length > length_remaining)
8185 fi->length = length_remaining;
8186 else
8187 fi->length = length;
8188
8189 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8190 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8191 fvalue_set_protocol_length(fi->value, fi->length);
8192 }
8193
8194 /*
8195 * You cannot just make the "len" field of a GByteArray
8196 * larger, if there's no data to back that length;
8197 * you can only make it smaller.
8198 */
8199 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8200 GBytes *bytes = fvalue_get_bytes(fi->value);
8201 size_t size;
8202 const void *data = g_bytes_get_data(bytes, &size);
8203 if ((size_t)fi->length <= size) {
8204 fvalue_set_bytes_data(fi->value, data, fi->length);
8205 }
8206 g_bytes_unref(bytes);
8207 }
8208}
8209
8210void
8211proto_item_set_len(proto_item *pi, const unsigned length)
8212{
8213 field_info *fi;
8214
8215 if (pi == NULL((void*)0))
8216 return;
8217
8218 fi = PITEM_FINFO(pi)((pi)->finfo);
8219 if (fi == NULL((void*)0))
8220 return;
8221
8222 finfo_set_len(fi, length);
8223}
8224
8225/*
8226 * Sets the length of the item based on its start and on the specified
8227 * offset, which is the offset past the end of the item; as the start
8228 * in the item is relative to the beginning of the data source tvbuff,
8229 * we need to pass in a tvbuff - the end offset is relative to the beginning
8230 * of that tvbuff.
8231 */
8232void
8233proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8234{
8235 field_info *fi;
8236 unsigned length;
8237
8238 if (pi == NULL((void*)0))
8239 return;
8240
8241 fi = PITEM_FINFO(pi)((pi)->finfo);
8242 if (fi == NULL((void*)0))
8243 return;
8244
8245 if (G_LIKELY(tvb)(tvb)) {
8246 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"
, 8246, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8247 end += tvb_raw_offset(tvb);
8248 } else {
8249 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", 8249, "((void*)0) == fi->ds_tvb"
))))
;
8250 }
8251 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8251, "end >= fi->start"
))))
;
8252 length = end - fi->start;
8253
8254 finfo_set_len(fi, length);
8255}
8256
8257unsigned
8258proto_item_get_len(const proto_item *pi)
8259{
8260 /* XXX - The only use case where this is really guaranteed to work is
8261 * increasing the length of an item (which has no effect if the item
8262 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8263 *
8264 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8265 *
8266 * Should there be a macro or function to do that, and possibly this
8267 * be deprecated? As a bonus, we could handle overflow.
8268 */
8269 field_info *fi;
8270
8271 if (!pi)
8272 return 0;
8273 fi = PITEM_FINFO(pi)((pi)->finfo);
8274 if (fi) {
8275 return fi->length;
8276 }
8277 return 0;
8278}
8279
8280void
8281proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8282 if (!ti) {
8283 return;
8284 }
8285 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)
;
8286 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)
;
8287}
8288
8289char *
8290proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8291{
8292 field_info *fi;
8293
8294 if (!pi)
8295 return wmem_strdup(scope, "");
8296 fi = PITEM_FINFO(pi)((pi)->finfo);
8297 if (!fi)
8298 return wmem_strdup(scope, "");
8299 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8299, "fi->hfinfo != ((void*)0)"
))))
;
8300 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8301}
8302
8303proto_tree *
8304proto_tree_create_root(packet_info *pinfo)
8305{
8306 proto_node *pnode;
8307
8308 /* Initialize the proto_node */
8309 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8310 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8311 pnode->parent = NULL((void*)0);
8312 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8313 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)))
;
8314
8315 /* Make sure we can access pinfo everywhere */
8316 pnode->tree_data->pinfo = pinfo;
8317
8318 /* Don't initialize the tree_data_t. Wait until we know we need it */
8319 pnode->tree_data->interesting_hfids = NULL((void*)0);
8320
8321 /* Set the default to false so it's easier to
8322 * find errors; if we expect to see the protocol tree
8323 * but for some reason the default 'visible' is not
8324 * changed, then we'll find out very quickly. */
8325 pnode->tree_data->visible = false0;
8326
8327 /* Make sure that we fake protocols (if possible) */
8328 pnode->tree_data->fake_protocols = true1;
8329
8330 /* Keep track of the number of children */
8331 pnode->tree_data->count = 0;
8332
8333 /* Initialize our loop checks */
8334 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8335 pnode->tree_data->max_start = 0;
8336 pnode->tree_data->start_idle_count = 0;
8337
8338 return (proto_tree *)pnode;
8339}
8340
8341
8342/* "prime" a proto_tree with a single hfid that a dfilter
8343 * is interested in. */
8344void
8345proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8346{
8347 header_field_info *hfinfo;
8348
8349 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", 8349, __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", 8349, "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", 8349, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8350 /* this field is referenced by a filter so increase the refcount.
8351 also increase the refcount for the parent, i.e the protocol.
8352 Don't increase the refcount if we're already printing the
8353 type, as that is a superset of direct reference.
8354 */
8355 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8356 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8357 }
8358 /* only increase the refcount if there is a parent.
8359 if this is a protocol and not a field then parent will be -1
8360 and there is no parent to add any refcounting for.
8361 */
8362 if (hfinfo->parent != -1) {
8363 header_field_info *parent_hfinfo;
8364 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", 8364
, __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", 8364,
"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", 8364,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8365
8366 /* Mark parent as indirectly referenced unless it is already directly
8367 * referenced, i.e. the user has specified the parent in a filter.
8368 */
8369 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8370 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8371 }
8372}
8373
8374/* "prime" a proto_tree with a single hfid that a dfilter
8375 * is interested in. */
8376void
8377proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8378{
8379 header_field_info *hfinfo;
8380
8381 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", 8381, __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", 8381, "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", 8381, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8382 /* this field is referenced by an (output) filter so increase the refcount.
8383 also increase the refcount for the parent, i.e the protocol.
8384 */
8385 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8386 /* only increase the refcount if there is a parent.
8387 if this is a protocol and not a field then parent will be -1
8388 and there is no parent to add any refcounting for.
8389 */
8390 if (hfinfo->parent != -1) {
8391 header_field_info *parent_hfinfo;
8392 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", 8392
, __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", 8392,
"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", 8392,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8393
8394 /* Mark parent as indirectly referenced unless it is already directly
8395 * referenced, i.e. the user has specified the parent in a filter.
8396 */
8397 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8398 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8399 }
8400}
8401
8402proto_tree *
8403proto_item_add_subtree(proto_item *pi, const int idx) {
8404 field_info *fi;
8405
8406 if (!pi)
8407 return NULL((void*)0);
8408
8409 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", 8409, "idx >= 0 && idx < num_tree_types"
))))
;
8410
8411 fi = PITEM_FINFO(pi)((pi)->finfo);
8412 if (!fi)
8413 return (proto_tree *)pi;
8414
8415 fi->tree_type = idx;
8416
8417 return (proto_tree *)pi;
8418}
8419
8420proto_tree *
8421proto_item_get_subtree(proto_item *pi) {
8422 field_info *fi;
8423
8424 if (!pi)
8425 return NULL((void*)0);
8426 fi = PITEM_FINFO(pi)((pi)->finfo);
8427 if ( (fi) && (fi->tree_type == -1) )
8428 return NULL((void*)0);
8429 return (proto_tree *)pi;
8430}
8431
8432proto_item *
8433proto_item_get_parent(const proto_item *ti) {
8434 if (!ti)
8435 return NULL((void*)0);
8436 return ti->parent;
8437}
8438
8439proto_item *
8440proto_item_get_parent_nth(proto_item *ti, int gen) {
8441 if (!ti)
8442 return NULL((void*)0);
8443 while (gen--) {
8444 ti = ti->parent;
8445 if (!ti)
8446 return NULL((void*)0);
8447 }
8448 return ti;
8449}
8450
8451
8452proto_item *
8453proto_tree_get_parent(proto_tree *tree) {
8454 if (!tree)
8455 return NULL((void*)0);
8456 return (proto_item *)tree;
8457}
8458
8459proto_tree *
8460proto_tree_get_parent_tree(proto_tree *tree) {
8461 if (!tree)
8462 return NULL((void*)0);
8463
8464 /* we're the root tree, there's no parent
8465 return ourselves so the caller has at least a tree to attach to */
8466 if (!tree->parent)
8467 return tree;
8468
8469 return (proto_tree *)tree->parent;
8470}
8471
8472proto_tree *
8473proto_tree_get_root(proto_tree *tree) {
8474 if (!tree)
8475 return NULL((void*)0);
8476 while (tree->parent) {
8477 tree = tree->parent;
8478 }
8479 return tree;
8480}
8481
8482void
8483proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8484 proto_item *item_to_move)
8485{
8486 /* This function doesn't generate any values. It only reorganizes the protocol tree
8487 * so we can bail out immediately if it isn't visible. */
8488 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8489 return;
8490
8491 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", 8491, "item_to_move->parent == tree"
))))
;
8492 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", 8492, "fixed_item->parent == tree"
))))
;
8493
8494 /*** cut item_to_move out ***/
8495
8496 /* is item_to_move the first? */
8497 if (tree->first_child == item_to_move) {
8498 /* simply change first child to next */
8499 tree->first_child = item_to_move->next;
8500
8501 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", 8501, "tree->last_child != item_to_move"
))))
;
8502 } else {
8503 proto_item *curr_item;
8504 /* find previous and change it's next */
8505 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8506 if (curr_item->next == item_to_move) {
8507 break;
8508 }
8509 }
8510
8511 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8511, "curr_item"
))))
;
8512
8513 curr_item->next = item_to_move->next;
8514
8515 /* fix last_child if required */
8516 if (tree->last_child == item_to_move) {
8517 tree->last_child = curr_item;
8518 }
8519 }
8520
8521 /*** insert to_move after fixed ***/
8522 item_to_move->next = fixed_item->next;
8523 fixed_item->next = item_to_move;
8524 if (tree->last_child == fixed_item) {
8525 tree->last_child = item_to_move;
8526 }
8527}
8528
8529void
8530proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8531 const unsigned length)
8532{
8533 field_info *fi;
8534
8535 if (tree == NULL((void*)0))
8536 return;
8537
8538 fi = PTREE_FINFO(tree)((tree)->finfo);
8539 if (fi == NULL((void*)0))
8540 return;
8541
8542 /* We don't store a separate data source tvb for the appendix, so
8543 * it must be from the same data source. (XXX - Are there any
8544 * situations where it makes sense to have an appendix from a
8545 * different data source?) */
8546 if (G_LIKELY(tvb)(tvb)) {
8547 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"
, 8547, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8548 start += tvb_raw_offset(tvb);
8549 } else {
8550 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", 8550, "((void*)0) == fi->ds_tvb"
))))
;
8551 }
8552
8553 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8554 * main body? */
8555
8556 fi->appendix_start = start;
8557 fi->appendix_length = length;
8558}
8559
8560static void
8561check_protocol_filter_name_or_fail(const char *filter_name)
8562{
8563 /* Require at least two characters. */
8564 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8565 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)
;
8566 }
8567
8568 if (proto_check_field_name(filter_name) != '\0') {
8569 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)
8570 " 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)
8571 " 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)
;
8572 }
8573
8574 /* Check that it doesn't match some very common numeric forms. */
8575 if (filter_name[0] == '0' &&
8576 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8577 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8578 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])
8579 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])
;
8580 }
8581
8582 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8583
8584 /* Check that it contains at least one letter. */
8585 bool_Bool have_letter = false0;
8586 for (const char *s = filter_name; *s != '\0'; s++) {
8587 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8588 have_letter = true1;
8589 break;
8590 }
8591 }
8592 if (!have_letter) {
8593 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)
8594 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8595 }
8596
8597 /* Check for reserved keywords. */
8598 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8599 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)
8600 " 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)
;
8601 }
8602}
8603
8604int
8605proto_register_protocol(const char *name, const char *short_name,
8606 const char *filter_name)
8607{
8608 protocol_t *protocol;
8609 header_field_info *hfinfo;
8610
8611 check_protocol_filter_name_or_fail(filter_name);
8612
8613 /*
8614 * Add this protocol to the list of known protocols;
8615 * the list is sorted by protocol short name.
8616 */
8617 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8618 protocol->name = name;
8619 protocol->short_name = short_name;
8620 protocol->filter_name = filter_name;
8621 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8622 protocol->is_enabled = true1; /* protocol is enabled by default */
8623 protocol->enabled_by_default = true1; /* see previous comment */
8624 protocol->can_toggle = true1;
8625 protocol->parent_proto_id = -1;
8626 protocol->heur_list = NULL((void*)0);
8627
8628 /* List will be sorted later by name, when all protocols completed registering */
8629 protocols = g_list_prepend(protocols, protocol);
8630 /*
8631 * Make sure there's not already a protocol with any of those
8632 * names. Crash if there is, as that's an error in the code
8633 * or an inappropriate plugin.
8634 * This situation has to be fixed to not register more than one
8635 * protocol with the same name.
8636 */
8637 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8638 /* ws_error will terminate the program */
8639 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)
8640 " 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)
;
8641 }
8642 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8643 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)
8644 " 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)
;
8645 }
8646 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8647 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)
8648 " 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)
;
8649 }
8650
8651 /* Here we allocate a new header_field_info struct */
8652 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8653 hfinfo->name = name;
8654 hfinfo->abbrev = filter_name;
8655 hfinfo->type = FT_PROTOCOL;
8656 hfinfo->display = BASE_NONE;
8657 hfinfo->strings = protocol;
8658 hfinfo->bitmask = 0;
8659 hfinfo->ref_type = HF_REF_TYPE_NONE;
8660 hfinfo->blurb = NULL((void*)0);
8661 hfinfo->parent = -1; /* This field differentiates protos and fields */
8662
8663 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8664 return protocol->proto_id;
8665}
8666
8667int
8668proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8669{
8670 protocol_t *protocol;
8671 header_field_info *hfinfo;
8672
8673 /*
8674 * Helper protocols don't need the strict rules as a "regular" protocol
8675 * Just register it in a list and make a hf_ field from it
8676 */
8677 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8678 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)
;
8679 }
8680
8681 if (parent_proto <= 0) {
8682 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)
8683 " 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)
;
8684 }
8685
8686 check_protocol_filter_name_or_fail(filter_name);
8687
8688 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8689 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8690 protocol->name = name;
8691 protocol->short_name = short_name;
8692 protocol->filter_name = filter_name;
8693 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8694
8695 /* Enabling and toggling is really determined by parent protocol,
8696 but provide default values here */
8697 protocol->is_enabled = true1;
8698 protocol->enabled_by_default = true1;
8699 protocol->can_toggle = true1;
8700
8701 protocol->parent_proto_id = parent_proto;
8702 protocol->heur_list = NULL((void*)0);
8703
8704 /* List will be sorted later by name, when all protocols completed registering */
8705 protocols = g_list_prepend(protocols, protocol);
8706
8707 /* Here we allocate a new header_field_info struct */
8708 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8709 hfinfo->name = name;
8710 hfinfo->abbrev = filter_name;
8711 hfinfo->type = field_type;
8712 hfinfo->display = BASE_NONE;
8713 if (field_type == FT_BYTES) {
8714 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8715 }
8716 hfinfo->strings = protocol;
8717 hfinfo->bitmask = 0;
8718 hfinfo->ref_type = HF_REF_TYPE_NONE;
8719 hfinfo->blurb = NULL((void*)0);
8720 hfinfo->parent = -1; /* This field differentiates protos and fields */
8721
8722 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8723 return protocol->proto_id;
8724}
8725
8726bool_Bool
8727proto_deregister_protocol(const char *short_name)
8728{
8729 protocol_t *protocol;
8730 header_field_info *hfinfo;
8731 int proto_id;
8732 unsigned i;
8733
8734 proto_id = proto_get_id_by_short_name(short_name);
8735 protocol = find_protocol_by_id(proto_id);
8736 if (protocol == NULL((void*)0))
8737 return false0;
8738
8739 g_hash_table_remove(proto_names, protocol->name);
8740 g_hash_table_remove(proto_short_names, (void *)short_name);
8741 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8742
8743 if (protocol->fields) {
8744 for (i = 0; i < protocol->fields->len; i++) {
8745 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8746 hfinfo_remove_from_gpa_name_map(hfinfo);
8747 expert_deregister_expertinfo(hfinfo->abbrev);
8748 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8749 }
8750 g_ptr_array_free(protocol->fields, true1);
8751 protocol->fields = NULL((void*)0);
8752 }
8753
8754 g_list_free(protocol->heur_list);
8755
8756 /* Remove this protocol from the list of known protocols */
8757 protocols = g_list_remove(protocols, protocol);
8758
8759 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8760 wmem_map_remove(gpa_name_map, protocol->filter_name);
8761
8762 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)
;
8763 last_field_name = NULL((void*)0);
8764
8765 return true1;
8766}
8767
8768void
8769proto_register_alias(const int proto_id, const char *alias_name)
8770{
8771 protocol_t *protocol;
8772
8773 protocol = find_protocol_by_id(proto_id);
8774 if (alias_name && protocol) {
8775 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8776 }
8777}
8778
8779/*
8780 * Routines to use to iterate over the protocols.
8781 * The argument passed to the iterator routines is an opaque cookie to
8782 * their callers; it's the GList pointer for the current element in
8783 * the list.
8784 * The ID of the protocol is returned, or -1 if there is no protocol.
8785 */
8786int
8787proto_get_first_protocol(void **cookie)
8788{
8789 protocol_t *protocol;
8790
8791 if (protocols == NULL((void*)0))
8792 return -1;
8793 *cookie = protocols;
8794 protocol = (protocol_t *)protocols->data;
8795 return protocol->proto_id;
8796}
8797
8798int
8799proto_get_data_protocol(void *cookie)
8800{
8801 GList *list_item = (GList *)cookie;
8802
8803 protocol_t *protocol = (protocol_t *)list_item->data;
8804 return protocol->proto_id;
8805}
8806
8807int
8808proto_get_next_protocol(void **cookie)
8809{
8810 GList *list_item = (GList *)*cookie;
8811 protocol_t *protocol;
8812
8813 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8814 if (list_item == NULL((void*)0))
8815 return -1;
8816 *cookie = list_item;
8817 protocol = (protocol_t *)list_item->data;
8818 return protocol->proto_id;
8819}
8820
8821header_field_info *
8822proto_get_first_protocol_field(const int proto_id, void **cookie)
8823{
8824 protocol_t *protocol = find_protocol_by_id(proto_id);
8825
8826 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8827 return NULL((void*)0);
8828
8829 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8830 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8831}
8832
8833header_field_info *
8834proto_get_next_protocol_field(const int proto_id, void **cookie)
8835{
8836 protocol_t *protocol = find_protocol_by_id(proto_id);
8837 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8838
8839 i++;
8840
8841 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8842 return NULL((void*)0);
8843
8844 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8845 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8846}
8847
8848protocol_t *
8849find_protocol_by_id(const int proto_id)
8850{
8851 header_field_info *hfinfo;
8852
8853 if (proto_id <= 0)
8854 return NULL((void*)0);
8855
8856 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", 8856, __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", 8856,
"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", 8856, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8857 if (hfinfo->type != FT_PROTOCOL) {
8858 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", 8858, "hfinfo->display & 0x00004000"
))))
;
8859 }
8860 return (protocol_t *)hfinfo->strings;
8861}
8862
8863int
8864proto_get_id(const protocol_t *protocol)
8865{
8866 return protocol->proto_id;
8867}
8868
8869bool_Bool
8870proto_name_already_registered(const char *name)
8871{
8872 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8872, "name", "No name present"))))
;
8873
8874 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8875 return true1;
8876 return false0;
8877}
8878
8879int
8880proto_get_id_by_filter_name(const char *filter_name)
8881{
8882 const protocol_t *protocol = NULL((void*)0);
8883
8884 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", 8884,
"filter_name", "No filter name present"))))
;
8885
8886 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8887
8888 if (protocol == NULL((void*)0))
8889 return -1;
8890 return protocol->proto_id;
8891}
8892
8893int
8894proto_get_id_by_short_name(const char *short_name)
8895{
8896 const protocol_t *protocol = NULL((void*)0);
8897
8898 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", 8898,
"short_name", "No short name present"))))
;
8899
8900 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8901
8902 if (protocol == NULL((void*)0))
8903 return -1;
8904 return protocol->proto_id;
8905}
8906
8907const char *
8908proto_get_protocol_name(const int proto_id)
8909{
8910 protocol_t *protocol;
8911
8912 protocol = find_protocol_by_id(proto_id);
8913
8914 if (protocol == NULL((void*)0))
8915 return NULL((void*)0);
8916 return protocol->name;
8917}
8918
8919const char *
8920proto_get_protocol_short_name(const protocol_t *protocol)
8921{
8922 if (protocol == NULL((void*)0))
8923 return "(none)";
8924 return protocol->short_name;
8925}
8926
8927const char *
8928proto_get_protocol_long_name(const protocol_t *protocol)
8929{
8930 if (protocol == NULL((void*)0))
8931 return "(none)";
8932 return protocol->name;
8933}
8934
8935const char *
8936proto_get_protocol_filter_name(const int proto_id)
8937{
8938 protocol_t *protocol;
8939
8940 protocol = find_protocol_by_id(proto_id);
8941 if (protocol == NULL((void*)0))
8942 return "(none)";
8943 return protocol->filter_name;
8944}
8945
8946void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8947{
8948 heur_dtbl_entry_t* heuristic_dissector;
8949
8950 if (protocol == NULL((void*)0))
8951 return;
8952
8953 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8954 if (heuristic_dissector != NULL((void*)0))
8955 {
8956 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8957 }
8958}
8959
8960void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8961{
8962 if (protocol == NULL((void*)0))
8963 return;
8964
8965 g_list_foreach(protocol->heur_list, func, user_data);
8966}
8967
8968void
8969proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8970 bool_Bool *is_tcp, bool_Bool *is_udp,
8971 bool_Bool *is_sctp, bool_Bool *is_tls,
8972 bool_Bool *is_rtp,
8973 bool_Bool *is_lte_rlc)
8974{
8975 wmem_list_frame_t *protos = wmem_list_head(layers);
8976 int proto_id;
8977 const char *proto_name;
8978
8979 /* Walk the list of a available protocols in the packet and
8980 attempt to find "major" ones. */
8981 /* It might make more sense to assemble and return a bitfield. */
8982 while (protos != NULL((void*)0))
8983 {
8984 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8985 proto_name = proto_get_protocol_filter_name(proto_id);
8986
8987 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8988 (!strcmp(proto_name, "ipv6")))) {
8989 *is_ip = true1;
8990 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8991 *is_tcp = true1;
8992 } else if (is_udp && !strcmp(proto_name, "udp")) {
8993 *is_udp = true1;
8994 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8995 *is_sctp = true1;
8996 } else if (is_tls && !strcmp(proto_name, "tls")) {
8997 *is_tls = true1;
8998 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8999 *is_rtp = true1;
9000 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
9001 *is_lte_rlc = true1;
9002 }
9003
9004 protos = wmem_list_frame_next(protos);
9005 }
9006}
9007
9008bool_Bool
9009proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
9010{
9011 wmem_list_frame_t *protos = wmem_list_head(layers);
9012 int proto_id;
9013 const char *name;
9014
9015 /* Walk the list of a available protocols in the packet and
9016 attempt to find the specified protocol. */
9017 while (protos != NULL((void*)0))
9018 {
9019 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
9020 name = proto_get_protocol_filter_name(proto_id);
9021
9022 if (!strcmp(name, proto_name))
9023 {
9024 return true1;
9025 }
9026
9027 protos = wmem_list_frame_next(protos);
9028 }
9029
9030 return false0;
9031}
9032
9033char *
9034proto_list_layers(const packet_info *pinfo)
9035{
9036 wmem_strbuf_t *buf;
9037 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
9038
9039 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
9040
9041 /* Walk the list of layers in the packet and
9042 return a string of all entries. */
9043 while (layers != NULL((void*)0))
9044 {
9045 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
9046
9047 layers = wmem_list_frame_next(layers);
9048 if (layers != NULL((void*)0)) {
9049 wmem_strbuf_append_c(buf, ':');
9050 }
9051 }
9052
9053 return wmem_strbuf_finalize(buf);
9054}
9055
9056uint8_t
9057proto_get_layer_num(const packet_info *pinfo, const int proto_id)
9058{
9059 int *proto_layer_num_ptr;
9060
9061 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
9062 if (proto_layer_num_ptr == NULL((void*)0)) {
9063 return 0;
9064 }
9065
9066 return (uint8_t)*proto_layer_num_ptr;
9067}
9068
9069bool_Bool
9070proto_is_pino(const protocol_t *protocol)
9071{
9072 return (protocol->parent_proto_id != -1);
9073}
9074
9075bool_Bool
9076proto_is_bytes_pino(const protocol_t *protocol)
9077{
9078 header_field_info *hfinfo;
9079
9080 if (!proto_is_pino(protocol))
9081 return false0;
9082
9083 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", 9083
, __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", 9083,
"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", 9083,
"gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[protocol->proto_id];
;
9084 return hfinfo->type != FT_PROTOCOL;
9085}
9086
9087bool_Bool
9088// NOLINTNEXTLINE(misc-no-recursion)
9089proto_is_protocol_enabled(const protocol_t *protocol)
9090{
9091 if (protocol == NULL((void*)0))
9092 return false0;
9093
9094 //parent protocol determines enable/disable for helper dissectors
9095 if (proto_is_pino(protocol))
9096 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9097
9098 return protocol->is_enabled;
9099}
9100
9101bool_Bool
9102// NOLINTNEXTLINE(misc-no-recursion)
9103proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9104{
9105 //parent protocol determines enable/disable for helper dissectors
9106 if (proto_is_pino(protocol))
9107 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9108
9109 return protocol->enabled_by_default;
9110}
9111
9112bool_Bool
9113// NOLINTNEXTLINE(misc-no-recursion)
9114proto_can_toggle_protocol(const int proto_id)
9115{
9116 protocol_t *protocol;
9117
9118 protocol = find_protocol_by_id(proto_id);
9119 //parent protocol determines toggling for helper dissectors
9120 if (proto_is_pino(protocol))
9121 return proto_can_toggle_protocol(protocol->parent_proto_id);
9122
9123 return protocol->can_toggle;
9124}
9125
9126void
9127proto_disable_by_default(const int proto_id)
9128{
9129 protocol_t *protocol;
9130
9131 protocol = find_protocol_by_id(proto_id);
9132 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9132, "protocol->can_toggle"
))))
;
9133 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", 9133, "proto_is_pino(protocol) == 0"
))))
;
9134 protocol->is_enabled = false0;
9135 protocol->enabled_by_default = false0;
9136}
9137
9138void
9139proto_set_decoding(const int proto_id, const bool_Bool enabled)
9140{
9141 protocol_t *protocol;
9142
9143 protocol = find_protocol_by_id(proto_id);
9144 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9144, "protocol->can_toggle"
))))
;
9145 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", 9145, "proto_is_pino(protocol) == 0"
))))
;
9146 protocol->is_enabled = enabled;
9147}
9148
9149void
9150proto_disable_all(void)
9151{
9152 /* This doesn't explicitly disable heuristic protocols,
9153 * but the heuristic doesn't get called if the parent
9154 * protocol isn't enabled.
9155 */
9156 protocol_t *protocol;
9157 GList *list_item = protocols;
9158
9159 if (protocols == NULL((void*)0))
9160 return;
9161
9162 while (list_item) {
9163 protocol = (protocol_t *)list_item->data;
9164 if (protocol->can_toggle) {
9165 protocol->is_enabled = false0;
9166 }
9167 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9168 }
9169}
9170
9171static void
9172heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9173{
9174 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9175
9176 heur->enabled = heur->enabled_by_default;
9177}
9178
9179void
9180proto_reenable_all(void)
9181{
9182 protocol_t *protocol;
9183 GList *list_item = protocols;
9184
9185 if (protocols == NULL((void*)0))
9186 return;
9187
9188 while (list_item) {
9189 protocol = (protocol_t *)list_item->data;
9190 if (protocol->can_toggle)
9191 protocol->is_enabled = protocol->enabled_by_default;
9192 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9193 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9194 }
9195}
9196
9197void
9198proto_set_cant_toggle(const int proto_id)
9199{
9200 protocol_t *protocol;
9201
9202 protocol = find_protocol_by_id(proto_id);
9203 protocol->can_toggle = false0;
9204}
9205
9206static int
9207proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9208{
9209 g_ptr_array_add(proto->fields, hfi);
9210
9211 return proto_register_field_init(hfi, parent);
9212}
9213
9214/* for use with static arrays only, since we don't allocate our own copies
9215of the header_field_info struct contained within the hf_register_info struct */
9216void
9217proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9218{
9219 hf_register_info *ptr = hf;
9220 protocol_t *proto;
9221 int i;
9222
9223 proto = find_protocol_by_id(parent);
9224
9225 /* if (proto == NULL) - error or return? */
9226
9227 if (proto->fields == NULL((void*)0)) {
9228 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9229 * GLib introduced g_ptr_array_new_from_array, which might have
9230 * given a reason to actually use it. (#17774)
9231 */
9232 proto->fields = g_ptr_array_sized_new(num_records);
9233 }
9234
9235 for (i = 0; i < num_records; i++, ptr++) {
9236 /*
9237 * Make sure we haven't registered this yet.
9238 * Most fields have variables associated with them that
9239 * are initialized to 0; some are initialized to -1 (which
9240 * was the standard before 4.4).
9241 *
9242 * XXX - Since this is called almost 300000 times at startup,
9243 * it might be nice to compare to only 0 and require
9244 * dissectors to pass in zero for unregistered fields.
9245 */
9246 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9247 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9248 "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)
9249 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9250 return;
9251 }
9252
9253 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9254 }
9255}
9256
9257/* deregister already registered fields */
9258void
9259proto_deregister_field (const int parent, int hf_id)
9260{
9261 header_field_info *hfi;
9262 protocol_t *proto;
9263 unsigned i;
9264
9265 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)
;
9266 last_field_name = NULL((void*)0);
9267
9268 if (hf_id == -1 || hf_id == 0)
9269 return;
9270
9271 proto = find_protocol_by_id (parent);
9272 if (!proto || proto->fields == NULL((void*)0)) {
9273 return;
9274 }
9275
9276 for (i = 0; i < proto->fields->len; i++) {
9277 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9278 if (hfi->id == hf_id) {
9279 /* Found the hf_id in this protocol */
9280 wmem_map_remove(gpa_name_map, hfi->abbrev);
9281 g_ptr_array_remove_index_fast(proto->fields, i);
9282 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9283 return;
9284 }
9285 }
9286}
9287
9288/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9289void
9290proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9291{
9292 header_field_info *hfinfo;
9293 protocol_t *proto;
9294
9295 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)
;
9296 last_field_name = NULL((void*)0);
9297
9298 proto = find_protocol_by_id(parent);
9299 if (proto && proto->fields && proto->fields->len > 0) {
9300 unsigned i = proto->fields->len;
9301 do {
9302 i--;
9303
9304 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9305 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) )
) {
9306 hfinfo_remove_from_gpa_name_map(hfinfo);
9307 expert_deregister_expertinfo(hfinfo->abbrev);
9308 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9309 g_ptr_array_remove_index_fast(proto->fields, i);
9310 }
9311 } while (i > 0);
9312 }
9313}
9314
9315void
9316proto_add_deregistered_data (void *data)
9317{
9318 g_ptr_array_add(deregistered_data, data);
9319}
9320
9321void
9322proto_add_deregistered_slice (size_t block_size, void *mem_block)
9323{
9324 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)))
;
9325
9326 slice_data->block_size = block_size;
9327 slice_data->mem_block = mem_block;
9328
9329 g_ptr_array_add(deregistered_slice, slice_data);
9330}
9331
9332void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9333{
9334 if (field_strings == NULL((void*)0)) {
9335 return;
9336 }
9337
9338 switch (field_type) {
9339 case FT_FRAMENUM:
9340 /* This is just an integer represented as a pointer */
9341 break;
9342 case FT_PROTOCOL: {
9343 protocol_t *protocol = (protocol_t *)field_strings;
9344 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)
;
9345 break;
9346 }
9347 case FT_BOOLEAN: {
9348 true_false_string *tf = (true_false_string *)field_strings;
9349 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)
;
9350 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)
;
9351 break;
9352 }
9353 case FT_UINT40:
9354 case FT_INT40:
9355 case FT_UINT48:
9356 case FT_INT48:
9357 case FT_UINT56:
9358 case FT_INT56:
9359 case FT_UINT64:
9360 case FT_INT64: {
9361 if (field_display & BASE_UNIT_STRING0x00001000) {
9362 unit_name_string *unit = (unit_name_string *)field_strings;
9363 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)
;
9364 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)
;
9365 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9366 range_string *rs = (range_string *)field_strings;
9367 while (rs->strptr) {
9368 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
)
;
9369 rs++;
9370 }
9371 } else if (field_display & BASE_EXT_STRING0x00000200) {
9372 val64_string_ext *vse = (val64_string_ext *)field_strings;
9373 val64_string *vs = (val64_string *)vse->_vs_p;
9374 while (vs->strptr) {
9375 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
)
;
9376 vs++;
9377 }
9378 val64_string_ext_free(vse);
9379 field_strings = NULL((void*)0);
9380 } else if (field_display == BASE_CUSTOM) {
9381 /* this will be a pointer to a function, don't free that */
9382 field_strings = NULL((void*)0);
9383 } else {
9384 val64_string *vs64 = (val64_string *)field_strings;
9385 while (vs64->strptr) {
9386 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)
;
9387 vs64++;
9388 }
9389 }
9390 break;
9391 }
9392 case FT_CHAR:
9393 case FT_UINT8:
9394 case FT_INT8:
9395 case FT_UINT16:
9396 case FT_INT16:
9397 case FT_UINT24:
9398 case FT_INT24:
9399 case FT_UINT32:
9400 case FT_INT32:
9401 case FT_FLOAT:
9402 case FT_DOUBLE: {
9403 if (field_display & BASE_UNIT_STRING0x00001000) {
9404 unit_name_string *unit = (unit_name_string *)field_strings;
9405 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)
;
9406 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)
;
9407 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9408 range_string *rs = (range_string *)field_strings;
9409 while (rs->strptr) {
9410 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
)
;
9411 rs++;
9412 }
9413 } else if (field_display & BASE_EXT_STRING0x00000200) {
9414 value_string_ext *vse = (value_string_ext *)field_strings;
9415 value_string *vs = (value_string *)vse->_vs_p;
9416 while (vs->strptr) {
9417 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
)
;
9418 vs++;
9419 }
9420 value_string_ext_free(vse);
9421 field_strings = NULL((void*)0);
9422 } else if (field_display == BASE_CUSTOM) {
9423 /* this will be a pointer to a function, don't free that */
9424 field_strings = NULL((void*)0);
9425 } else {
9426 value_string *vs = (value_string *)field_strings;
9427 while (vs->strptr) {
9428 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
)
;
9429 vs++;
9430 }
9431 }
9432 break;
9433 default:
9434 break;
9435 }
9436 }
9437
9438 if (field_type != FT_FRAMENUM) {
9439 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
)
;
9440 }
9441}
9442
9443static void
9444free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9445{
9446 header_field_info *hfi = (header_field_info *) data;
9447 int hf_id = hfi->id;
9448
9449 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
)
;
9450 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
)
;
9451 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
)
;
9452
9453 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9454
9455 if (hfi->parent == -1)
9456 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)
;
9457
9458 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9459}
9460
9461static void
9462free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9463{
9464 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9465}
9466
9467static void
9468free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9469{
9470 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9471
9472 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9473 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)
;
9474}
9475
9476/* free deregistered fields and data */
9477void
9478proto_free_deregistered_fields (void)
9479{
9480 expert_free_deregistered_expertinfos();
9481
9482 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9483 g_ptr_array_free(deregistered_fields, true1);
9484 deregistered_fields = g_ptr_array_new();
9485
9486 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9487 g_ptr_array_free(deregistered_data, true1);
9488 deregistered_data = g_ptr_array_new();
9489
9490 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9491 g_ptr_array_free(deregistered_slice, true1);
9492 deregistered_slice = g_ptr_array_new();
9493}
9494
9495static const value_string hf_display[] = {
9496 { BASE_NONE, "BASE_NONE" },
9497 { BASE_DEC, "BASE_DEC" },
9498 { BASE_HEX, "BASE_HEX" },
9499 { BASE_OCT, "BASE_OCT" },
9500 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9501 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9502 { BASE_CUSTOM, "BASE_CUSTOM" },
9503 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9504 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9505 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9506 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9507 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9508 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9509 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9510 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9511 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9512 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9513 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9514 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9515 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9516 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9517 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9518 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9519 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9520 { BASE_PT_UDP, "BASE_PT_UDP" },
9521 { BASE_PT_TCP, "BASE_PT_TCP" },
9522 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9523 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9524 { BASE_OUI, "BASE_OUI" },
9525 { 0, NULL((void*)0) } };
9526
9527const char* proto_field_display_to_string(int field_display)
9528{
9529 return val_to_str_const(field_display, hf_display, "Unknown");
9530}
9531
9532static inline port_type
9533display_to_port_type(field_display_e e)
9534{
9535 switch (e) {
9536 case BASE_PT_UDP:
9537 return PT_UDP;
9538 case BASE_PT_TCP:
9539 return PT_TCP;
9540 case BASE_PT_DCCP:
9541 return PT_DCCP;
9542 case BASE_PT_SCTP:
9543 return PT_SCTP;
9544 default:
9545 break;
9546 }
9547 return PT_NONE;
9548}
9549
9550/* temporary function containing assert part for easier profiling */
9551static void
9552tmp_fld_check_assert(header_field_info *hfinfo)
9553{
9554 char* tmp_str;
9555
9556 /* The field must have a name (with length > 0) */
9557 if (!hfinfo->name || !hfinfo->name[0]) {
9558 if (hfinfo->abbrev)
9559 /* Try to identify the field */
9560 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)
9561 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9562 else
9563 /* Hum, no luck */
9564 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)"
)
;
9565 }
9566
9567 /* fields with an empty string for an abbreviation aren't filterable */
9568 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9569 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)
;
9570
9571 /* TODO: This check is a significant percentage of startup time (~10%),
9572 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9573 It might be nice to have a way to disable this check when, e.g.,
9574 running TShark many times with the same configuration. */
9575 /* Check that the filter name (abbreviation) is legal;
9576 * it must contain only alphanumerics, '-', "_", and ".". */
9577 unsigned char c;
9578 c = module_check_valid_name(hfinfo->abbrev, false0);
9579 if (c) {
9580 if (c == '.') {
9581 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)
;
9582 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9583 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)
;
9584 } else {
9585 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)
;
9586 }
9587 }
9588
9589 /* These types of fields are allowed to have value_strings,
9590 * true_false_strings or a protocol_t struct
9591 */
9592 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9593 switch (hfinfo->type) {
9594
9595 /*
9596 * These types are allowed to support display value_strings,
9597 * value64_strings, the extended versions of the previous
9598 * two, range strings, or unit strings.
9599 */
9600 case FT_CHAR:
9601 case FT_UINT8:
9602 case FT_UINT16:
9603 case FT_UINT24:
9604 case FT_UINT32:
9605 case FT_UINT40:
9606 case FT_UINT48:
9607 case FT_UINT56:
9608 case FT_UINT64:
9609 case FT_INT8:
9610 case FT_INT16:
9611 case FT_INT24:
9612 case FT_INT32:
9613 case FT_INT40:
9614 case FT_INT48:
9615 case FT_INT56:
9616 case FT_INT64:
9617 case FT_BOOLEAN:
9618 case FT_PROTOCOL:
9619 break;
9620
9621 /*
9622 * This is allowed to have a value of type
9623 * enum ft_framenum_type to indicate what relationship
9624 * the frame in question has to the frame in which
9625 * the field is put.
9626 */
9627 case FT_FRAMENUM:
9628 break;
9629
9630 /*
9631 * These types are allowed to support only unit strings.
9632 */
9633 case FT_FLOAT:
9634 case FT_DOUBLE:
9635 case FT_IEEE_11073_SFLOAT:
9636 case FT_IEEE_11073_FLOAT:
9637 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9638 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))
9639 " (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))
9640 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))
;
9641 }
9642 break;
9643
9644 /*
9645 * These types are allowed to support display
9646 * time_value_strings.
9647 */
9648 case FT_ABSOLUTE_TIME:
9649 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9650 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9651 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9652 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9653 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))
9654 " (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))
9655 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))
;
9656 }
9657 break;
9658
9659 /*
9660 * This type is only allowed to support a string if it's
9661 * a protocol (for pinos).
9662 */
9663 case FT_BYTES:
9664 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9665 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))
9666 " (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))
9667 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))
;
9668 }
9669 break;
9670
9671 default:
9672 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))
9673 " (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))
9674 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))
;
9675 }
9676 }
9677
9678 /* TODO: This check may slow down startup, and output quite a few warnings.
9679 It would be good to be able to enable this (and possibly other checks?)
9680 in non-release builds. */
9681#ifdef ENABLE_CHECK_FILTER
9682 /* Check for duplicate value_string values.
9683 There are lots that have the same value *and* string, so for now only
9684 report those that have same value but different string. */
9685 if ((hfinfo->strings != NULL((void*)0)) &&
9686 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9687 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9688 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9689 (
9690 (hfinfo->type == FT_CHAR) ||
9691 (hfinfo->type == FT_UINT8) ||
9692 (hfinfo->type == FT_UINT16) ||
9693 (hfinfo->type == FT_UINT24) ||
9694 (hfinfo->type == FT_UINT32) ||
9695 (hfinfo->type == FT_INT8) ||
9696 (hfinfo->type == FT_INT16) ||
9697 (hfinfo->type == FT_INT24) ||
9698 (hfinfo->type == FT_INT32) )) {
9699
9700 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9701 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9702 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9703 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9704 } else {
9705 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9706 CHECK_HF_VALUE(value_string, "u", start_values);
9707 }
9708 } else {
9709 const value_string *start_values = (const value_string*)hfinfo->strings;
9710 CHECK_HF_VALUE(value_string, "u", start_values);
9711 }
9712 }
9713
9714 if (hfinfo->type == FT_BOOLEAN) {
9715 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9716 if (tfs) {
9717 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9718 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9720
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9719 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9720
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9720 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9720
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9721 }
9722 }
9723 }
9724
9725 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9726 const range_string *rs = (const range_string*)(hfinfo->strings);
9727 if (rs) {
9728 const range_string *this_it = rs;
9729
9730 do {
9731 if (this_it->value_max < this_it->value_min) {
9732 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"
, 9736, __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)
9733 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9736, __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)
9734 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9736, __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)
9735 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9736, __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)
9736 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9736, __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)
;
9737 ++this_it;
9738 continue;
9739 }
9740
9741 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9742 /* Not OK if this one is completely hidden by an earlier one! */
9743 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9744 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"
, 9750, __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)
9745 "(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"
, 9750, __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)
9746 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9750, __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)
9747 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9750, __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)
9748 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9750, __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)
9749 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9750, __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)
9750 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9750, __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)
;
9751 }
9752 }
9753 ++this_it;
9754 } while (this_it->strptr);
9755 }
9756 }
9757#endif
9758
9759 switch (hfinfo->type) {
9760
9761 case FT_CHAR:
9762 /* Require the char type to have BASE_HEX, BASE_OCT,
9763 * BASE_CUSTOM, or BASE_NONE as its base.
9764 *
9765 * If the display value is BASE_NONE and there is a
9766 * strings conversion then the dissector writer is
9767 * telling us that the field's numerical value is
9768 * meaningless; we'll avoid showing the value to the
9769 * user.
9770 */
9771 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9772 case BASE_HEX:
9773 case BASE_OCT:
9774 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9775 break;
9776 case BASE_NONE:
9777 if (hfinfo->strings == NULL((void*)0))
9778 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
))
9779 " 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
))
9780 " 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
))
9781 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
))
9782 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
))
;
9783 break;
9784 default:
9785 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9786 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)
9787 " 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)
9788 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)
9789 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)
;
9790 //wmem_free(NULL, tmp_str);
9791 }
9792 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9793 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
))
9794 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
))
9795 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
))
;
9796 }
9797 break;
9798 case FT_INT8:
9799 case FT_INT16:
9800 case FT_INT24:
9801 case FT_INT32:
9802 case FT_INT40:
9803 case FT_INT48:
9804 case FT_INT56:
9805 case FT_INT64:
9806 /* Hexadecimal and octal are, in printf() and everywhere
9807 * else, unsigned so don't allow dissectors to register a
9808 * signed field to be displayed unsigned. (Else how would
9809 * we display negative values?)
9810 */
9811 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9812 case BASE_HEX:
9813 case BASE_OCT:
9814 case BASE_DEC_HEX:
9815 case BASE_HEX_DEC:
9816 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9817 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)
9818 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)
9819 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)
;
9820 //wmem_free(NULL, tmp_str);
9821 }
9822 /* FALL THROUGH */
9823 case FT_UINT8:
9824 case FT_UINT16:
9825 case FT_UINT24:
9826 case FT_UINT32:
9827 case FT_UINT40:
9828 case FT_UINT48:
9829 case FT_UINT56:
9830 case FT_UINT64:
9831 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
))
) {
9832 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9833 if (hfinfo->type != FT_UINT16) {
9834 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))
9835 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))
9836 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))
;
9837 }
9838 if (hfinfo->strings != NULL((void*)0)) {
9839 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)
9840 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)
9841 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)
;
9842 }
9843 if (hfinfo->bitmask != 0) {
9844 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)
9845 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)
9846 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)
;
9847 }
9848 wmem_free(NULL((void*)0), tmp_str);
9849 break;
9850 }
9851
9852 if (hfinfo->display == BASE_OUI) {
9853 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9854 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) {
9855 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))
9856 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))
9857 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))
;
9858 }
9859 if (hfinfo->strings != NULL((void*)0)) {
9860 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)
9861 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)
9862 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)
;
9863 }
9864 /* It can be a FT_UINT24 with a 0 bitmask, or
9865 * larger with a bitmask with 24 bits set. */
9866 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9867 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)
9868 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)
9869 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)
;
9870 }
9871 wmem_free(NULL((void*)0), tmp_str);
9872 break;
9873 }
9874
9875 /* Require integral types (other than frame number,
9876 * which is always displayed in decimal) to have a
9877 * number base.
9878 *
9879 * If the display value is BASE_NONE and there is a
9880 * strings conversion then the dissector writer is
9881 * telling us that the field's numerical value is
9882 * meaningless; we'll avoid showing the value to the
9883 * user.
9884 */
9885 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9886 case BASE_DEC:
9887 case BASE_HEX:
9888 case BASE_OCT:
9889 case BASE_DEC_HEX:
9890 case BASE_HEX_DEC:
9891 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9892 break;
9893 case BASE_NONE:
9894 if (hfinfo->strings == NULL((void*)0)) {
9895 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
))
9896 " 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
))
9897 " 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
))
9898 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
))
9899 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
))
;
9900 }
9901 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9902 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
))
9903 " 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
))
9904 " 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
))
9905 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
))
9906 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
))
;
9907 }
9908 break;
9909
9910 default:
9911 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9912 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)
9913 " 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)
9914 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)
9915 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)
;
9916 //wmem_free(NULL, tmp_str);
9917 }
9918 break;
9919 case FT_BYTES:
9920 case FT_UINT_BYTES:
9921 /* Require bytes to have a "display type" that could
9922 * add a character between displayed bytes.
9923 */
9924 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9925 case BASE_NONE:
9926 case SEP_DOT:
9927 case SEP_DASH:
9928 case SEP_COLON:
9929 case SEP_SPACE:
9930 break;
9931 default:
9932 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9933 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)
9934 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)
;
9935 //wmem_free(NULL, tmp_str);
9936 }
9937 if (hfinfo->bitmask != 0)
9938 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
))
9939 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
))
9940 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
))
;
9941 //allowed to support string if its a protocol (for pinos)
9942 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9943 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
))
9944 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
))
9945 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
))
;
9946 break;
9947
9948 case FT_PROTOCOL:
9949 case FT_FRAMENUM:
9950 if (hfinfo->display != BASE_NONE) {
9951 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9952 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)
9953 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)
9954 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)
;
9955 //wmem_free(NULL, tmp_str);
9956 }
9957 if (hfinfo->bitmask != 0)
9958 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
))
9959 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
))
9960 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
))
;
9961 break;
9962
9963 case FT_BOOLEAN:
9964 break;
9965
9966 case FT_ABSOLUTE_TIME:
9967 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9968 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9969 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)
9970 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)
;
9971 //wmem_free(NULL, tmp_str);
9972 }
9973 if (hfinfo->bitmask != 0)
9974 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
))
9975 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
))
9976 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
))
;
9977 break;
9978
9979 case FT_STRING:
9980 case FT_STRINGZ:
9981 case FT_UINT_STRING:
9982 case FT_STRINGZPAD:
9983 case FT_STRINGZTRUNC:
9984 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9985 case BASE_NONE:
9986 case BASE_STR_WSP:
9987 break;
9988
9989 default:
9990 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9991 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)
9992 " 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)
9993 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)
9994 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)
;
9995 //wmem_free(NULL, tmp_str);
9996 }
9997
9998 if (hfinfo->bitmask != 0)
9999 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
))
10000 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
))
10001 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
))
;
10002 if (hfinfo->strings != NULL((void*)0))
10003 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
))
10004 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
))
10005 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
))
;
10006 break;
10007
10008 case FT_IPv4:
10009 switch (hfinfo->display) {
10010 case BASE_NONE:
10011 case BASE_NETMASK:
10012 break;
10013
10014 default:
10015 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10016 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)
10017 " 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)
10018 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)
10019 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)
;
10020 //wmem_free(NULL, tmp_str);
10021 break;
10022 }
10023 break;
10024 case FT_FLOAT:
10025 case FT_DOUBLE:
10026 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
10027 case BASE_NONE:
10028 case BASE_DEC:
10029 case BASE_HEX:
10030 case BASE_EXP:
10031 case BASE_CUSTOM:
10032 break;
10033 default:
10034 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10035 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)
10036 " 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)
10037 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)
10038 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)
;
10039 //wmem_free(NULL, tmp_str);
10040 }
10041 if (hfinfo->bitmask != 0)
10042 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
))
10043 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
))
10044 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
))
;
10045 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10046 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
))
10047 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
))
10048 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
))
;
10049 break;
10050 case FT_IEEE_11073_SFLOAT:
10051 case FT_IEEE_11073_FLOAT:
10052 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
10053 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10054 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)
10055 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)
10056 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)
10057 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)
;
10058 //wmem_free(NULL, tmp_str);
10059 }
10060 if (hfinfo->bitmask != 0)
10061 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
))
10062 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
))
10063 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
))
;
10064 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10065 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
))
10066 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
))
10067 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
))
;
10068 break;
10069 default:
10070 if (hfinfo->display != BASE_NONE) {
10071 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10072 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)
10073 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)
10074 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)
10075 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)
;
10076 //wmem_free(NULL, tmp_str);
10077 }
10078 if (hfinfo->bitmask != 0)
10079 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
))
10080 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
))
10081 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
))
;
10082 if (hfinfo->strings != NULL((void*)0))
10083 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
))
10084 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
))
10085 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
))
;
10086 break;
10087 }
10088}
10089
10090static void
10091register_type_length_mismatch(void)
10092{
10093 static ei_register_info ei[] = {
10094 { &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)}}
}},
10095 { &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)}}
}},
10096 };
10097
10098 expert_module_t* expert_type_length_mismatch;
10099
10100 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10101
10102 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10103 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10104
10105 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10106 disabling them makes no sense. */
10107 proto_set_cant_toggle(proto_type_length_mismatch);
10108}
10109
10110static void
10111register_byte_array_string_decodinws_error(void)
10112{
10113 static ei_register_info ei[] = {
10114 { &ei_byte_array_string_decoding_failed_error,
10115 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10116 "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)}}
10117 }
10118 },
10119 };
10120
10121 expert_module_t* expert_byte_array_string_decoding_error;
10122
10123 proto_byte_array_string_decoding_error =
10124 proto_register_protocol("Byte Array-String Decoding Error",
10125 "Byte Array-string decoding error",
10126 "_ws.byte_array_string.decoding_error");
10127
10128 expert_byte_array_string_decoding_error =
10129 expert_register_protocol(proto_byte_array_string_decoding_error);
10130 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10131
10132 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10133 disabling them makes no sense. */
10134 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10135}
10136
10137static void
10138register_date_time_string_decodinws_error(void)
10139{
10140 static ei_register_info ei[] = {
10141 { &ei_date_time_string_decoding_failed_error,
10142 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10143 "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)}}
10144 }
10145 },
10146 };
10147
10148 expert_module_t* expert_date_time_string_decoding_error;
10149
10150 proto_date_time_string_decoding_error =
10151 proto_register_protocol("Date and Time-String Decoding Error",
10152 "Date and Time-string decoding error",
10153 "_ws.date_time_string.decoding_error");
10154
10155 expert_date_time_string_decoding_error =
10156 expert_register_protocol(proto_date_time_string_decoding_error);
10157 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10158
10159 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10160 disabling them makes no sense. */
10161 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10162}
10163
10164static void
10165register_string_errors(void)
10166{
10167 static ei_register_info ei[] = {
10168 { &ei_string_trailing_characters,
10169 { "_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)}}
}
10170 },
10171 };
10172
10173 expert_module_t* expert_string_errors;
10174
10175 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10176
10177 expert_string_errors = expert_register_protocol(proto_string_errors);
10178 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10179
10180 /* "String Errors" isn't really a protocol, it's an error indication;
10181 disabling them makes no sense. */
10182 proto_set_cant_toggle(proto_string_errors);
10183}
10184
10185static void
10186register_varint_errors(void)
10187{
10188 static ei_register_info ei[] = {
10189 { &ei_varint_decoding_failed_error,
10190 { "_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)}}
}
10191 },
10192 };
10193
10194 expert_module_t* expert_varint_errors;
10195
10196 proto_varint_errors = proto_register_protocol("Varint Errors", "Varint errors", "_ws.varint");
10197
10198 expert_varint_errors = expert_register_protocol(proto_varint_errors);
10199 expert_register_field_array(expert_varint_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10200
10201 /* "Varint Errors" isn't really a protocol, it's an error indication;
10202 disabling them makes no sense. */
10203 proto_set_cant_toggle(proto_varint_errors);
10204}
10205
10206static int
10207proto_register_field_init(header_field_info *hfinfo, const int parent)
10208{
10209
10210 tmp_fld_check_assert(hfinfo);
10211
10212 hfinfo->parent = parent;
10213 hfinfo->same_name_next = NULL((void*)0);
10214 hfinfo->same_name_prev_id = -1;
10215
10216 /* if we always add and never delete, then id == len - 1 is correct */
10217 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10218 if (!gpa_hfinfo.hfi) {
10219 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10220 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10221 /* The entry with index 0 is not used. */
10222 gpa_hfinfo.hfi[0] = NULL((void*)0);
10223 gpa_hfinfo.len = 1;
10224 } else {
10225 gpa_hfinfo.allocated_len += 1000;
10226 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10227 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10228 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10229 }
10230 }
10231 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10232 gpa_hfinfo.len++;
10233 hfinfo->id = gpa_hfinfo.len - 1;
10234
10235 /* if we have real names, enter this field in the name tree */
10236 /* Already checked in tmp_fld_check_assert */
10237 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10238 {
10239
10240 header_field_info *same_name_next_hfinfo;
10241
10242 /* We allow multiple hfinfo's to be registered under the same
10243 * abbreviation. This was done for X.25, as, depending
10244 * on whether it's modulo-8 or modulo-128 operation,
10245 * some bitfield fields may be in different bits of
10246 * a byte, and we want to be able to refer to that field
10247 * with one name regardless of whether the packets
10248 * are modulo-8 or modulo-128 packets. */
10249
10250 /* wmem_map_insert - if key is already present the previous
10251 * hfinfo with the same key/name is returned, otherwise NULL */
10252 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10253 if (same_name_hfinfo) {
10254 /* There's already a field with this name.
10255 * Put the current field *before* that field
10256 * in the list of fields with this name, Thus,
10257 * we end up with an effectively
10258 * doubly-linked-list of same-named hfinfo's,
10259 * with the head of the list (stored in the
10260 * hash) being the last seen hfinfo.
10261 */
10262 same_name_next_hfinfo =
10263 same_name_hfinfo->same_name_next;
10264
10265 hfinfo->same_name_next = same_name_next_hfinfo;
10266 if (same_name_next_hfinfo)
10267 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10268
10269 same_name_hfinfo->same_name_next = hfinfo;
10270 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10271#ifdef ENABLE_CHECK_FILTER
10272 while (same_name_hfinfo) {
10273 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10274 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", 10274
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10275 same_name_hfinfo = same_name_hfinfo->same_name_next;
10276 }
10277#endif
10278 }
10279 }
10280
10281 return hfinfo->id;
10282}
10283
10284void
10285proto_register_subtree_array(int * const *indices, const int num_indices)
10286{
10287 int i;
10288 int *const *ptr = indices;
10289
10290 /*
10291 * If we've already allocated the array of tree types, expand
10292 * it; this lets plugins such as mate add tree types after
10293 * the initial startup. (If we haven't already allocated it,
10294 * we don't allocate it; on the first pass, we just assign
10295 * ett values and keep track of how many we've assigned, and
10296 * when we're finished registering all dissectors we allocate
10297 * the array, so that we do only one allocation rather than
10298 * wasting CPU time and memory by growing the array for each
10299 * dissector that registers ett values.)
10300 */
10301 if (tree_is_expanded != NULL((void*)0)) {
10302 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10303
10304 /* set new items to 0 */
10305 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10306 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10307 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10308 }
10309
10310 /*
10311 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10312 * returning the indices through the pointers in the array whose
10313 * first element is pointed to by "indices", and update
10314 * "num_tree_types" appropriately.
10315 */
10316 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10317 if (**ptr != -1 && **ptr != 0) {
10318 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.")
10319 " 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.")
10320 " 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.")
10321 " 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.")
;
10322 }
10323 **ptr = num_tree_types;
10324 }
10325}
10326
10327static void
10328mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10329{
10330 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10331 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10332 char *last_char;
10333
10334 /* ..... field_name: dataaaaaaaaaaaaa
10335 * |
10336 * ^^^^^ name_pos
10337 *
10338 * ..... field_name […]: dataaaaaaaaaaaaa
10339 *
10340 * name_pos==0 means that we have only data or only a field_name
10341 */
10342
10343 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10343, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10344
10345 if (name_pos >= size - trunc_len) {
10346 /* No room for trunc_str after the field_name, put it first. */
10347 name_pos = 0;
10348 }
10349
10350 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10351 if (name_pos == 0) {
10352 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10353 memcpy(label_str, trunc_str + 1, trunc_len);
10354 } else {
10355 memcpy(label_str + name_pos, trunc_str, trunc_len);
10356 }
10357 /* in general, label_str is UTF-8
10358 we can truncate it only at the beginning of a new character
10359 we go backwards from the byte right after our buffer and
10360 find the next starting byte of a UTF-8 character, this is
10361 where we cut
10362 there's no need to use g_utf8_find_prev_char(), the search
10363 will always succeed since we copied trunc_str into the
10364 buffer */
10365 /* g_utf8_prev_char does not deference the memory address
10366 * passed in (until after decrementing it, so it is perfectly
10367 * legal to pass in a pointer one past the last element.
10368 */
10369 last_char = g_utf8_prev_char(label_str + size);
10370 *last_char = '\0';
10371 /* This is unnecessary (above always terminates), but try to
10372 * convince Coverity to avoid dozens of false positives. */
10373 label_str[size - 1] = '\0';
10374
10375 if (value_pos && *value_pos > 0) {
10376 if (name_pos == 0) {
10377 *value_pos += trunc_len;
10378 } else {
10379 /* Move one back to include trunc_str in the value. */
10380 *value_pos -= 1;
10381 }
10382 }
10383
10384 /* Check if value_pos is past label_str. */
10385 if (value_pos && *value_pos >= size) {
10386 *value_pos = size - 1;
10387 }
10388}
10389
10390static void
10391label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10392{
10393 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10394}
10395
10396static size_t
10397label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10398{
10399 size_t name_pos;
10400
10401 /* "%s: %s", hfinfo->name, text */
10402 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)
;
10403 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10404 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10405 if (value_pos) {
10406 *value_pos = pos;
10407 }
10408 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10409 }
10410
10411 if (pos >= ITEM_LABEL_LENGTH240) {
10412 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10413 label_mark_truncated(label_str, name_pos, value_pos);
10414 }
10415
10416 return pos;
10417}
10418
10419static size_t
10420label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10421{
10422 size_t name_pos;
10423
10424 /* "%s: %s (%s)", hfinfo->name, text, descr */
10425 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)
;
10426 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10427 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10428 if (value_pos) {
10429 *value_pos = pos;
10430 }
10431 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10432 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)
;
10433 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)
;
10434 } else {
10435 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)
;
10436 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10437 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)
;
10438 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10439 }
10440 }
10441
10442 if (pos >= ITEM_LABEL_LENGTH240) {
10443 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10444 label_mark_truncated(label_str, name_pos, value_pos);
10445 }
10446
10447 return pos;
10448}
10449
10450void
10451proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10452{
10453 const header_field_info *hfinfo;
10454 const char *str;
10455 const uint8_t *bytes;
10456 uint32_t integer;
10457 const ipv4_addr_and_mask *ipv4;
10458 const ipv6_addr_and_prefix *ipv6;
10459 const e_guid_t *guid;
10460 char *name;
10461 address addr;
10462 char *addr_str;
10463 char *tmp;
10464
10465 if (!label_str) {
10466 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10466, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10467 return;
10468 }
10469
10470 label_str[0]= '\0';
10471
10472 if (!fi) {
10473 return;
10474 }
10475
10476 hfinfo = fi->hfinfo;
10477
10478 switch (hfinfo->type) {
10479 case FT_NONE:
10480 case FT_PROTOCOL:
10481 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10482 if (value_pos) {
10483 *value_pos = strlen(hfinfo->name);
10484 }
10485 break;
10486
10487 case FT_BOOLEAN:
10488 fill_label_boolean(fi, label_str, value_pos);
10489 break;
10490
10491 case FT_BYTES:
10492 case FT_UINT_BYTES:
10493 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10494 fvalue_get_bytes_data(fi->value),
10495 (unsigned)fvalue_length2(fi->value));
10496 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10497 wmem_free(NULL((void*)0), tmp);
10498 break;
10499
10500 case FT_CHAR:
10501 if (hfinfo->bitmask) {
10502 fill_label_bitfield_char(fi, label_str, value_pos);
10503 } else {
10504 fill_label_char(fi, label_str, value_pos);
10505 }
10506 break;
10507
10508 /* Four types of integers to take care of:
10509 * Bitfield, with val_string
10510 * Bitfield, w/o val_string
10511 * Non-bitfield, with val_string
10512 * Non-bitfield, w/o val_string
10513 */
10514 case FT_UINT8:
10515 case FT_UINT16:
10516 case FT_UINT24:
10517 case FT_UINT32:
10518 if (hfinfo->bitmask) {
10519 fill_label_bitfield(fi, label_str, value_pos, false0);
10520 } else {
10521 fill_label_number(fi, label_str, value_pos, false0);
10522 }
10523 break;
10524
10525 case FT_FRAMENUM:
10526 fill_label_number(fi, label_str, value_pos, false0);
10527 break;
10528
10529 case FT_UINT40:
10530 case FT_UINT48:
10531 case FT_UINT56:
10532 case FT_UINT64:
10533 if (hfinfo->bitmask) {
10534 fill_label_bitfield64(fi, label_str, value_pos, false0);
10535 } else {
10536 fill_label_number64(fi, label_str, value_pos, false0);
10537 }
10538 break;
10539
10540 case FT_INT8:
10541 case FT_INT16:
10542 case FT_INT24:
10543 case FT_INT32:
10544 if (hfinfo->bitmask) {
10545 fill_label_bitfield(fi, label_str, value_pos, true1);
10546 } else {
10547 fill_label_number(fi, label_str, value_pos, true1);
10548 }
10549 break;
10550
10551 case FT_INT40:
10552 case FT_INT48:
10553 case FT_INT56:
10554 case FT_INT64:
10555 if (hfinfo->bitmask) {
10556 fill_label_bitfield64(fi, label_str, value_pos, true1);
10557 } else {
10558 fill_label_number64(fi, label_str, value_pos, true1);
10559 }
10560 break;
10561
10562 case FT_FLOAT:
10563 case FT_DOUBLE:
10564 fill_label_float(fi, label_str, value_pos);
10565 break;
10566
10567 case FT_ABSOLUTE_TIME:
10568 {
10569 const nstime_t *value = fvalue_get_time(fi->value);
10570 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10571 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10572 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10573 }
10574 if (hfinfo->strings) {
10575 /*
10576 * Table of time values to be displayed
10577 * specially.
10578 *
10579 * XXX - Initializing these time_value_strings can be a pain
10580 * because the special times usually have special values in
10581 * the original encoding, not when converted to a nstime_t
10582 * relative to the UN*X epoch.
10583 */
10584 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10585 if (time_string != NULL((void*)0)) {
10586 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10587 break;
10588 }
10589 }
10590 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10591 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10592 wmem_free(NULL((void*)0), tmp);
10593 break;
10594 }
10595 case FT_RELATIVE_TIME:
10596 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10597 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10598 wmem_free(NULL((void*)0), tmp);
10599 break;
10600
10601 case FT_IPXNET:
10602 integer = fvalue_get_uinteger(fi->value);
10603 tmp = get_ipxnet_name(NULL((void*)0), integer);
10604 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10605 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10606 wmem_free(NULL((void*)0), tmp);
10607 wmem_free(NULL((void*)0), addr_str);
10608 break;
10609
10610 case FT_VINES:
10611 addr.type = AT_VINES;
10612 addr.len = VINES_ADDR_LEN6;
10613 addr.data = fvalue_get_bytes_data(fi->value);
10614
10615 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10616 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10617 wmem_free(NULL((void*)0), addr_str);
10618 break;
10619
10620 case FT_ETHER:
10621 bytes = fvalue_get_bytes_data(fi->value);
10622
10623 addr.type = AT_ETHER;
10624 addr.len = 6;
10625 addr.data = bytes;
10626
10627 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10628 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10629 wmem_free(NULL((void*)0), addr_str);
10630 break;
10631
10632 case FT_IPv4:
10633 ipv4 = fvalue_get_ipv4(fi->value);
10634 set_address_ipv4(&addr, ipv4);
10635
10636 if (hfinfo->display == BASE_NETMASK) {
10637 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10638 } else {
10639 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10640 }
10641 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10642 wmem_free(NULL((void*)0), addr_str);
10643 free_address(&addr);
10644 break;
10645
10646 case FT_IPv6:
10647 ipv6 = fvalue_get_ipv6(fi->value);
10648 set_address_ipv6(&addr, ipv6);
10649
10650 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10651 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10652 wmem_free(NULL((void*)0), addr_str);
10653 free_address(&addr);
10654 break;
10655
10656 case FT_FCWWN:
10657 bytes = fvalue_get_bytes_data(fi->value);
10658 addr.type = AT_FCWWN;
10659 addr.len = FCWWN_ADDR_LEN8;
10660 addr.data = bytes;
10661
10662 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10663 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10664 wmem_free(NULL((void*)0), addr_str);
10665 break;
10666
10667 case FT_GUID:
10668 guid = fvalue_get_guid(fi->value);
10669 tmp = guid_to_str(NULL((void*)0), guid);
10670 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10671 wmem_free(NULL((void*)0), tmp);
10672 break;
10673
10674 case FT_OID:
10675 bytes = fvalue_get_bytes_data(fi->value);
10676 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10677 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10678 if (name) {
10679 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10680 wmem_free(NULL((void*)0), name);
10681 } else {
10682 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10683 }
10684 wmem_free(NULL((void*)0), tmp);
10685 break;
10686
10687 case FT_REL_OID:
10688 bytes = fvalue_get_bytes_data(fi->value);
10689 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10690 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10691 if (name) {
10692 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10693 wmem_free(NULL((void*)0), name);
10694 } else {
10695 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10696 }
10697 wmem_free(NULL((void*)0), tmp);
10698 break;
10699
10700 case FT_SYSTEM_ID:
10701 bytes = fvalue_get_bytes_data(fi->value);
10702 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10703 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10704 wmem_free(NULL((void*)0), tmp);
10705 break;
10706
10707 case FT_EUI64:
10708 bytes = fvalue_get_bytes_data(fi->value);
10709 addr.type = AT_EUI64;
10710 addr.len = EUI64_ADDR_LEN8;
10711 addr.data = bytes;
10712
10713 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10714 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10715 wmem_free(NULL((void*)0), addr_str);
10716 break;
10717 case FT_STRING:
10718 case FT_STRINGZ:
10719 case FT_UINT_STRING:
10720 case FT_STRINGZPAD:
10721 case FT_STRINGZTRUNC:
10722 case FT_AX25:
10723 str = fvalue_get_string(fi->value);
10724 label_fill(label_str, 0, hfinfo, str, value_pos);
10725 break;
10726
10727 case FT_IEEE_11073_SFLOAT:
10728 case FT_IEEE_11073_FLOAT:
10729 fill_label_ieee_11073_float(fi, label_str, value_pos);
10730 break;
10731
10732 default:
10733 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
))
10734 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
))
10735 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
))
10736 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
))
;
10737 break;
10738 }
10739}
10740
10741static void
10742fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10743{
10744 char *p;
10745 unsigned bitfield_byte_length = 0;
10746 int bitwidth;
10747 uint64_t unshifted_value;
10748 uint64_t value;
10749
10750 const header_field_info *hfinfo = fi->hfinfo;
10751
10752 value = fvalue_get_uinteger64(fi->value);
10753 if (hfinfo->bitmask) {
10754 /* Figure out the bit width */
10755 bitwidth = hfinfo_container_bitwidth(hfinfo);
10756
10757 /* Un-shift bits */
10758 unshifted_value = value;
10759 unshifted_value <<= hfinfo_bitshift(hfinfo);
10760
10761 /* Create the bitfield first */
10762 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10763 bitfield_byte_length = (unsigned) (p - label_str);
10764 }
10765
10766 /* Fill in the textual info */
10767 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10768}
10769
10770static const char *
10771hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10772{
10773 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10774 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10775
10776 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10777 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10778 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10779 else
10780 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10781 }
10782
10783 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10784 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10785
10786 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10787 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10788
10789 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10790}
10791
10792static const char *
10793hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10794{
10795 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10796 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10797 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10798 else
10799 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10800 }
10801
10802 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10803 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10804
10805 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10806 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10807
10808 /* If this is reached somebody registered a 64-bit field with a 32-bit
10809 * value-string, which isn't right. */
10810 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)
10811 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10812
10813 /* This is necessary to squelch MSVC errors; is there
10814 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10815 never returns? */
10816 return NULL((void*)0);
10817}
10818
10819static const char *
10820hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10821{
10822 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10823 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10824
10825 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)
;
10826
10827 /* This is necessary to squelch MSVC errors; is there
10828 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10829 never returns? */
10830 return NULL((void*)0);
10831}
10832
10833static const char *
10834hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10835{
10836 const char *str = hf_try_val_to_str(value, hfinfo);
10837
10838 return (str) ? str : unknown_str;
10839}
10840
10841static const char *
10842hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10843{
10844 const char *str = hf_try_val64_to_str(value, hfinfo);
10845
10846 return (str) ? str : unknown_str;
10847}
10848
10849/* Fills data for bitfield chars with val_strings */
10850static void
10851fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10852{
10853 char *p;
10854 unsigned bitfield_byte_length;
10855 int bitwidth;
10856 uint32_t unshifted_value;
10857 uint32_t value;
10858
10859 char buf[32];
10860 const char *out;
10861
10862 const header_field_info *hfinfo = fi->hfinfo;
10863
10864 /* Figure out the bit width */
10865 bitwidth = hfinfo_container_bitwidth(hfinfo);
10866
10867 /* Un-shift bits */
10868 value = fvalue_get_uinteger(fi->value);
10869
10870 unshifted_value = value;
10871 if (hfinfo->bitmask) {
10872 unshifted_value <<= hfinfo_bitshift(hfinfo);
10873 }
10874
10875 /* Create the bitfield first */
10876 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10877 bitfield_byte_length = (unsigned) (p - label_str);
10878
10879 /* Fill in the textual info using stored (shifted) value */
10880 if (hfinfo->display == BASE_CUSTOM) {
10881 char tmp[ITEM_LABEL_LENGTH240];
10882 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10883
10884 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10884, "fmtfunc"))))
;
10885 fmtfunc(tmp, value);
10886 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10887 }
10888 else if (hfinfo->strings) {
10889 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10890
10891 out = hfinfo_char_vals_format(hfinfo, buf, value);
10892 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10893 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10894 else
10895 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10896 }
10897 else {
10898 out = hfinfo_char_value_format(hfinfo, buf, value);
10899
10900 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10901 }
10902}
10903
10904/* Fills data for bitfield ints with val_strings */
10905static void
10906fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10907{
10908 char *p;
10909 unsigned bitfield_byte_length;
10910 int bitwidth;
10911 uint32_t value, unshifted_value;
10912 char buf[NUMBER_LABEL_LENGTH80];
10913 const char *out;
10914
10915 const header_field_info *hfinfo = fi->hfinfo;
10916
10917 /* Figure out the bit width */
10918 if (fi->flags & FI_VARINT0x00040000)
10919 bitwidth = fi->length*8;
10920 else
10921 bitwidth = hfinfo_container_bitwidth(hfinfo);
10922
10923 /* Un-shift bits */
10924 if (is_signed)
10925 value = fvalue_get_sinteger(fi->value);
10926 else
10927 value = fvalue_get_uinteger(fi->value);
10928
10929 unshifted_value = value;
10930 if (hfinfo->bitmask) {
10931 unshifted_value <<= hfinfo_bitshift(hfinfo);
10932 }
10933
10934 /* Create the bitfield first */
10935 if (fi->flags & FI_VARINT0x00040000)
10936 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10937 else
10938 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10939 bitfield_byte_length = (unsigned) (p - label_str);
10940
10941 /* Fill in the textual info using stored (shifted) value */
10942 if (hfinfo->display == BASE_CUSTOM) {
10943 char tmp[ITEM_LABEL_LENGTH240];
10944 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10945
10946 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10946, "fmtfunc"))))
;
10947 fmtfunc(tmp, value);
10948 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10949 }
10950 else if (hfinfo->strings) {
10951 const char *val_str = hf_try_val_to_str(value, hfinfo);
10952
10953 out = hfinfo_number_vals_format(hfinfo, buf, value);
10954 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10955 /*
10956 * Unique values only display value_string string
10957 * if there is a match. Otherwise it's just a number
10958 */
10959 if (val_str) {
10960 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10961 } else {
10962 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10963 }
10964 } else {
10965 if (val_str == NULL((void*)0))
10966 val_str = "Unknown";
10967
10968 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10969 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10970 else
10971 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10972 }
10973 }
10974 else {
10975 out = hfinfo_number_value_format(hfinfo, buf, value);
10976
10977 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10978 }
10979}
10980
10981static void
10982fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10983{
10984 char *p;
10985 unsigned bitfield_byte_length;
10986 int bitwidth;
10987 uint64_t value, unshifted_value;
10988 char buf[NUMBER_LABEL_LENGTH80];
10989 const char *out;
10990
10991 const header_field_info *hfinfo = fi->hfinfo;
10992
10993 /* Figure out the bit width */
10994 if (fi->flags & FI_VARINT0x00040000)
10995 bitwidth = fi->length*8;
10996 else
10997 bitwidth = hfinfo_container_bitwidth(hfinfo);
10998
10999 /* Un-shift bits */
11000 if (is_signed)
11001 value = fvalue_get_sinteger64(fi->value);
11002 else
11003 value = fvalue_get_uinteger64(fi->value);
11004
11005 unshifted_value = value;
11006 if (hfinfo->bitmask) {
11007 unshifted_value <<= hfinfo_bitshift(hfinfo);
11008 }
11009
11010 /* Create the bitfield first */
11011 if (fi->flags & FI_VARINT0x00040000)
11012 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11013 else
11014 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11015 bitfield_byte_length = (unsigned) (p - label_str);
11016
11017 /* Fill in the textual info using stored (shifted) value */
11018 if (hfinfo->display == BASE_CUSTOM) {
11019 char tmp[ITEM_LABEL_LENGTH240];
11020 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11021
11022 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11022, "fmtfunc64"
))))
;
11023 fmtfunc64(tmp, value);
11024 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
11025 }
11026 else if (hfinfo->strings) {
11027 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11028
11029 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11030 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11031 /*
11032 * Unique values only display value_string string
11033 * if there is a match. Otherwise it's just a number
11034 */
11035 if (val_str) {
11036 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11037 } else {
11038 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11039 }
11040 } else {
11041 if (val_str == NULL((void*)0))
11042 val_str = "Unknown";
11043
11044 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11045 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
11046 else
11047 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11048 }
11049 }
11050 else {
11051 out = hfinfo_number_value_format64(hfinfo, buf, value);
11052
11053 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11054 }
11055}
11056
11057static void
11058fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
11059{
11060 const header_field_info *hfinfo = fi->hfinfo;
11061 uint32_t value;
11062
11063 char buf[32];
11064 const char *out;
11065
11066 value = fvalue_get_uinteger(fi->value);
11067
11068 /* Fill in the textual info */
11069 if (hfinfo->display == BASE_CUSTOM) {
11070 char tmp[ITEM_LABEL_LENGTH240];
11071 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11072
11073 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11073, "fmtfunc"))))
;
11074 fmtfunc(tmp, value);
11075 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11076 }
11077 else if (hfinfo->strings) {
11078 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
11079
11080 out = hfinfo_char_vals_format(hfinfo, buf, value);
11081 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11082 }
11083 else {
11084 out = hfinfo_char_value_format(hfinfo, buf, value);
11085
11086 label_fill(label_str, 0, hfinfo, out, value_pos);
11087 }
11088}
11089
11090static void
11091fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11092{
11093 const header_field_info *hfinfo = fi->hfinfo;
11094 uint32_t value;
11095
11096 char buf[NUMBER_LABEL_LENGTH80];
11097 const char *out;
11098
11099 if (is_signed)
11100 value = fvalue_get_sinteger(fi->value);
11101 else
11102 value = fvalue_get_uinteger(fi->value);
11103
11104 /* Fill in the textual info */
11105 if (hfinfo->display == BASE_CUSTOM) {
11106 char tmp[ITEM_LABEL_LENGTH240];
11107 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11108
11109 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11109, "fmtfunc"))))
;
11110 fmtfunc(tmp, value);
11111 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11112 }
11113 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
11114 /*
11115 * It makes no sense to have a value-string table for a
11116 * frame-number field - they're just integers giving
11117 * the ordinal frame number.
11118 */
11119 const char *val_str = hf_try_val_to_str(value, hfinfo);
11120
11121 out = hfinfo_number_vals_format(hfinfo, buf, value);
11122 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11123 /*
11124 * Unique values only display value_string string
11125 * if there is a match. Otherwise it's just a number
11126 */
11127 if (val_str) {
11128 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11129 } else {
11130 label_fill(label_str, 0, hfinfo, out, value_pos);
11131 }
11132 } else {
11133 if (val_str == NULL((void*)0))
11134 val_str = "Unknown";
11135
11136 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11137 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11138 else
11139 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11140 }
11141 }
11142 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
))
) {
11143 char tmp[ITEM_LABEL_LENGTH240];
11144
11145 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11146 display_to_port_type((field_display_e)hfinfo->display), value);
11147 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11148 }
11149 else {
11150 out = hfinfo_number_value_format(hfinfo, buf, value);
11151
11152 label_fill(label_str, 0, hfinfo, out, value_pos);
11153 }
11154}
11155
11156static void
11157fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11158{
11159 const header_field_info *hfinfo = fi->hfinfo;
11160 uint64_t value;
11161
11162 char buf[NUMBER_LABEL_LENGTH80];
11163 const char *out;
11164
11165 if (is_signed)
11166 value = fvalue_get_sinteger64(fi->value);
11167 else
11168 value = fvalue_get_uinteger64(fi->value);
11169
11170 /* Fill in the textual info */
11171 if (hfinfo->display == BASE_CUSTOM) {
11172 char tmp[ITEM_LABEL_LENGTH240];
11173 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11174
11175 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11175, "fmtfunc64"
))))
;
11176 fmtfunc64(tmp, value);
11177 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11178 }
11179 else if (hfinfo->strings) {
11180 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11181
11182 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11183 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11184 /*
11185 * Unique values only display value_string string
11186 * if there is a match. Otherwise it's just a number
11187 */
11188 if (val_str) {
11189 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11190 } else {
11191 label_fill(label_str, 0, hfinfo, out, value_pos);
11192 }
11193 } else {
11194 if (val_str == NULL((void*)0))
11195 val_str = "Unknown";
11196
11197 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11198 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11199 else
11200 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11201 }
11202 }
11203 else {
11204 out = hfinfo_number_value_format64(hfinfo, buf, value);
11205
11206 label_fill(label_str, 0, hfinfo, out, value_pos);
11207 }
11208}
11209
11210static size_t
11211fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11212{
11213 int display;
11214 int n;
11215 double value;
11216
11217 if (label_str_size < 12) {
11218 /* Not enough room to write an entire floating point value. */
11219 return 0;
11220 }
11221
11222 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11223 value = fvalue_get_floating(fi->value);
11224
11225 if (display == BASE_CUSTOM) {
11226 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11227 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11227, "fmtfunc"))))
;
11228 fmtfunc(label_str, value);
11229 return strlen(label_str);
11230 }
11231
11232 switch (display) {
11233 case BASE_NONE:
11234 if (fi->hfinfo->type == FT_FLOAT) {
11235 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11236 } else {
11237 n = (int)strlen(dtoa_g_fmt(label_str, value));
11238 }
11239 break;
11240 case BASE_DEC:
11241 n = snprintf(label_str, label_str_size, "%f", value);
11242 break;
11243 case BASE_HEX:
11244 n = snprintf(label_str, label_str_size, "%a", value);
11245 break;
11246 case BASE_EXP:
11247 n = snprintf(label_str, label_str_size, "%e", value);
11248 break;
11249 default:
11250 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11250
, __func__, "assertion \"not reached\" failed")
;
11251 }
11252 if (n < 0) {
11253 return 0; /* error */
11254 }
11255 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11256 const char *hf_str_val;
11257 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11258 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11259 }
11260 if (n > label_str_size) {
11261 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11261, __func__, "label length too small"); } } while (0)
;
11262 return strlen(label_str);
11263 }
11264
11265 return n;
11266}
11267
11268void
11269fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11270{
11271 char tmp[ITEM_LABEL_LENGTH240];
11272
11273 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11274 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11275}
11276
11277static size_t
11278fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11279{
11280 int display;
11281 size_t pos = 0;
11282 double value;
11283 char* tmp_str;
11284
11285 if (label_str_size < 12) {
11286 /* Not enough room to write an entire floating point value. */
11287 return 0;
11288 }
11289
11290 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11291 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11292 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11293 wmem_free(NULL((void*)0), tmp_str);
11294
11295 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11296 const char *hf_str_val;
11297 fvalue_to_double(fi->value, &value);
11298 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11299 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)
;
11300 }
11301 if ((int)pos > label_str_size) {
11302 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11302, __func__, "label length too small"); } } while (0)
;
11303 return strlen(label_str);
11304 }
11305
11306 return pos;
11307}
11308
11309void
11310fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11311{
11312 char tmp[ITEM_LABEL_LENGTH240];
11313
11314 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11315 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11316}
11317
11318int
11319hfinfo_bitshift(const header_field_info *hfinfo)
11320{
11321 return ws_ctz(hfinfo->bitmask);
11322}
11323
11324
11325static int
11326hfinfo_bitoffset(const header_field_info *hfinfo)
11327{
11328 if (!hfinfo->bitmask) {
11329 return 0;
11330 }
11331
11332 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11333 * as the first bit */
11334 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11335}
11336
11337static int
11338hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11339{
11340 if (!hfinfo->bitmask) {
11341 return 0;
11342 }
11343
11344 /* ilog2 = first set bit, ctz = last set bit */
11345 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11346}
11347
11348static int
11349hfinfo_type_bitwidth(enum ftenum type)
11350{
11351 int bitwidth = 0;
11352
11353 switch (type) {
11354 case FT_CHAR:
11355 case FT_UINT8:
11356 case FT_INT8:
11357 bitwidth = 8;
11358 break;
11359 case FT_UINT16:
11360 case FT_INT16:
11361 bitwidth = 16;
11362 break;
11363 case FT_UINT24:
11364 case FT_INT24:
11365 bitwidth = 24;
11366 break;
11367 case FT_UINT32:
11368 case FT_INT32:
11369 bitwidth = 32;
11370 break;
11371 case FT_UINT40:
11372 case FT_INT40:
11373 bitwidth = 40;
11374 break;
11375 case FT_UINT48:
11376 case FT_INT48:
11377 bitwidth = 48;
11378 break;
11379 case FT_UINT56:
11380 case FT_INT56:
11381 bitwidth = 56;
11382 break;
11383 case FT_UINT64:
11384 case FT_INT64:
11385 bitwidth = 64;
11386 break;
11387 default:
11388 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11388))
;
11389 ;
11390 }
11391 return bitwidth;
11392}
11393
11394
11395static int
11396hfinfo_container_bitwidth(const header_field_info *hfinfo)
11397{
11398 if (!hfinfo->bitmask) {
11399 return 0;
11400 }
11401
11402 if (hfinfo->type == FT_BOOLEAN) {
11403 return hfinfo->display; /* hacky? :) */
11404 }
11405
11406 return hfinfo_type_bitwidth(hfinfo->type);
11407}
11408
11409static int
11410hfinfo_hex_digits(const header_field_info *hfinfo)
11411{
11412 int bitwidth;
11413
11414 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11415 * appropriate to determine the number of hex digits for the field.
11416 * So instead, we compute it from the bitmask.
11417 */
11418 if (hfinfo->bitmask != 0) {
11419 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11420 } else {
11421 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11422 }
11423
11424 /* Divide by 4, rounding up, to get number of hex digits. */
11425 return (bitwidth + 3) / 4;
11426}
11427
11428const char *
11429hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11430{
11431 char *ptr = &buf[6];
11432 static const char hex_digits[16] =
11433 { '0', '1', '2', '3', '4', '5', '6', '7',
11434 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11435
11436 *ptr = '\0';
11437 *(--ptr) = '\'';
11438 /* Properly format value */
11439 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11440 /*
11441 * Printable, so just show the character, and, if it needs
11442 * to be escaped, escape it.
11443 */
11444 *(--ptr) = value;
11445 if (value == '\\' || value == '\'')
11446 *(--ptr) = '\\';
11447 } else {
11448 /*
11449 * Non-printable; show it as an escape sequence.
11450 */
11451 switch (value) {
11452
11453 case '\0':
11454 /*
11455 * Show a NUL with only one digit.
11456 */
11457 *(--ptr) = '0';
11458 break;
11459
11460 case '\a':
11461 case '\b':
11462 case '\f':
11463 case '\n':
11464 case '\r':
11465 case '\t':
11466 case '\v':
11467 *(--ptr) = value - '\a' + 'a';
11468 break;
11469
11470 default:
11471 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11472
11473 case BASE_OCT:
11474 *(--ptr) = (value & 0x7) + '0';
11475 value >>= 3;
11476 *(--ptr) = (value & 0x7) + '0';
11477 value >>= 3;
11478 *(--ptr) = (value & 0x7) + '0';
11479 break;
11480
11481 case BASE_HEX:
11482 *(--ptr) = hex_digits[value & 0x0F];
11483 value >>= 4;
11484 *(--ptr) = hex_digits[value & 0x0F];
11485 *(--ptr) = 'x';
11486 break;
11487
11488 default:
11489 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11490 }
11491 }
11492 *(--ptr) = '\\';
11493 }
11494 *(--ptr) = '\'';
11495 return ptr;
11496}
11497
11498static const char *
11499hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11500{
11501 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11502 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
))
;
11503
11504 *ptr = '\0';
11505 /* Properly format value */
11506 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11507 case BASE_DEC:
11508 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11509
11510 case BASE_DEC_HEX:
11511 *(--ptr) = ')';
11512 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11513 *(--ptr) = '(';
11514 *(--ptr) = ' ';
11515 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11516 return ptr;
11517
11518 case BASE_OCT:
11519 return oct_to_str_back(ptr, value);
11520
11521 case BASE_HEX:
11522 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11523
11524 case BASE_HEX_DEC:
11525 *(--ptr) = ')';
11526 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11527 *(--ptr) = '(';
11528 *(--ptr) = ' ';
11529 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11530 return ptr;
11531
11532 case BASE_PT_UDP:
11533 case BASE_PT_TCP:
11534 case BASE_PT_DCCP:
11535 case BASE_PT_SCTP:
11536 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11537 display_to_port_type((field_display_e)display), value);
11538 return buf;
11539 case BASE_OUI:
11540 {
11541 uint8_t p_oui[3];
11542 const char *manuf_name;
11543
11544 p_oui[0] = value >> 16 & 0xFF;
11545 p_oui[1] = value >> 8 & 0xFF;
11546 p_oui[2] = value & 0xFF;
11547
11548 /* Attempt an OUI lookup. */
11549 manuf_name = uint_get_manuf_name_if_known(value);
11550 if (manuf_name == NULL((void*)0)) {
11551 /* Could not find an OUI. */
11552 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11553 }
11554 else {
11555 /* Found an address string. */
11556 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11557 }
11558 return buf;
11559 }
11560
11561 default:
11562 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11563 }
11564 return ptr;
11565}
11566
11567static const char *
11568hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11569{
11570 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11571 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
))
;
11572
11573 *ptr = '\0';
11574 /* Properly format value */
11575 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11576 case BASE_DEC:
11577 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11578
11579 case BASE_DEC_HEX:
11580 *(--ptr) = ')';
11581 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11582 *(--ptr) = '(';
11583 *(--ptr) = ' ';
11584 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11585 return ptr;
11586
11587 case BASE_OCT:
11588 return oct64_to_str_back(ptr, value);
11589
11590 case BASE_HEX:
11591 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11592
11593 case BASE_HEX_DEC:
11594 *(--ptr) = ')';
11595 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11596 *(--ptr) = '(';
11597 *(--ptr) = ' ';
11598 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11599 return ptr;
11600
11601 default:
11602 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11603 }
11604
11605 return ptr;
11606}
11607
11608static const char *
11609hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11610{
11611 int display = hfinfo->display;
11612
11613 if (hfinfo->type == FT_FRAMENUM) {
11614 /*
11615 * Frame numbers are always displayed in decimal.
11616 */
11617 display = BASE_DEC;
11618 }
11619
11620 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11621}
11622
11623static const char *
11624hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11625{
11626 int display = hfinfo->display;
11627
11628 if (hfinfo->type == FT_FRAMENUM) {
11629 /*
11630 * Frame numbers are always displayed in decimal.
11631 */
11632 display = BASE_DEC;
11633 }
11634
11635 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11636}
11637
11638static const char *
11639hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11640{
11641 /* Get the underlying BASE_ value */
11642 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11643
11644 return hfinfo_char_value_format_display(display, buf, value);
11645}
11646
11647static const char *
11648hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11649{
11650 /* Get the underlying BASE_ value */
11651 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11652
11653 if (hfinfo->type == FT_FRAMENUM) {
11654 /*
11655 * Frame numbers are always displayed in decimal.
11656 */
11657 display = BASE_DEC;
11658 }
11659
11660 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11661 display = BASE_DEC;
11662 } else if (display == BASE_OUI) {
11663 display = BASE_HEX;
11664 }
11665
11666 switch (display) {
11667 case BASE_NONE:
11668 /* case BASE_DEC: */
11669 case BASE_DEC_HEX:
11670 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11671 case BASE_CUSTOM:
11672 display = BASE_DEC;
11673 break;
11674
11675 /* case BASE_HEX: */
11676 case BASE_HEX_DEC:
11677 display = BASE_HEX;
11678 break;
11679 }
11680
11681 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11682}
11683
11684static const char *
11685hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11686{
11687 /* Get the underlying BASE_ value */
11688 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11689
11690 if (hfinfo->type == FT_FRAMENUM) {
11691 /*
11692 * Frame numbers are always displayed in decimal.
11693 */
11694 display = BASE_DEC;
11695 }
11696
11697 switch (display) {
11698 case BASE_NONE:
11699 /* case BASE_DEC: */
11700 case BASE_DEC_HEX:
11701 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11702 case BASE_CUSTOM:
11703 display = BASE_DEC;
11704 break;
11705
11706 /* case BASE_HEX: */
11707 case BASE_HEX_DEC:
11708 display = BASE_HEX;
11709 break;
11710 }
11711
11712 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11713}
11714
11715static const char *
11716hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11717{
11718 /* Get the underlying BASE_ value */
11719 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11720
11721 return hfinfo_char_value_format_display(display, buf, value);
11722}
11723
11724static const char *
11725hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11726{
11727 /* Get the underlying BASE_ value */
11728 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11729
11730 if (display == BASE_NONE)
11731 return NULL((void*)0);
11732
11733 if (display == BASE_DEC_HEX)
11734 display = BASE_DEC;
11735 if (display == BASE_HEX_DEC)
11736 display = BASE_HEX;
11737
11738 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11739}
11740
11741static const char *
11742hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11743{
11744 /* Get the underlying BASE_ value */
11745 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11746
11747 if (display == BASE_NONE)
11748 return NULL((void*)0);
11749
11750 if (display == BASE_DEC_HEX)
11751 display = BASE_DEC;
11752 if (display == BASE_HEX_DEC)
11753 display = BASE_HEX;
11754
11755 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11756}
11757
11758const char *
11759proto_registrar_get_name(const int n)
11760{
11761 header_field_info *hfinfo;
11762
11763 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", 11763
, __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", 11763
, "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", 11763, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11764 return hfinfo->name;
11765}
11766
11767const char *
11768proto_registrar_get_abbrev(const int n)
11769{
11770 header_field_info *hfinfo;
11771
11772 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", 11772
, __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", 11772
, "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", 11772, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11773 return hfinfo->abbrev;
11774}
11775
11776enum ftenum
11777proto_registrar_get_ftype(const int n)
11778{
11779 header_field_info *hfinfo;
11780
11781 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", 11781
, __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", 11781
, "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", 11781, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11782 return hfinfo->type;
11783}
11784
11785int
11786proto_registrar_get_parent(const int n)
11787{
11788 header_field_info *hfinfo;
11789
11790 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", 11790
, __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", 11790
, "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", 11790, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11791 return hfinfo->parent;
11792}
11793
11794bool_Bool
11795proto_registrar_is_protocol(const int n)
11796{
11797 header_field_info *hfinfo;
11798
11799 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", 11799
, __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", 11799
, "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", 11799, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11800 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11801}
11802
11803/* Returns length of field in packet (not necessarily the length
11804 * in our internal representation, as in the case of IPv4).
11805 * 0 means undeterminable at time of registration
11806 * -1 means the field is not registered. */
11807int
11808proto_registrar_get_length(const int n)
11809{
11810 header_field_info *hfinfo;
11811
11812 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", 11812
, __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", 11812
, "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", 11812, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11813 return ftype_wire_size(hfinfo->type);
11814}
11815
11816size_t
11817proto_registrar_get_count(struct proto_registrar_stats *stats)
11818{
11819 header_field_info *hfinfo;
11820
11821 // Index zero is not used. We have to skip it.
11822 size_t total_count = gpa_hfinfo.len - 1;
11823 if (stats == NULL((void*)0)) {
11824 return total_count;
11825 }
11826 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11827 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11828 stats->deregistered_count++;
11829 continue; /* This is a deregistered protocol or header field */
11830 }
11831
11832 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", 11832
, __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", 11832, "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", 11832, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11833
11834 if (proto_registrar_is_protocol(id))
11835 stats->protocol_count++;
11836
11837 if (hfinfo->same_name_prev_id != -1)
11838 stats->same_name_count++;
11839 }
11840
11841 return total_count;
11842}
11843
11844/* Looks for a protocol or a field in a proto_tree. Returns true if
11845 * it exists anywhere, or false if it exists nowhere. */
11846bool_Bool
11847proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11848{
11849 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11850
11851 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11852 return true1;
11853 }
11854 else {
11855 return false0;
11856 }
11857}
11858
11859/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11860 * This only works if the hfindex was "primed" before the dissection
11861 * took place, as we just pass back the already-created GPtrArray*.
11862 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11863 * handles that. */
11864GPtrArray *
11865proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11866{
11867 if (!tree)
11868 return NULL((void*)0);
11869
11870 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11871 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11872 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11873 else
11874 return NULL((void*)0);
11875}
11876
11877bool_Bool
11878proto_tracking_interesting_fields(const proto_tree *tree)
11879{
11880 GHashTable *interesting_hfids;
11881
11882 if (!tree)
11883 return false0;
11884
11885 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11886
11887 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11888}
11889
11890/* Helper struct for proto_find_info() and proto_all_finfos() */
11891typedef struct {
11892 GPtrArray *array;
11893 int id;
11894} ffdata_t;
11895
11896/* Helper function for proto_find_info() */
11897static bool_Bool
11898find_finfo(proto_node *node, void * data)
11899{
11900 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11901 if (fi && fi->hfinfo) {
11902 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11903 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11904 }
11905 }
11906
11907 /* Don't stop traversing. */
11908 return false0;
11909}
11910
11911/* Helper function for proto_find_first_info() */
11912static bool_Bool
11913find_first_finfo(proto_node *node, void *data)
11914{
11915 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11916 if (fi && fi->hfinfo) {
11917 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11918 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11919
11920 /* Stop traversing. */
11921 return true1;
11922 }
11923 }
11924
11925 /* Continue traversing. */
11926 return false0;
11927}
11928
11929/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11930* This works on any proto_tree, primed or unprimed, but actually searches
11931* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11932* The caller does need to free the returned GPtrArray with
11933* g_ptr_array_free(<array>, true).
11934*/
11935GPtrArray *
11936proto_find_finfo(proto_tree *tree, const int id)
11937{
11938 ffdata_t ffdata;
11939
11940 ffdata.array = g_ptr_array_new();
11941 ffdata.id = id;
11942
11943 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11944
11945 return ffdata.array;
11946}
11947
11948/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11949* This works on any proto_tree, primed or unprimed, but actually searches
11950* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11951* The caller does need to free the returned GPtrArray with
11952* g_ptr_array_free(<array>, true).
11953*/
11954GPtrArray *
11955proto_find_first_finfo(proto_tree *tree, const int id)
11956{
11957 ffdata_t ffdata;
11958
11959 ffdata.array = g_ptr_array_new();
11960 ffdata.id = id;
11961
11962 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11963
11964 return ffdata.array;
11965}
11966
11967/* Helper function for proto_all_finfos() */
11968static bool_Bool
11969every_finfo(proto_node *node, void * data)
11970{
11971 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11972 if (fi && fi->hfinfo) {
11973 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11974 }
11975
11976 /* Don't stop traversing. */
11977 return false0;
11978}
11979
11980/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11981 * The caller does need to free the returned GPtrArray with
11982 * g_ptr_array_free(<array>, true).
11983 */
11984GPtrArray *
11985proto_all_finfos(proto_tree *tree)
11986{
11987 ffdata_t ffdata;
11988
11989 /* Pre allocate enough space to hold all fields in most cases */
11990 ffdata.array = g_ptr_array_sized_new(512);
11991 ffdata.id = 0;
11992
11993 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11994
11995 return ffdata.array;
11996}
11997
11998
11999typedef struct {
12000 unsigned offset;
12001 field_info *finfo;
12002 tvbuff_t *tvb;
12003} offset_search_t;
12004
12005static bool_Bool
12006check_for_offset(proto_node *node, void * data)
12007{
12008 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12009 offset_search_t *offsearch = (offset_search_t *)data;
12010
12011 /* !fi == the top most container node which holds nothing */
12012 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
12013 if (offsearch->offset >= (unsigned) fi->start &&
12014 offsearch->offset < (unsigned) (fi->start + fi->length)) {
12015
12016 offsearch->finfo = fi;
12017 return false0; /* keep traversing */
12018 }
12019 }
12020 return false0; /* keep traversing */
12021}
12022
12023/* Search a proto_tree backwards (from leaves to root) looking for the field
12024 * whose start/length occupies 'offset' */
12025/* XXX - I couldn't find an easy way to search backwards, so I search
12026 * forwards, w/o stopping. Therefore, the last finfo I find will the be
12027 * the one I want to return to the user. This algorithm is inefficient
12028 * and could be re-done, but I'd have to handle all the children and
12029 * siblings of each node myself. When I have more time I'll do that.
12030 * (yeah right) */
12031field_info *
12032proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
12033{
12034 offset_search_t offsearch;
12035
12036 offsearch.offset = offset;
12037 offsearch.finfo = NULL((void*)0);
12038 offsearch.tvb = tvb;
12039
12040 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
12041
12042 return offsearch.finfo;
12043}
12044
12045typedef struct {
12046 unsigned length;
12047 char *buf;
12048} decoded_data_t;
12049
12050static bool_Bool
12051check_for_undecoded(proto_node *node, void * data)
12052{
12053 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12054 decoded_data_t* decoded = (decoded_data_t*)data;
12055 unsigned i;
12056 unsigned byte;
12057 unsigned bit;
12058
12059 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
12060 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
12061 byte = i / 8;
12062 bit = i % 8;
12063 decoded->buf[byte] |= (1 << bit);
12064 }
12065 }
12066
12067 return false0;
12068}
12069
12070char*
12071proto_find_undecoded_data(proto_tree *tree, unsigned length)
12072{
12073 decoded_data_t decoded;
12074 decoded.length = length;
12075 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
12076
12077 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
12078 return decoded.buf;
12079}
12080
12081/* Dumps the protocols in the registration database to stdout. An independent
12082 * program can take this output and format it into nice tables or HTML or
12083 * whatever.
12084 *
12085 * There is one record per line. The fields are tab-delimited.
12086 *
12087 * Field 1 = protocol name
12088 * Field 2 = protocol short name
12089 * Field 3 = protocol filter name
12090 * Field 4 = protocol enabled
12091 * Field 5 = protocol enabled by default
12092 * Field 6 = protocol can toggle
12093 */
12094void
12095proto_registrar_dump_protocols(void)
12096{
12097 protocol_t *protocol;
12098 int i;
12099 void *cookie = NULL((void*)0);
12100
12101
12102 i = proto_get_first_protocol(&cookie);
12103 while (i != -1) {
12104 protocol = find_protocol_by_id(i);
12105 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
12106 protocol->name,
12107 protocol->short_name,
12108 protocol->filter_name,
12109 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
12110 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
12111 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
12112 i = proto_get_next_protocol(&cookie);
12113 }
12114}
12115
12116/* Dumps the value_strings, extended value string headers, range_strings
12117 * or true/false strings for fields that have them.
12118 * There is one record per line. Fields are tab-delimited.
12119 * There are four types of records: Value String, Extended Value String Header,
12120 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
12121 * the type of record.
12122 *
12123 * Note that a record will be generated only if the value_string,... is referenced
12124 * in a registered hfinfo entry.
12125 *
12126 *
12127 * Value Strings
12128 * -------------
12129 * Field 1 = 'V'
12130 * Field 2 = Field abbreviation to which this value string corresponds
12131 * Field 3 = Integer value
12132 * Field 4 = String
12133 *
12134 * Extended Value String Headers
12135 * -----------------------------
12136 * Field 1 = 'E'
12137 * Field 2 = Field abbreviation to which this extended value string header corresponds
12138 * Field 3 = Extended Value String "Name"
12139 * Field 4 = Number of entries in the associated value_string array
12140 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12141 *
12142 * Range Strings
12143 * -------------
12144 * Field 1 = 'R'
12145 * Field 2 = Field abbreviation to which this range string corresponds
12146 * Field 3 = Integer value: lower bound
12147 * Field 4 = Integer value: upper bound
12148 * Field 5 = String
12149 *
12150 * True/False Strings
12151 * ------------------
12152 * Field 1 = 'T'
12153 * Field 2 = Field abbreviation to which this true/false string corresponds
12154 * Field 3 = True String
12155 * Field 4 = False String
12156 */
12157void
12158proto_registrar_dump_values(void)
12159{
12160 header_field_info *hfinfo;
12161 int i, len, vi;
12162 const value_string *vals;
12163 const val64_string *vals64;
12164 const range_string *range;
12165 const true_false_string *tfs;
12166 const unit_name_string *units;
12167
12168 len = gpa_hfinfo.len;
12169 for (i = 1; i < len ; i++) {
12170 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12171 continue; /* This is a deregistered protocol or field */
12172
12173 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", 12173
, __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", 12173
, "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", 12173, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12174
12175 if (hfinfo->id == hf_text_only) {
12176 continue;
12177 }
12178
12179 /* ignore protocols */
12180 if (proto_registrar_is_protocol(i)) {
12181 continue;
12182 }
12183 /* process header fields */
12184#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12185 /*
12186 * If this field isn't at the head of the list of
12187 * fields with this name, skip this field - all
12188 * fields with the same name are really just versions
12189 * of the same field stored in different bits, and
12190 * should have the same type/radix/value list, and
12191 * just differ in their bit masks. (If a field isn't
12192 * a bitfield, but can be, say, 1 or 2 bytes long,
12193 * it can just be made FT_UINT16, meaning the
12194 * *maximum* length is 2 bytes, and be used
12195 * for all lengths.)
12196 */
12197 if (hfinfo->same_name_prev_id != -1)
12198 continue;
12199#endif
12200 vals = NULL((void*)0);
12201 vals64 = NULL((void*)0);
12202 range = NULL((void*)0);
12203 tfs = NULL((void*)0);
12204 units = NULL((void*)0);
12205
12206 if (hfinfo->strings != NULL((void*)0)) {
12207 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12208 (hfinfo->type == FT_CHAR ||
12209 hfinfo->type == FT_UINT8 ||
12210 hfinfo->type == FT_UINT16 ||
12211 hfinfo->type == FT_UINT24 ||
12212 hfinfo->type == FT_UINT32 ||
12213 hfinfo->type == FT_UINT40 ||
12214 hfinfo->type == FT_UINT48 ||
12215 hfinfo->type == FT_UINT56 ||
12216 hfinfo->type == FT_UINT64 ||
12217 hfinfo->type == FT_INT8 ||
12218 hfinfo->type == FT_INT16 ||
12219 hfinfo->type == FT_INT24 ||
12220 hfinfo->type == FT_INT32 ||
12221 hfinfo->type == FT_INT40 ||
12222 hfinfo->type == FT_INT48 ||
12223 hfinfo->type == FT_INT56 ||
12224 hfinfo->type == FT_INT64 ||
12225 hfinfo->type == FT_FLOAT ||
12226 hfinfo->type == FT_DOUBLE)) {
12227
12228 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12229 range = (const range_string *)hfinfo->strings;
12230 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12231 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12232 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12233 } else {
12234 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12235 }
12236 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12237 vals64 = (const val64_string *)hfinfo->strings;
12238 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12239 units = (const unit_name_string *)hfinfo->strings;
12240 } else {
12241 vals = (const value_string *)hfinfo->strings;
12242 }
12243 }
12244 else if (hfinfo->type == FT_BOOLEAN) {
12245 tfs = (const struct true_false_string *)hfinfo->strings;
12246 }
12247 }
12248
12249 /* Print value strings? */
12250 if (vals) {
12251 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12252 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12253 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12254 if (!val64_string_ext_validate(vse_p)) {
12255 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12255, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12256 continue;
12257 }
12258 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12259 printf("E\t%s\t%u\t%s\t%s\n",
12260 hfinfo->abbrev,
12261 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12262 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12263 val64_string_ext_match_type_str(vse_p));
12264 } else {
12265 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12266 if (!value_string_ext_validate(vse_p)) {
12267 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12267, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12268 continue;
12269 }
12270 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12271 printf("E\t%s\t%u\t%s\t%s\n",
12272 hfinfo->abbrev,
12273 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12274 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12275 value_string_ext_match_type_str(vse_p));
12276 }
12277 }
12278 vi = 0;
12279 while (vals[vi].strptr) {
12280 /* Print in the proper base */
12281 if (hfinfo->type == FT_CHAR) {
12282 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12283 printf("V\t%s\t'%c'\t%s\n",
12284 hfinfo->abbrev,
12285 vals[vi].value,
12286 vals[vi].strptr);
12287 } else {
12288 if (hfinfo->display == BASE_HEX) {
12289 printf("V\t%s\t'\\x%02x'\t%s\n",
12290 hfinfo->abbrev,
12291 vals[vi].value,
12292 vals[vi].strptr);
12293 }
12294 else {
12295 printf("V\t%s\t'\\%03o'\t%s\n",
12296 hfinfo->abbrev,
12297 vals[vi].value,
12298 vals[vi].strptr);
12299 }
12300 }
12301 } else {
12302 if (hfinfo->display == BASE_HEX) {
12303 printf("V\t%s\t0x%x\t%s\n",
12304 hfinfo->abbrev,
12305 vals[vi].value,
12306 vals[vi].strptr);
12307 }
12308 else {
12309 printf("V\t%s\t%u\t%s\n",
12310 hfinfo->abbrev,
12311 vals[vi].value,
12312 vals[vi].strptr);
12313 }
12314 }
12315 vi++;
12316 }
12317 }
12318 else if (vals64) {
12319 vi = 0;
12320 while (vals64[vi].strptr) {
12321 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12322 hfinfo->abbrev,
12323 vals64[vi].value,
12324 vals64[vi].strptr);
12325 vi++;
12326 }
12327 }
12328
12329 /* print range strings? */
12330 else if (range) {
12331 vi = 0;
12332 while (range[vi].strptr) {
12333 /* Print in the proper base */
12334 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12335 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12336 hfinfo->abbrev,
12337 range[vi].value_min,
12338 range[vi].value_max,
12339 range[vi].strptr);
12340 }
12341 else {
12342 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12343 hfinfo->abbrev,
12344 range[vi].value_min,
12345 range[vi].value_max,
12346 range[vi].strptr);
12347 }
12348 vi++;
12349 }
12350 }
12351
12352 /* Print true/false strings? */
12353 else if (tfs) {
12354 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12355 tfs->true_string, tfs->false_string);
12356 }
12357 /* Print unit strings? */
12358 else if (units) {
12359 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12360 units->singular, units->plural ? units->plural : "(no plural)");
12361 }
12362 }
12363}
12364
12365/* Prints the number of registered fields.
12366 * Useful for determining an appropriate value for
12367 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12368 *
12369 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12370 * the number of fields, true otherwise.
12371 */
12372bool_Bool
12373proto_registrar_dump_fieldcount(void)
12374{
12375 struct proto_registrar_stats stats = {0, 0, 0};
12376 size_t total_count = proto_registrar_get_count(&stats);
12377
12378 printf("There are %zu header fields registered, of which:\n"
12379 "\t%zu are deregistered\n"
12380 "\t%zu are protocols\n"
12381 "\t%zu have the same name as another field\n\n",
12382 total_count, stats.deregistered_count, stats.protocol_count,
12383 stats.same_name_count);
12384
12385 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12386 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12387 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12388 "\n");
12389
12390 printf("The header field table consumes %u KiB of memory.\n",
12391 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12392 printf("The fields themselves consume %u KiB of memory.\n",
12393 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12394
12395 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12396}
12397
12398static void
12399elastic_add_base_mapping(json_dumper *dumper)
12400{
12401 json_dumper_set_member_name(dumper, "index_patterns");
12402 json_dumper_begin_array(dumper);
12403 // The index names from write_json_index() in print.c
12404 json_dumper_value_string(dumper, "packets-*");
12405 json_dumper_end_array(dumper);
12406
12407 json_dumper_set_member_name(dumper, "settings");
12408 json_dumper_begin_object(dumper);
12409 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12410 json_dumper_value_anyf(dumper, "%d", 1000000);
12411 json_dumper_end_object(dumper);
12412}
12413
12414static char*
12415ws_type_to_elastic(unsigned type)
12416{
12417 switch(type) {
12418 case FT_INT8:
12419 return "byte";
12420 case FT_UINT8:
12421 case FT_INT16:
12422 return "short";
12423 case FT_UINT16:
12424 case FT_INT32:
12425 case FT_UINT24:
12426 case FT_INT24:
12427 return "integer";
12428 case FT_FRAMENUM:
12429 case FT_UINT32:
12430 case FT_UINT40:
12431 case FT_UINT48:
12432 case FT_UINT56:
12433 case FT_INT40:
12434 case FT_INT48:
12435 case FT_INT56:
12436 case FT_INT64:
12437 return "long";
12438 case FT_UINT64:
12439 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12440 case FT_FLOAT:
12441 return "float";
12442 case FT_DOUBLE:
12443 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12444 return "double";
12445 case FT_IPv6:
12446 case FT_IPv4:
12447 return "ip";
12448 case FT_ABSOLUTE_TIME:
12449 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12450 case FT_BOOLEAN:
12451 return "boolean";
12452 default:
12453 return NULL((void*)0);
12454 }
12455}
12456
12457static char*
12458dot_to_underscore(char* str)
12459{
12460 unsigned i;
12461 for (i = 0; i < strlen(str); i++) {
12462 if (str[i] == '.')
12463 str[i] = '_';
12464 }
12465 return str;
12466}
12467
12468/* Dumps a mapping file for ElasticSearch
12469 * This is the v1 (legacy) _template API.
12470 * At some point it may need to be updated with the composable templates
12471 * introduced in Elasticsearch 7.8 (_index_template)
12472 */
12473void
12474proto_registrar_dump_elastic(const char* filter)
12475{
12476 header_field_info *hfinfo;
12477 header_field_info *parent_hfinfo;
12478 unsigned i;
12479 bool_Bool open_object = true1;
12480 const char* prev_proto = NULL((void*)0);
12481 char* str;
12482 char** protos = NULL((void*)0);
12483 char* proto;
12484 bool_Bool found;
12485 unsigned j;
12486 char* type;
12487 char* prev_item = NULL((void*)0);
12488
12489 /* We have filtering protocols. Extract them. */
12490 if (filter) {
12491 protos = g_strsplit(filter, ",", -1);
12492 }
12493
12494 /*
12495 * To help tracking down the json tree, objects have been appended with a comment:
12496 * n.label -> where n is the indentation level and label the name of the object
12497 */
12498
12499 json_dumper dumper = {
12500 .output_file = stdoutstdout,
12501 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12502 };
12503 json_dumper_begin_object(&dumper); // 1.root
12504 elastic_add_base_mapping(&dumper);
12505
12506 json_dumper_set_member_name(&dumper, "mappings");
12507 json_dumper_begin_object(&dumper); // 2.mappings
12508
12509 json_dumper_set_member_name(&dumper, "properties");
12510 json_dumper_begin_object(&dumper); // 3.properties
12511 json_dumper_set_member_name(&dumper, "timestamp");
12512 json_dumper_begin_object(&dumper); // 4.timestamp
12513 json_dumper_set_member_name(&dumper, "type");
12514 json_dumper_value_string(&dumper, "date");
12515 json_dumper_end_object(&dumper); // 4.timestamp
12516
12517 json_dumper_set_member_name(&dumper, "layers");
12518 json_dumper_begin_object(&dumper); // 4.layers
12519 json_dumper_set_member_name(&dumper, "properties");
12520 json_dumper_begin_object(&dumper); // 5.properties
12521
12522 for (i = 1; i < gpa_hfinfo.len; i++) {
12523 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12524 continue; /* This is a deregistered protocol or header field */
12525
12526 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", 12526
, __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", 12526
, "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", 12526, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12527
12528 /*
12529 * Skip the pseudo-field for "proto_tree_add_text()" since
12530 * we don't want it in the list of filterable protocols.
12531 */
12532 if (hfinfo->id == hf_text_only)
12533 continue;
12534
12535 if (!proto_registrar_is_protocol(i)) {
12536 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", 12536
, __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", 12536
, "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", 12536
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12537
12538 /*
12539 * Skip the field if filter protocols have been set and this one's
12540 * parent is not listed.
12541 */
12542 if (protos) {
12543 found = false0;
12544 j = 0;
12545 proto = protos[0];
12546 while(proto) {
12547 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12548 found = true1;
12549 break;
12550 }
12551 j++;
12552 proto = protos[j];
12553 }
12554 if (!found)
12555 continue;
12556 }
12557
12558 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12559 json_dumper_end_object(&dumper); // 7.properties
12560 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12561 open_object = true1;
12562 }
12563
12564 prev_proto = parent_hfinfo->abbrev;
12565
12566 if (open_object) {
12567 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12568 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12569 json_dumper_set_member_name(&dumper, "properties");
12570 json_dumper_begin_object(&dumper); // 7.properties
12571 open_object = false0;
12572 }
12573 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12574 type = ws_type_to_elastic(hfinfo->type);
12575 /* when type is NULL, we have the default mapping: string */
12576 if (type) {
12577 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12578 dot_to_underscore(str);
12579 if (g_strcmp0(prev_item, str)) {
12580 json_dumper_set_member_name(&dumper, str);
12581 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12582 json_dumper_set_member_name(&dumper, "type");
12583 json_dumper_value_string(&dumper, type);
12584 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12585 }
12586 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)
;
12587 prev_item = str;
12588 }
12589 }
12590 }
12591 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)
;
12592
12593 if (prev_proto) {
12594 json_dumper_end_object(&dumper); // 7.properties
12595 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12596 }
12597
12598 json_dumper_end_object(&dumper); // 5.properties
12599 json_dumper_end_object(&dumper); // 4.layers
12600 json_dumper_end_object(&dumper); // 3.properties
12601 json_dumper_end_object(&dumper); // 2.mappings
12602 json_dumper_end_object(&dumper); // 1.root
12603 bool_Bool ret = json_dumper_finish(&dumper);
12604 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12604, "ret"))))
;
12605
12606 g_strfreev(protos);
12607}
12608
12609/* Dumps the contents of the registration database to stdout. An independent
12610 * program can take this output and format it into nice tables or HTML or
12611 * whatever.
12612 *
12613 * There is one record per line. Each record is either a protocol or a header
12614 * field, differentiated by the first field. The fields are tab-delimited.
12615 *
12616 * Protocols
12617 * ---------
12618 * Field 1 = 'P'
12619 * Field 2 = descriptive protocol name
12620 * Field 3 = protocol abbreviation
12621 *
12622 * Header Fields
12623 * -------------
12624 * Field 1 = 'F'
12625 * Field 2 = descriptive field name
12626 * Field 3 = field abbreviation
12627 * Field 4 = type ( textual representation of the ftenum type )
12628 * Field 5 = parent protocol abbreviation
12629 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12630 * Field 7 = bitmask: format: hex: 0x....
12631 * Field 8 = blurb describing field
12632 */
12633void
12634proto_registrar_dump_fields(void)
12635{
12636 header_field_info *hfinfo, *parent_hfinfo;
12637 int i, len;
12638 const char *enum_name;
12639 const char *base_name;
12640 const char *blurb;
12641 char width[5];
12642
12643 len = gpa_hfinfo.len;
12644 for (i = 1; i < len ; i++) {
12645 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12646 continue; /* This is a deregistered protocol or header field */
12647
12648 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", 12648
, __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", 12648
, "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", 12648, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12649
12650 /*
12651 * Skip the pseudo-field for "proto_tree_add_text()" since
12652 * we don't want it in the list of filterable fields.
12653 */
12654 if (hfinfo->id == hf_text_only)
12655 continue;
12656
12657 /* format for protocols */
12658 if (proto_registrar_is_protocol(i)) {
12659 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12660 }
12661 /* format for header fields */
12662 else {
12663 /*
12664 * If this field isn't at the head of the list of
12665 * fields with this name, skip this field - all
12666 * fields with the same name are really just versions
12667 * of the same field stored in different bits, and
12668 * should have the same type/radix/value list, and
12669 * just differ in their bit masks. (If a field isn't
12670 * a bitfield, but can be, say, 1 or 2 bytes long,
12671 * it can just be made FT_UINT16, meaning the
12672 * *maximum* length is 2 bytes, and be used
12673 * for all lengths.)
12674 */
12675 if (hfinfo->same_name_prev_id != -1)
12676 continue;
12677
12678 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", 12678
, __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", 12678
, "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", 12678
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12679
12680 enum_name = ftype_name(hfinfo->type);
12681 base_name = "";
12682
12683 if (hfinfo->type == FT_CHAR ||
12684 hfinfo->type == FT_UINT8 ||
12685 hfinfo->type == FT_UINT16 ||
12686 hfinfo->type == FT_UINT24 ||
12687 hfinfo->type == FT_UINT32 ||
12688 hfinfo->type == FT_UINT40 ||
12689 hfinfo->type == FT_UINT48 ||
12690 hfinfo->type == FT_UINT56 ||
12691 hfinfo->type == FT_UINT64 ||
12692 hfinfo->type == FT_INT8 ||
12693 hfinfo->type == FT_INT16 ||
12694 hfinfo->type == FT_INT24 ||
12695 hfinfo->type == FT_INT32 ||
12696 hfinfo->type == FT_INT40 ||
12697 hfinfo->type == FT_INT48 ||
12698 hfinfo->type == FT_INT56 ||
12699 hfinfo->type == FT_INT64) {
12700
12701 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12702 case BASE_NONE:
12703 case BASE_DEC:
12704 case BASE_HEX:
12705 case BASE_OCT:
12706 case BASE_DEC_HEX:
12707 case BASE_HEX_DEC:
12708 case BASE_CUSTOM:
12709 case BASE_PT_UDP:
12710 case BASE_PT_TCP:
12711 case BASE_PT_DCCP:
12712 case BASE_PT_SCTP:
12713 case BASE_OUI:
12714 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12715 break;
12716 default:
12717 base_name = "????";
12718 break;
12719 }
12720 } else if (hfinfo->type == FT_BOOLEAN) {
12721 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12722 snprintf(width, sizeof(width), "%d", hfinfo->display);
12723 base_name = width;
12724 }
12725
12726 blurb = hfinfo->blurb;
12727 if (blurb == NULL((void*)0))
12728 blurb = "";
12729 else if (strlen(blurb) == 0)
12730 blurb = "\"\"";
12731
12732 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12733 hfinfo->name, hfinfo->abbrev, enum_name,
12734 parent_hfinfo->abbrev, base_name,
12735 hfinfo->bitmask, blurb);
12736 }
12737 }
12738}
12739
12740/* Dumps all abbreviated field and protocol completions of the given string to
12741 * stdout. An independent program may use this for command-line tab completion
12742 * of fields.
12743 */
12744bool_Bool
12745proto_registrar_dump_field_completions(const char *prefix)
12746{
12747 header_field_info *hfinfo;
12748 int i, len;
12749 size_t prefix_len;
12750 bool_Bool matched = false0;
12751
12752 prefix_len = strlen(prefix);
12753 len = gpa_hfinfo.len;
12754 for (i = 1; i < len ; i++) {
12755 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12756 continue; /* This is a deregistered protocol or header field */
12757
12758 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", 12758
, __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", 12758
, "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", 12758, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12759
12760 /*
12761 * Skip the pseudo-field for "proto_tree_add_text()" since
12762 * we don't want it in the list of filterable fields.
12763 */
12764 if (hfinfo->id == hf_text_only)
12765 continue;
12766
12767 /* format for protocols */
12768 if (proto_registrar_is_protocol(i)) {
12769 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12770 matched = true1;
12771 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12772 }
12773 }
12774 /* format for header fields */
12775 else {
12776 /*
12777 * If this field isn't at the head of the list of
12778 * fields with this name, skip this field - all
12779 * fields with the same name are really just versions
12780 * of the same field stored in different bits, and
12781 * should have the same type/radix/value list, and
12782 * just differ in their bit masks. (If a field isn't
12783 * a bitfield, but can be, say, 1 or 2 bytes long,
12784 * it can just be made FT_UINT16, meaning the
12785 * *maximum* length is 2 bytes, and be used
12786 * for all lengths.)
12787 */
12788 if (hfinfo->same_name_prev_id != -1)
12789 continue;
12790
12791 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12792 matched = true1;
12793 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12794 }
12795 }
12796 }
12797 return matched;
12798}
12799
12800/* Dumps field types and descriptive names to stdout. An independent
12801 * program can take this output and format it into nice tables or HTML or
12802 * whatever.
12803 *
12804 * There is one record per line. The fields are tab-delimited.
12805 *
12806 * Field 1 = field type name, e.g. FT_UINT8
12807 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12808 */
12809void
12810proto_registrar_dump_ftypes(void)
12811{
12812 int fte;
12813
12814 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12815 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12816 }
12817}
12818
12819/* This function indicates whether it's possible to construct a
12820 * "match selected" display filter string for the specified field,
12821 * returns an indication of whether it's possible, and, if it's
12822 * possible and "filter" is non-null, constructs the filter and
12823 * sets "*filter" to point to it.
12824 * You do not need to [g_]free() this string since it will be automatically
12825 * freed once the next packet is dissected.
12826 */
12827static bool_Bool
12828construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12829 char **filter)
12830{
12831 const header_field_info *hfinfo;
12832 int start, length, length_remaining;
12833
12834 if (!finfo)
12835 return false0;
12836
12837 hfinfo = finfo->hfinfo;
12838 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12838, "hfinfo"))))
;
12839
12840 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12841 * then "the numeric value ... is not used when preparing
12842 * filters for the field in question." If it's any other
12843 * base, we'll generate the filter normally (which will
12844 * be numeric, even though the human-readable string does
12845 * work for filtering.)
12846 *
12847 * XXX - It might be nice to use fvalue_to_string_repr() in
12848 * "proto_item_fill_label()" as well, although, there, you'd
12849 * have to deal with the base *and* with resolved values for
12850 * addresses.
12851 *
12852 * Perhaps in addition to taking the repr type (DISPLAY
12853 * or DFILTER) and the display (base), fvalue_to_string_repr()
12854 * should have the the "strings" values in the header_field_info
12855 * structure for the field as a parameter, so it can have
12856 * if the field is Boolean or an enumerated integer type,
12857 * the tables used to generate human-readable values.
12858 */
12859 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12860 const char *str = NULL((void*)0);
12861
12862 switch (hfinfo->type) {
12863
12864 case FT_INT8:
12865 case FT_INT16:
12866 case FT_INT24:
12867 case FT_INT32:
12868 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12869 break;
12870
12871 case FT_CHAR:
12872 case FT_UINT8:
12873 case FT_UINT16:
12874 case FT_UINT24:
12875 case FT_UINT32:
12876 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12877 break;
12878
12879 default:
12880 break;
12881 }
12882
12883 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12884 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12885 return true1;
12886 }
12887 }
12888
12889 switch (hfinfo->type) {
12890
12891 case FT_PROTOCOL:
12892 if (filter != NULL((void*)0))
12893 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12894 break;
12895
12896 case FT_NONE:
12897 /*
12898 * If the length is 0, just match the name of the
12899 * field.
12900 *
12901 * (Also check for negative values, just in case,
12902 * as we'll cast it to an unsigned value later.)
12903 */
12904 length = finfo->length;
12905 if (length == 0) {
12906 if (filter != NULL((void*)0))
12907 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12908 break;
12909 }
12910 if (length < 0)
12911 return false0;
12912
12913 /*
12914 * This doesn't have a value, so we'd match
12915 * on the raw bytes at this address.
12916 *
12917 * Should we be allowed to access to the raw bytes?
12918 * If "edt" is NULL, the answer is "no".
12919 */
12920 if (edt == NULL((void*)0))
12921 return false0;
12922
12923 /*
12924 * Is this field part of the raw frame tvbuff?
12925 * If not, we can't use "frame[N:M]" to match
12926 * it.
12927 *
12928 * XXX - should this be frame-relative, or
12929 * protocol-relative?
12930 *
12931 * XXX - does this fallback for non-registered
12932 * fields even make sense?
12933 */
12934 if (finfo->ds_tvb != edt->tvb)
12935 return false0; /* you lose */
12936
12937 /*
12938 * Don't go past the end of that tvbuff.
12939 */
12940 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12941 if (length > length_remaining)
12942 length = length_remaining;
12943 if (length <= 0)
12944 return false0;
12945
12946 if (filter != NULL((void*)0)) {
12947 start = finfo->start;
12948 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12949 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12950 wmem_free(NULL((void*)0), str);
12951 }
12952 break;
12953
12954 /* By default, use the fvalue's "to_string_repr" method. */
12955 default:
12956 if (filter != NULL((void*)0)) {
12957 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12958 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12959 wmem_free(NULL((void*)0), str);
12960 }
12961 break;
12962 }
12963
12964 return true1;
12965}
12966
12967/*
12968 * Returns true if we can do a "match selected" on the field, false
12969 * otherwise.
12970 */
12971bool_Bool
12972proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12973{
12974 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12975}
12976
12977/* This function attempts to construct a "match selected" display filter
12978 * string for the specified field; if it can do so, it returns a pointer
12979 * to the string, otherwise it returns NULL.
12980 *
12981 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12982 */
12983char *
12984proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12985{
12986 char *filter = NULL((void*)0);
12987
12988 if (!construct_match_selected_string(finfo, edt, &filter))
12989 {
12990 wmem_free(NULL((void*)0), filter);
12991 return NULL((void*)0);
12992 }
12993 return filter;
12994}
12995
12996/* This function is common code for all proto_tree_add_bitmask... functions.
12997 */
12998
12999static bool_Bool
13000proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
13001 const unsigned len, const int ett, int * const *fields,
13002 const int flags, bool_Bool first,
13003 bool_Bool use_parent_tree,
13004 proto_tree* tree, uint64_t value)
13005{
13006 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
13007 uint64_t bitmask = 0;
13008 uint64_t tmpval;
13009 header_field_info *hf;
13010 uint32_t integer32;
13011 int bit_offset;
13012 int no_of_bits;
13013
13014 if (!*fields)
13015 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"
)
;
13016
13017 if (len > 8)
13018 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
13019 /**
13020 * packet-frame.c uses len=0 since the value is taken from the packet
13021 * metadata, not the packet bytes. In that case, assume that all bits
13022 * in the provided value are valid.
13023 */
13024 if (len > 0) {
13025 available_bits >>= (8 - len)*8;
13026 }
13027
13028 if (use_parent_tree == false0)
13029 tree = proto_item_add_subtree(item, ett);
13030
13031 while (*fields) {
13032 uint64_t present_bits;
13033 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", 13033, __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", 13033
, "**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", 13033, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
13034 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", 13034
, "hf->bitmask != 0", hf->abbrev))))
;
13035
13036 bitmask |= hf->bitmask;
13037
13038 /* Skip fields that aren't fully present */
13039 present_bits = available_bits & hf->bitmask;
13040 if (present_bits != hf->bitmask) {
13041 fields++;
13042 continue;
13043 }
13044
13045 switch (hf->type) {
13046 case FT_CHAR:
13047 case FT_UINT8:
13048 case FT_UINT16:
13049 case FT_UINT24:
13050 case FT_UINT32:
13051 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
13052 break;
13053
13054 case FT_INT8:
13055 case FT_INT16:
13056 case FT_INT24:
13057 case FT_INT32:
13058 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
13059 break;
13060
13061 case FT_UINT40:
13062 case FT_UINT48:
13063 case FT_UINT56:
13064 case FT_UINT64:
13065 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
13066 break;
13067
13068 case FT_INT40:
13069 case FT_INT48:
13070 case FT_INT56:
13071 case FT_INT64:
13072 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
13073 break;
13074
13075 case FT_BOOLEAN:
13076 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
13077 break;
13078
13079 default:
13080 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))
13081 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))
13082 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))
13083 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))
;
13084 break;
13085 }
13086 if (flags & BMT_NO_APPEND0x01) {
13087 fields++;
13088 continue;
13089 }
13090 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
13091
13092 /* XXX: README.developer and the comments have always defined
13093 * BMT_NO_INT as "only boolean flags are added to the title /
13094 * don't add non-boolean (integral) fields", but the
13095 * implementation has always added BASE_CUSTOM and fields with
13096 * value_strings, though not fields with unit_strings.
13097 * Possibly this is because some dissectors use a FT_UINT8
13098 * with a value_string for fields that should be a FT_BOOLEAN.
13099 */
13100 switch (hf->type) {
13101 case FT_CHAR:
13102 if (hf->display == BASE_CUSTOM) {
13103 char lbl[ITEM_LABEL_LENGTH240];
13104 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13105
13106 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13106, "fmtfunc"))))
;
13107 fmtfunc(lbl, (uint32_t) tmpval);
13108 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13109 hf->name, lbl);
13110 first = false0;
13111 }
13112 else if (hf->strings) {
13113 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13114 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13115 first = false0;
13116 }
13117 else if (!(flags & BMT_NO_INT0x02)) {
13118 char buf[32];
13119 const char *out;
13120
13121 if (!first) {
13122 proto_item_append_text(item, ", ");
13123 }
13124
13125 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13126 proto_item_append_text(item, "%s: %s", hf->name, out);
13127 first = false0;
13128 }
13129
13130 break;
13131
13132 case FT_UINT8:
13133 case FT_UINT16:
13134 case FT_UINT24:
13135 case FT_UINT32:
13136 if (hf->display == BASE_CUSTOM) {
13137 char lbl[ITEM_LABEL_LENGTH240];
13138 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13139
13140 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13140, "fmtfunc"))))
;
13141 fmtfunc(lbl, (uint32_t) tmpval);
13142 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13143 hf->name, lbl);
13144 first = false0;
13145 }
13146 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13147 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13148 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13149 first = false0;
13150 }
13151 else if (!(flags & BMT_NO_INT0x02)) {
13152 char buf[NUMBER_LABEL_LENGTH80];
13153 const char *out = NULL((void*)0);
13154
13155 if (!first) {
13156 proto_item_append_text(item, ", ");
13157 }
13158
13159 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13160 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13161 }
13162 if (out == NULL((void*)0)) {
13163 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13164 }
13165 proto_item_append_text(item, "%s: %s", hf->name, out);
13166 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13167 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13168 }
13169 first = false0;
13170 }
13171
13172 break;
13173
13174 case FT_INT8:
13175 case FT_INT16:
13176 case FT_INT24:
13177 case FT_INT32:
13178 integer32 = (uint32_t) tmpval;
13179 if (hf->bitmask) {
13180 no_of_bits = ws_count_ones(hf->bitmask);
13181 integer32 = ws_sign_ext32(integer32, no_of_bits);
13182 }
13183 if (hf->display == BASE_CUSTOM) {
13184 char lbl[ITEM_LABEL_LENGTH240];
13185 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13186
13187 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13187, "fmtfunc"))))
;
13188 fmtfunc(lbl, (int32_t) integer32);
13189 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13190 hf->name, lbl);
13191 first = false0;
13192 }
13193 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13194 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13195 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13196 first = false0;
13197 }
13198 else if (!(flags & BMT_NO_INT0x02)) {
13199 char buf[NUMBER_LABEL_LENGTH80];
13200 const char *out = NULL((void*)0);
13201
13202 if (!first) {
13203 proto_item_append_text(item, ", ");
13204 }
13205
13206 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13207 out = hf_try_val_to_str((int32_t) integer32, hf);
13208 }
13209 if (out == NULL((void*)0)) {
13210 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13211 }
13212 proto_item_append_text(item, "%s: %s", hf->name, out);
13213 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13214 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13215 }
13216 first = false0;
13217 }
13218
13219 break;
13220
13221 case FT_UINT40:
13222 case FT_UINT48:
13223 case FT_UINT56:
13224 case FT_UINT64:
13225 if (hf->display == BASE_CUSTOM) {
13226 char lbl[ITEM_LABEL_LENGTH240];
13227 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13228
13229 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13229, "fmtfunc"))))
;
13230 fmtfunc(lbl, tmpval);
13231 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13232 hf->name, lbl);
13233 first = false0;
13234 }
13235 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13236 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13237 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13238 first = false0;
13239 }
13240 else if (!(flags & BMT_NO_INT0x02)) {
13241 char buf[NUMBER_LABEL_LENGTH80];
13242 const char *out = NULL((void*)0);
13243
13244 if (!first) {
13245 proto_item_append_text(item, ", ");
13246 }
13247
13248 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13249 out = hf_try_val64_to_str(tmpval, hf);
13250 }
13251 if (out == NULL((void*)0)) {
13252 out = hfinfo_number_value_format64(hf, buf, tmpval);
13253 }
13254 proto_item_append_text(item, "%s: %s", hf->name, out);
13255 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13256 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13257 }
13258 first = false0;
13259 }
13260
13261 break;
13262
13263 case FT_INT40:
13264 case FT_INT48:
13265 case FT_INT56:
13266 case FT_INT64:
13267 if (hf->bitmask) {
13268 no_of_bits = ws_count_ones(hf->bitmask);
13269 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13270 }
13271 if (hf->display == BASE_CUSTOM) {
13272 char lbl[ITEM_LABEL_LENGTH240];
13273 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13274
13275 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13275, "fmtfunc"))))
;
13276 fmtfunc(lbl, (int64_t) tmpval);
13277 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13278 hf->name, lbl);
13279 first = false0;
13280 }
13281 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13282 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13283 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13284 first = false0;
13285 }
13286 else if (!(flags & BMT_NO_INT0x02)) {
13287 char buf[NUMBER_LABEL_LENGTH80];
13288 const char *out = NULL((void*)0);
13289
13290 if (!first) {
13291 proto_item_append_text(item, ", ");
13292 }
13293
13294 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13295 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13296 }
13297 if (out == NULL((void*)0)) {
13298 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13299 }
13300 proto_item_append_text(item, "%s: %s", hf->name, out);
13301 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13302 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13303 }
13304 first = false0;
13305 }
13306
13307 break;
13308
13309 case FT_BOOLEAN:
13310 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13311 /* If we have true/false strings, emit full - otherwise messages
13312 might look weird */
13313 const struct true_false_string *tfs =
13314 (const struct true_false_string *)hf->strings;
13315
13316 if (tmpval) {
13317 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13318 hf->name, tfs->true_string);
13319 first = false0;
13320 } else if (!(flags & BMT_NO_FALSE0x04)) {
13321 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13322 hf->name, tfs->false_string);
13323 first = false0;
13324 }
13325 } else if (hf->bitmask & value) {
13326 /* If the flag is set, show the name */
13327 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13328 first = false0;
13329 }
13330 break;
13331 default:
13332 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))
13333 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))
13334 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))
13335 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))
;
13336 break;
13337 }
13338
13339 fields++;
13340 }
13341
13342 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13343 * but then again most dissectors don't set the bitmask field for
13344 * the higher level bitmask hfi, so calculate the bitmask from the
13345 * fields present. */
13346 if (item) {
13347 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13348 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13349 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)
;
13350 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)
;
13351 }
13352 return first;
13353}
13354
13355/* This function will dissect a sequence of bytes that describe a
13356 * bitmask and supply the value of that sequence through a pointer.
13357 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13358 * to be dissected.
13359 * This field will form an expansion under which the individual fields of the
13360 * bitmask is dissected and displayed.
13361 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13362 *
13363 * fields is an array of pointers to int that lists all the fields of the
13364 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13365 * or another integer of the same type/size as hf_hdr with a mask specified.
13366 * This array is terminated by a NULL entry.
13367 *
13368 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13369 * FT_integer fields that have a value_string attached will have the
13370 * matched string displayed on the expansion line.
13371 */
13372proto_item *
13373proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13374 const unsigned offset, const int hf_hdr,
13375 const int ett, int * const *fields,
13376 const unsigned encoding, uint64_t *retval)
13377{
13378 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);
13379}
13380
13381/* This function will dissect a sequence of bytes that describe a
13382 * bitmask.
13383 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13384 * to be dissected.
13385 * This field will form an expansion under which the individual fields of the
13386 * bitmask is dissected and displayed.
13387 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13388 *
13389 * fields is an array of pointers to int that lists all the fields of the
13390 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13391 * or another integer of the same type/size as hf_hdr with a mask specified.
13392 * This array is terminated by a NULL entry.
13393 *
13394 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13395 * FT_integer fields that have a value_string attached will have the
13396 * matched string displayed on the expansion line.
13397 */
13398proto_item *
13399proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13400 const unsigned offset, const int hf_hdr,
13401 const int ett, int * const *fields,
13402 const unsigned encoding)
13403{
13404 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13405}
13406
13407/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13408 * what data is appended to the header.
13409 */
13410proto_item *
13411proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13412 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13413 uint64_t *retval)
13414{
13415 proto_item *item = NULL((void*)0);
13416 header_field_info *hf;
13417 unsigned len;
13418 uint64_t value;
13419
13420 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", 13420, __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", 13420
, "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", 13420, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13421 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", 13421, (hf)->abbrev)))
;
13422 len = ftype_wire_size(hf->type);
13423 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13424
13425 if (parent_tree) {
13426 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13427 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13428 flags, false0, false0, NULL((void*)0), value);
13429 }
13430
13431 *retval = value;
13432 if (hf->bitmask) {
13433 /* Mask out irrelevant portions */
13434 *retval &= hf->bitmask;
13435 /* Shift bits */
13436 *retval >>= hfinfo_bitshift(hf);
13437 }
13438
13439 return item;
13440}
13441
13442/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13443 * what data is appended to the header.
13444 */
13445proto_item *
13446proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13447 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13448{
13449 proto_item *item = NULL((void*)0);
13450 header_field_info *hf;
13451 unsigned len;
13452 uint64_t value;
13453
13454 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", 13454, __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", 13454
, "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", 13454, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13455 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", 13455, (hf)->abbrev)))
;
13456
13457 if (parent_tree) {
13458 len = ftype_wire_size(hf->type);
13459 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13460 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13461 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13462 flags, false0, false0, NULL((void*)0), value);
13463 }
13464
13465 return item;
13466}
13467
13468/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13469 can't be retrieved directly from tvb) */
13470proto_item *
13471proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13472 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13473{
13474 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13475 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13476}
13477
13478/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13479WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13480proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13481 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13482{
13483 proto_item *item = NULL((void*)0);
13484 header_field_info *hf;
13485 unsigned len;
13486
13487 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", 13487, __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", 13487
, "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", 13487, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13488 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", 13488, (hf)->abbrev)))
;
13489 /* the proto_tree_add_uint/_uint64() calls below
13490 will fail if tvb==NULL and len!=0 */
13491 len = tvb ? ftype_wire_size(hf->type) : 0;
13492
13493 if (parent_tree) {
13494 if (len <= 4)
13495 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13496 else
13497 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13498
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 no "header" item to group all of the fields */
13507void
13508proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13509 const unsigned len, int * const *fields, const unsigned encoding)
13510{
13511 uint64_t value;
13512
13513 if (tree) {
13514 value = get_uint64_value(tree, tvb, offset, len, encoding);
13515 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13516 BMT_NO_APPEND0x01, false0, true1, tree, value);
13517 }
13518}
13519
13520WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13521proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13522 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13523{
13524 uint64_t value;
13525
13526 value = get_uint64_value(tree, tvb, offset, len, encoding);
13527 if (tree) {
13528 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13529 BMT_NO_APPEND0x01, false0, true1, tree, value);
13530 }
13531 if (retval) {
13532 *retval = value;
13533 }
13534}
13535
13536WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13537proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13538 const unsigned len, int * const *fields, const uint64_t value)
13539{
13540 if (tree) {
13541 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13542 BMT_NO_APPEND0x01, false0, true1, tree, value);
13543 }
13544}
13545
13546
13547/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13548 * This is intended to support bitmask fields whose lengths can vary, perhaps
13549 * as the underlying standard evolves over time.
13550 * With this API there is the possibility of being called to display more or
13551 * less data than the dissector was coded to support.
13552 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13553 * Thus when presented with "too much" or "too little" data, MSbits will be
13554 * ignored or MSfields sacrificed.
13555 *
13556 * Only fields for which all defined bits are available are displayed.
13557 */
13558proto_item *
13559proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13560 const unsigned offset, const unsigned len, const int hf_hdr,
13561 const int ett, int * const *fields, struct expert_field* exp,
13562 const unsigned encoding)
13563{
13564 proto_item *item = NULL((void*)0);
13565 header_field_info *hf;
13566 unsigned decodable_len;
13567 unsigned decodable_offset;
13568 uint32_t decodable_value;
13569 uint64_t value;
13570
13571 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", 13571, __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", 13571
, "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", 13571, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13572 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", 13572, (hf)->abbrev)))
;
13573
13574 decodable_offset = offset;
13575 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13576
13577 /* If we are ftype_wire_size-limited,
13578 * make sure we decode as many LSBs as possible.
13579 */
13580 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13581 decodable_offset += (len - decodable_len);
13582 }
13583
13584 if (parent_tree) {
13585 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13586 decodable_len, encoding);
13587
13588 /* The root item covers all the bytes even if we can't decode them all */
13589 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13590 decodable_value);
13591 }
13592
13593 if (decodable_len < len) {
13594 /* Dissector likely requires updating for new protocol revision */
13595 expert_add_info_format(NULL((void*)0), item, exp,
13596 "Only least-significant %d of %d bytes decoded",
13597 decodable_len, len);
13598 }
13599
13600 if (item) {
13601 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13602 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13603 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13604 }
13605
13606 return item;
13607}
13608
13609/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13610proto_item *
13611proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13612 const unsigned offset, const unsigned len,
13613 const char *name, const char *fallback,
13614 const int ett, int * const *fields,
13615 const unsigned encoding, const int flags)
13616{
13617 proto_item *item = NULL((void*)0);
13618 uint64_t value;
13619
13620 if (parent_tree) {
13621 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13622 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13623 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13624 flags, true1, false0, NULL((void*)0), value) && fallback) {
13625 /* Still at first item - append 'fallback' text if any */
13626 proto_item_append_text(item, "%s", fallback);
13627 }
13628 }
13629
13630 return item;
13631}
13632
13633proto_item *
13634proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13635 const unsigned bit_offset, const int no_of_bits,
13636 const unsigned encoding)
13637{
13638 header_field_info *hfinfo;
13639 int octet_length;
13640 unsigned octet_offset;
13641
13642 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", 13642, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13642
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13642, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13643
13644 if (no_of_bits < 0) {
13645 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13646 }
13647 octet_length = (no_of_bits + 7) >> 3;
13648 octet_offset = bit_offset >> 3;
13649 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13650
13651 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13652 * but only after doing a bunch more work (which we can, in the common
13653 * case, shortcut here).
13654 */
13655 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13656 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", 13656
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13656, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13656, "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", 13656, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13657
13658 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13659}
13660
13661/*
13662 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13663 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13664 * Offset should be given in bits from the start of the tvb.
13665 */
13666
13667static proto_item *
13668_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13669 const unsigned bit_offset, const int no_of_bits,
13670 uint64_t *return_value, const unsigned encoding)
13671{
13672 unsigned offset;
13673 unsigned length;
13674 uint8_t tot_no_bits;
13675 char *bf_str;
13676 char lbl_str[ITEM_LABEL_LENGTH240];
13677 uint64_t value = 0;
13678 uint8_t *bytes = NULL((void*)0);
13679 size_t bytes_length = 0;
13680
13681 proto_item *pi;
13682 header_field_info *hf_field;
13683
13684 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13685 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", 13685, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13685
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13685, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13686
13687 if (hf_field->bitmask != 0) {
13688 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)
13689 " 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)
13690 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)
;
13691 }
13692
13693 if (no_of_bits < 0) {
13694 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13695 } else if (no_of_bits == 0) {
13696 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)
13697 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)
;
13698 }
13699
13700 /* Byte align offset */
13701 offset = bit_offset>>3;
13702
13703 /*
13704 * Calculate the number of octets used to hold the bits
13705 */
13706 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13707 length = (tot_no_bits + 7) >> 3;
13708
13709 if (no_of_bits < 65) {
13710 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13711 } else if (hf_field->type != FT_BYTES) {
13712 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)
13713 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)
;
13714 return NULL((void*)0);
13715 }
13716
13717 /* Sign extend for signed types */
13718 switch (hf_field->type) {
13719 case FT_INT8:
13720 case FT_INT16:
13721 case FT_INT24:
13722 case FT_INT32:
13723 case FT_INT40:
13724 case FT_INT48:
13725 case FT_INT56:
13726 case FT_INT64:
13727 value = ws_sign_ext64(value, no_of_bits);
13728 break;
13729
13730 default:
13731 break;
13732 }
13733
13734 if (return_value) {
13735 *return_value = value;
13736 }
13737
13738 /* Coast clear. Try and fake it */
13739 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13740 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", 13740
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13740, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13740, "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", 13740, __func__, "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); } } }
;
13741
13742 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13743
13744 switch (hf_field->type) {
13745 case FT_BOOLEAN:
13746 /* Boolean field */
13747 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13748 "%s = %s: %s",
13749 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13750 break;
13751
13752 case FT_CHAR:
13753 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13754 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13755 break;
13756
13757 case FT_UINT8:
13758 case FT_UINT16:
13759 case FT_UINT24:
13760 case FT_UINT32:
13761 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13762 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13763 break;
13764
13765 case FT_INT8:
13766 case FT_INT16:
13767 case FT_INT24:
13768 case FT_INT32:
13769 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13770 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13771 break;
13772
13773 case FT_UINT40:
13774 case FT_UINT48:
13775 case FT_UINT56:
13776 case FT_UINT64:
13777 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13778 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13779 break;
13780
13781 case FT_INT40:
13782 case FT_INT48:
13783 case FT_INT56:
13784 case FT_INT64:
13785 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13786 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13787 break;
13788
13789 case FT_BYTES:
13790 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13791 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13792 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13793 proto_item_set_text(pi, "%s", lbl_str);
13794 return pi;
13795
13796 /* TODO: should handle FT_UINT_BYTES ? */
13797
13798 default:
13799 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))
13800 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))
13801 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))
13802 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))
;
13803 return NULL((void*)0);
13804 }
13805
13806 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13807 return pi;
13808}
13809
13810proto_item *
13811proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13812 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13813 uint64_t *return_value)
13814{
13815 proto_item *pi;
13816 int no_of_bits;
13817 unsigned octet_offset;
13818 unsigned mask_initial_bit_offset;
13819 unsigned mask_greatest_bit_offset;
13820 unsigned octet_length;
13821 uint8_t i;
13822 char bf_str[256];
13823 char lbl_str[ITEM_LABEL_LENGTH240];
13824 uint64_t value;
13825 uint64_t composite_bitmask;
13826 uint64_t composite_bitmap;
13827
13828 header_field_info *hf_field;
13829
13830 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13831 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", 13831, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13831
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13831, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13832
13833 if (hf_field->bitmask != 0) {
13834 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)
13835 " 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)
13836 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)
;
13837 }
13838
13839 mask_initial_bit_offset = bit_offset % 8;
13840
13841 no_of_bits = 0;
13842 value = 0;
13843 i = 0;
13844 mask_greatest_bit_offset = 0;
13845 composite_bitmask = 0;
13846 composite_bitmap = 0;
13847
13848 while (crumb_spec[i].crumb_bit_length != 0) {
13849 uint64_t crumb_mask, crumb_value;
13850 uint8_t crumb_end_bit_offset;
13851
13852 crumb_value = tvb_get_bits64(tvb,
13853 bit_offset + crumb_spec[i].crumb_bit_offset,
13854 crumb_spec[i].crumb_bit_length,
13855 ENC_BIG_ENDIAN0x00000000);
13856 value += crumb_value;
13857 no_of_bits += crumb_spec[i].crumb_bit_length;
13858 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", 13858
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
13859
13860 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13861 octet containing the initial offset.
13862 If the mask is beyond 32 bits, then give up on bit map display.
13863 This could be improved in future, probably showing a table
13864 of 32 or 64 bits per row */
13865 if (mask_greatest_bit_offset < 32) {
13866 crumb_end_bit_offset = mask_initial_bit_offset
13867 + crumb_spec[i].crumb_bit_offset
13868 + crumb_spec[i].crumb_bit_length;
13869 crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
13870
13871 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
13872 mask_greatest_bit_offset = crumb_end_bit_offset;
13873 }
13874 /* Currently the bitmap of the crumbs are only shown if
13875 * smaller than 32 bits. Do not bother calculating the
13876 * mask if it is larger than that. */
13877 if (crumb_end_bit_offset <= 32) {
13878 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
13879 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13880 }
13881 }
13882 /* Shift left for the next segment */
13883 value <<= crumb_spec[++i].crumb_bit_length;
13884 }
13885
13886 /* Sign extend for signed types */
13887 switch (hf_field->type) {
13888 case FT_INT8:
13889 case FT_INT16:
13890 case FT_INT24:
13891 case FT_INT32:
13892 case FT_INT40:
13893 case FT_INT48:
13894 case FT_INT56:
13895 case FT_INT64:
13896 value = ws_sign_ext64(value, no_of_bits);
13897 break;
13898 default:
13899 break;
13900 }
13901
13902 if (return_value) {
13903 *return_value = value;
13904 }
13905
13906 /* Coast clear. Try and fake it */
13907 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13908 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", 13908
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13908, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13908, "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", 13908, __func__, "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); } } }
;
13909
13910 /* initialise the format string */
13911 bf_str[0] = '\0';
13912
13913 octet_offset = bit_offset >> 3;
13914
13915 /* Round up mask length to nearest octet */
13916 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13917 mask_greatest_bit_offset = octet_length << 3;
13918
13919 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13920 It would be a useful enhancement to eliminate this restriction. */
13921 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13922 other_decode_bitfield_value(bf_str,
13923 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13924 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13925 mask_greatest_bit_offset);
13926 } else {
13927 /* If the bitmask is too large, try to describe its contents. */
13928 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13929 }
13930
13931 switch (hf_field->type) {
13932 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13933 /* Boolean field */
13934 return proto_tree_add_boolean_format(tree, hfindex,
13935 tvb, octet_offset, octet_length, value,
13936 "%s = %s: %s",
13937 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13938 break;
13939
13940 case FT_CHAR:
13941 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13942 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13943 break;
13944
13945 case FT_UINT8:
13946 case FT_UINT16:
13947 case FT_UINT24:
13948 case FT_UINT32:
13949 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13950 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13951 break;
13952
13953 case FT_INT8:
13954 case FT_INT16:
13955 case FT_INT24:
13956 case FT_INT32:
13957 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13958 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13959 break;
13960
13961 case FT_UINT40:
13962 case FT_UINT48:
13963 case FT_UINT56:
13964 case FT_UINT64:
13965 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13966 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13967 break;
13968
13969 case FT_INT40:
13970 case FT_INT48:
13971 case FT_INT56:
13972 case FT_INT64:
13973 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13974 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13975 break;
13976
13977 default:
13978 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))
13979 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))
13980 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))
13981 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))
;
13982 return NULL((void*)0);
13983 }
13984 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13985 return pi;
13986}
13987
13988void
13989proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13990 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13991{
13992 header_field_info *hfinfo;
13993 unsigned start = bit_offset >> 3;
13994 unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13995
13996 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13997 * so that we can use the tree's memory scope in calculating the string */
13998 tvb_ensure_bytes_exist(tvb, start, length);
13999 if (!tree) return;
14000
14001 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", 14001, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 14001
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14001, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
14002 proto_tree_add_text_internal(tree, tvb, start, length,
14003 "%s crumb %d of %s (decoded above)",
14004 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
14005 tvb_get_bits32(tvb,
14006 bit_offset,
14007 crumb_spec[crumb_index].crumb_bit_length,
14008 ENC_BIG_ENDIAN0x00000000),
14009 ENC_BIG_ENDIAN0x00000000),
14010 crumb_index,
14011 hfinfo->name);
14012}
14013
14014proto_item *
14015proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14016 const unsigned bit_offset, const int no_of_bits,
14017 uint64_t *return_value, const unsigned encoding)
14018{
14019 proto_item *item;
14020
14021 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
14022 bit_offset, no_of_bits,
14023 return_value, encoding))) {
14024 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)
;
14025 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)
;
14026 }
14027 return item;
14028}
14029
14030static proto_item *
14031_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14032 tvbuff_t *tvb, const unsigned bit_offset,
14033 const int no_of_bits, void *value_ptr,
14034 const unsigned encoding, char *value_str)
14035{
14036 unsigned offset;
14037 unsigned length;
14038 uint8_t tot_no_bits;
14039 char *str;
14040 uint64_t value = 0;
14041 header_field_info *hf_field;
14042
14043 /* We do not have to return a value, try to fake it as soon as possible */
14044 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14045 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", 14045
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14045, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14045, "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", 14045, __func__, "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); } } }
;
14046
14047 if (hf_field->bitmask != 0) {
14048 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)
14049 " 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)
14050 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)
;
14051 }
14052
14053 if (no_of_bits < 0) {
14054 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
14055 } else if (no_of_bits == 0) {
14056 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)
14057 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)
;
14058 }
14059
14060 /* Byte align offset */
14061 offset = bit_offset>>3;
14062
14063 /*
14064 * Calculate the number of octets used to hold the bits
14065 */
14066 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
14067 length = tot_no_bits>>3;
14068 /* If we are using part of the next octet, increase length by 1 */
14069 if (tot_no_bits & 0x07)
14070 length++;
14071
14072 if (no_of_bits < 65) {
14073 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
14074 } else {
14075 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)
14076 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)
;
14077 return NULL((void*)0);
14078 }
14079
14080 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
14081
14082 (void) g_strlcat(str, " = ", 256+64);
14083 (void) g_strlcat(str, hf_field->name, 256+64);
14084
14085 /*
14086 * This function does not receive an actual value but a dimensionless pointer to that value.
14087 * For this reason, the type of the header field is examined in order to determine
14088 * what kind of value we should read from this address.
14089 * The caller of this function must make sure that for the specific header field type the address of
14090 * a compatible value is provided.
14091 */
14092 switch (hf_field->type) {
14093 case FT_BOOLEAN:
14094 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14095 "%s: %s", str, value_str);
14096 break;
14097
14098 case FT_CHAR:
14099 case FT_UINT8:
14100 case FT_UINT16:
14101 case FT_UINT24:
14102 case FT_UINT32:
14103 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
14104 "%s: %s", str, value_str);
14105 break;
14106
14107 case FT_UINT40:
14108 case FT_UINT48:
14109 case FT_UINT56:
14110 case FT_UINT64:
14111 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14112 "%s: %s", str, value_str);
14113 break;
14114
14115 case FT_INT8:
14116 case FT_INT16:
14117 case FT_INT24:
14118 case FT_INT32:
14119 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
14120 "%s: %s", str, value_str);
14121 break;
14122
14123 case FT_INT40:
14124 case FT_INT48:
14125 case FT_INT56:
14126 case FT_INT64:
14127 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14128 "%s: %s", str, value_str);
14129 break;
14130
14131 case FT_FLOAT:
14132 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14133 "%s: %s", str, value_str);
14134 break;
14135
14136 default:
14137 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))
14138 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))
14139 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))
14140 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))
;
14141 return NULL((void*)0);
14142 }
14143}
14144
14145static proto_item *
14146proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14147 tvbuff_t *tvb, const unsigned bit_offset,
14148 const int no_of_bits, void *value_ptr,
14149 const unsigned encoding, char *value_str)
14150{
14151 proto_item *item;
14152
14153 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14154 tvb, bit_offset, no_of_bits,
14155 value_ptr, encoding, value_str))) {
14156 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)
;
14157 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)
;
14158 }
14159 return item;
14160}
14161
14162#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);
\
14163 va_start(ap, format)__builtin_va_start(ap, format); \
14164 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14165 va_end(ap)__builtin_va_end(ap);
14166
14167proto_item *
14168proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14169 tvbuff_t *tvb, const unsigned bit_offset,
14170 const int no_of_bits, uint32_t value,
14171 const unsigned encoding,
14172 const char *format, ...)
14173{
14174 va_list ap;
14175 char *dst;
14176 header_field_info *hf_field;
14177
14178 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14179
14180 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", 14180
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14180, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14180, "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", 14180, __func__, "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); } } }
;
14181
14182 switch (hf_field->type) {
14183 case FT_UINT8:
14184 case FT_UINT16:
14185 case FT_UINT24:
14186 case FT_UINT32:
14187 break;
14188
14189 default:
14190 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)
14191 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)
;
14192 return NULL((void*)0);
14193 }
14194
14195 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);
;
14196
14197 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14198}
14199
14200proto_item *
14201proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14202 tvbuff_t *tvb, const unsigned bit_offset,
14203 const int no_of_bits, uint64_t value,
14204 const unsigned encoding,
14205 const char *format, ...)
14206{
14207 va_list ap;
14208 char *dst;
14209 header_field_info *hf_field;
14210
14211 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14212
14213 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", 14213
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14213, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14213, "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", 14213, __func__, "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); } } }
;
14214
14215 switch (hf_field->type) {
14216 case FT_UINT40:
14217 case FT_UINT48:
14218 case FT_UINT56:
14219 case FT_UINT64:
14220 break;
14221
14222 default:
14223 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)
14224 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)
;
14225 return NULL((void*)0);
14226 }
14227
14228 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);
;
14229
14230 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14231}
14232
14233proto_item *
14234proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14235 tvbuff_t *tvb, const unsigned bit_offset,
14236 const int no_of_bits, float value,
14237 const unsigned encoding,
14238 const char *format, ...)
14239{
14240 va_list ap;
14241 char *dst;
14242 header_field_info *hf_field;
14243
14244 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14245
14246 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", 14246
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14246, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14246, "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", 14246, __func__, "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); } } }
;
14247
14248 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",
14248, ((hf_field))->abbrev))))
;
14249
14250 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);
;
14251
14252 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14253}
14254
14255proto_item *
14256proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14257 tvbuff_t *tvb, const unsigned bit_offset,
14258 const int no_of_bits, int32_t value,
14259 const unsigned encoding,
14260 const char *format, ...)
14261{
14262 va_list ap;
14263 char *dst;
14264 header_field_info *hf_field;
14265
14266 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14267
14268 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", 14268
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14268, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14268, "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", 14268, __func__, "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); } } }
;
14269
14270 switch (hf_field->type) {
14271 case FT_INT8:
14272 case FT_INT16:
14273 case FT_INT24:
14274 case FT_INT32:
14275 break;
14276
14277 default:
14278 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)
14279 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)
;
14280 return NULL((void*)0);
14281 }
14282
14283 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);
;
14284
14285 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14286}
14287
14288proto_item *
14289proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14290 tvbuff_t *tvb, const unsigned bit_offset,
14291 const int no_of_bits, int64_t value,
14292 const unsigned encoding,
14293 const char *format, ...)
14294{
14295 va_list ap;
14296 char *dst;
14297 header_field_info *hf_field;
14298
14299 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14300
14301 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", 14301
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14301, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14301, "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", 14301, __func__, "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); } } }
;
14302
14303 switch (hf_field->type) {
14304 case FT_INT40:
14305 case FT_INT48:
14306 case FT_INT56:
14307 case FT_INT64:
14308 break;
14309
14310 default:
14311 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)
14312 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)
;
14313 return NULL((void*)0);
14314 }
14315
14316 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);
;
14317
14318 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14319}
14320
14321proto_item *
14322proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14323 tvbuff_t *tvb, const unsigned bit_offset,
14324 const int no_of_bits, uint64_t value,
14325 const unsigned encoding,
14326 const char *format, ...)
14327{
14328 va_list ap;
14329 char *dst;
14330 header_field_info *hf_field;
14331
14332 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14333
14334 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", 14334
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14334, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14334, "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", 14334, __func__, "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); } } }
;
14335
14336 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"
, 14336, ((hf_field))->abbrev))))
;
14337
14338 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);
;
14339
14340 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14341}
14342
14343proto_item *
14344proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14345 const unsigned bit_offset, const int no_of_chars)
14346{
14347 proto_item *pi;
14348 header_field_info *hfinfo;
14349 int byte_length;
14350 unsigned byte_offset;
14351 char *string;
14352
14353 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14354
14355 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", 14355
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14355, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14355, "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", 14355, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14356
14357 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"
, 14357, ((hfinfo))->abbrev))))
;
14358
14359 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14360 byte_offset = bit_offset >> 3;
14361
14362 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14363
14364 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14365 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14365, "byte_length >= 0"
))))
;
14366 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14367
14368 return pi;
14369}
14370
14371proto_item *
14372proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14373 const unsigned bit_offset, const int no_of_chars)
14374{
14375 proto_item *pi;
14376 header_field_info *hfinfo;
14377 int byte_length;
14378 unsigned byte_offset;
14379 char *string;
14380
14381 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14382
14383 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", 14383
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14383, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14383, "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", 14383, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14384
14385 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"
, 14385, ((hfinfo))->abbrev))))
;
14386
14387 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14388 byte_offset = bit_offset >> 3;
14389
14390 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14391
14392 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14393 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14393, "byte_length >= 0"
))))
;
14394 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14395
14396 return pi;
14397}
14398
14399const value_string proto_checksum_vals[] = {
14400 { PROTO_CHECKSUM_E_BAD, "Bad" },
14401 { PROTO_CHECKSUM_E_GOOD, "Good" },
14402 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14403 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14404 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14405
14406 { 0, NULL((void*)0) }
14407};
14408
14409#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14410
14411proto_item *
14412proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14413 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14414 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14415{
14416 header_field_info *hfinfo;
14417 uint32_t checksum;
14418 uint32_t len;
14419 proto_item* ti = NULL((void*)0);
14420 proto_item* ti2;
14421 bool_Bool incorrect_checksum = true1;
14422
14423 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", 14423, __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", 14423
, "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", 14423, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14424
14425 switch (hfinfo->type) {
14426 case FT_UINT8:
14427 len = 1;
14428 break;
14429 case FT_UINT16:
14430 len = 2;
14431 break;
14432 case FT_UINT24:
14433 len = 3;
14434 break;
14435 case FT_UINT32:
14436 len = 4;
14437 break;
14438 default:
14439 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)
14440 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14441 }
14442
14443 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14444 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14445 proto_item_set_generated(ti);
14446 // Backward compatible with use of -1
14447 if (hf_checksum_status > 0) {
14448 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14449 proto_item_set_generated(ti2);
14450 }
14451 return ti;
14452 }
14453
14454 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14455 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14456 proto_item_set_generated(ti);
14457 } else {
14458 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14459 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14460 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14461 if (computed_checksum == 0) {
14462 proto_item_append_text(ti, " [correct]");
14463 // Backward compatible with use of -1
14464 if (hf_checksum_status > 0) {
14465 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14466 proto_item_set_generated(ti2);
14467 }
14468 incorrect_checksum = false0;
14469 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14470 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14471 /* XXX - This can't distinguish between "shouldbe"
14472 * 0x0000 and 0xFFFF unless we know whether there
14473 * were any nonzero bits (other than the checksum).
14474 * Protocols should not use this path if they might
14475 * have an all zero packet.
14476 * Some implementations put the wrong zero; maybe
14477 * we should have a special expert info for that?
14478 */
14479 }
14480 } else {
14481 if (checksum == computed_checksum) {
14482 proto_item_append_text(ti, " [correct]");
14483 // Backward compatible with use of -1
14484 if (hf_checksum_status > 0) {
14485 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14486 proto_item_set_generated(ti2);
14487 }
14488 incorrect_checksum = false0;
14489 }
14490 }
14491
14492 if (incorrect_checksum) {
14493 // Backward compatible with use of -1
14494 if (hf_checksum_status > 0) {
14495 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14496 proto_item_set_generated(ti2);
14497 }
14498 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14499 proto_item_append_text(ti, " [incorrect]");
14500 if (bad_checksum_expert != NULL((void*)0))
14501 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14502 } else {
14503 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14504 if (bad_checksum_expert != NULL((void*)0))
14505 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);
14506 }
14507 }
14508 } else {
14509 // Backward compatible with use of -1
14510 if (hf_checksum_status > 0) {
14511 proto_item_append_text(ti, " [unverified]");
14512 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14513 proto_item_set_generated(ti2);
14514 }
14515 }
14516 }
14517
14518 return ti;
14519}
14520
14521proto_item *
14522proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14523 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14524 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14525{
14526 header_field_info *hfinfo;
14527 uint8_t *checksum = NULL((void*)0);
14528 proto_item* ti = NULL((void*)0);
14529 proto_item* ti2;
14530 bool_Bool incorrect_checksum = true1;
14531
14532 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", 14532, __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", 14532
, "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", 14532, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14533
14534 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",
14534, ((hfinfo))->abbrev))))
;
14535
14536 /* Make sure a NULL computed_checksum isn't dereferenced.
14537 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14538 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14539 * cases the behavior is unexpected and still a programmer error;
14540 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14541 * _NOT_PRESENT nor _GENERATED is correct.
14542 */
14543 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", 14543, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14544
14545 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14546 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14547 proto_item_set_generated(ti);
14548 // Backward compatible with use of -1
14549 if (hf_checksum_status > 0) {
14550 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14551 proto_item_set_generated(ti2);
14552 }
14553 return ti;
14554 }
14555
14556 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14557 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14558 proto_item_set_generated(ti);
14559 return ti;
14560 }
14561
14562 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14563 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14564 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14565 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14566 bool_Bool non_zero_flag = false0;
14567 for (size_t index = 0; index < checksum_len; index++) {
14568 if (computed_checksum[index]) {
14569 non_zero_flag = true1;
14570 break;
14571 }
14572 }
14573 if (!non_zero_flag) {
14574 proto_item_append_text(ti, " [correct]");
14575 // Backward compatible with use of -1
14576 if (hf_checksum_status > 0) {
14577 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14578 proto_item_set_generated(ti2);
14579 }
14580 incorrect_checksum = false0;
14581 }
14582 } else {
14583 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14584 proto_item_append_text(ti, " [correct]");
14585 // Backward compatible with use of -1
14586 if (hf_checksum_status > 0) {
14587 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14588 proto_item_set_generated(ti2);
14589 }
14590 incorrect_checksum = false0;
14591 }
14592 }
14593
14594 if (incorrect_checksum) {
14595 // Backward compatible with use of -1
14596 if (hf_checksum_status > 0) {
14597 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14598 proto_item_set_generated(ti2);
14599 }
14600 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14601 proto_item_append_text(ti, " [incorrect]");
14602 if (bad_checksum_expert != NULL((void*)0))
14603 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14604 } else {
14605 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14606 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14607 if (bad_checksum_expert != NULL((void*)0))
14608 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14609 }
14610 }
14611 } else {
14612 // Backward compatible with use of -1
14613 if (hf_checksum_status > 0) {
14614 proto_item_append_text(ti, " [unverified]");
14615 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14616 proto_item_set_generated(ti2);
14617 }
14618 }
14619
14620 return ti;
14621}
14622
14623unsigned char
14624proto_check_field_name(const char *field_name)
14625{
14626 return module_check_valid_name(field_name, false0);
14627}
14628
14629unsigned char
14630proto_check_field_name_lower(const char *field_name)
14631{
14632 return module_check_valid_name(field_name, true1);
14633}
14634
14635bool_Bool
14636tree_expanded(int tree_type)
14637{
14638 if (tree_type <= 0) {
14639 return false0;
14640 }
14641 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", 14641, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14642 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14643}
14644
14645void
14646tree_expanded_set(int tree_type, bool_Bool value)
14647{
14648 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", 14648, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14649
14650 if (value)
14651 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14652 else
14653 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14654}
14655
14656/*
14657 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14658 *
14659 * Local variables:
14660 * c-basic-offset: 8
14661 * tab-width: 8
14662 * indent-tabs-mode: t
14663 * End:
14664 *
14665 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14666 * :indentSize=8:tabSize=8:noTabs=false:
14667 */