Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13725, column 39
The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-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-06-11-100424-3529-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 lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_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
396static int proto_register_field_init(header_field_info *hfinfo, const int parent);
397
398/* special-case header field used within proto.c */
399static header_field_info hfi_text_only =
400 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
401int hf_text_only;
402
403/* Structure for information about a protocol */
404struct _protocol {
405 const char *name; /* long description */
406 const char *short_name; /* short description */
407 const char *filter_name; /* name of this protocol in filters */
408 GPtrArray *fields; /* fields for this protocol */
409 int proto_id; /* field ID for this protocol */
410 bool_Bool is_enabled; /* true if protocol is enabled */
411 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
412 bool_Bool can_toggle; /* true if is_enabled can be changed */
413 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
414 For dissectors that need a protocol name so they
415 can be added to a dissector table, but use the
416 parent_proto_id for things like enable/disable */
417 GList *heur_list; /* Heuristic dissectors associated with this protocol */
418};
419
420/* List of all protocols */
421static GList *protocols;
422
423/* Structure stored for deregistered g_slice */
424struct g_slice_data {
425 size_t block_size;
426 void *mem_block;
427};
428
429/* Deregistered fields */
430static GPtrArray *deregistered_fields;
431static GPtrArray *deregistered_data;
432static GPtrArray *deregistered_slice;
433
434/* indexed by prefix, contains initializers */
435static GHashTable* prefixes;
436
437/* Contains information about a field when a dissector calls
438 * proto_tree_add_item. */
439#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)))
440#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
441
442/* Contains the space for proto_nodes. */
443#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
444 node->first_child = NULL((void*)0); \
445 node->last_child = NULL((void*)0); \
446 node->next = NULL((void*)0);
447
448#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
449 wmem_free(pool, node)
450
451/* String space for protocol and field items for the GUI */
452#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;
\
453 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
454 il->value_pos = 0; \
455 il->value_len = 0;
456#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
457 wmem_free(pool, il);
458
459#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", 459, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 459, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
460 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
461 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 461
, __func__, "Unregistered hf! index=%d", hfindex)
; \
462 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", 462, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
463 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", 463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
464 hfinfo = gpa_hfinfo.hfi[hfindex];
465
466#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
467
468/* List which stores protocols and fields that have been registered */
469typedef struct _gpa_hfinfo_t {
470 uint32_t len;
471 uint32_t allocated_len;
472 header_field_info **hfi;
473} gpa_hfinfo_t;
474
475static gpa_hfinfo_t gpa_hfinfo;
476
477/* Hash table of abbreviations and IDs */
478static wmem_map_t *gpa_name_map;
479static header_field_info *same_name_hfinfo;
480
481/* Hash table protocol aliases. const char * -> const char * */
482static GHashTable *gpa_protocol_aliases;
483
484/*
485 * We're called repeatedly with the same field name when sorting a column.
486 * Cache our last gpa_name_map hit for faster lookups.
487 */
488static char *last_field_name;
489static header_field_info *last_hfinfo;
490
491/* Points to the first element of an array of bits, indexed by
492 a subtree item type; that array element is true if subtrees of
493 an item of that type are to be expanded. */
494static uint32_t *tree_is_expanded;
495
496/* Number of elements in that array. The entry with index 0 is not used. */
497int num_tree_types = 1;
498
499/* Name hashtables for fast detection of duplicate names */
500static GHashTable* proto_names;
501static GHashTable* proto_short_names;
502static GHashTable* proto_filter_names;
503
504static const char * const reserved_filter_names[] = {
505 /* Display filter keywords. */
506 "eq",
507 "ne",
508 "all_eq",
509 "any_eq",
510 "all_ne",
511 "any_ne",
512 "gt",
513 "ge",
514 "lt",
515 "le",
516 "bitand",
517 "bitwise_and",
518 "contains",
519 "matches",
520 "not",
521 "and",
522 "or",
523 "xor",
524 "in",
525 "any",
526 "all",
527 "true",
528 "false",
529 "nan",
530 "inf",
531 "infinity",
532 NULL((void*)0)
533};
534
535static GHashTable *proto_reserved_filter_names;
536static GQueue* saved_dir_queue;
537
538static int
539proto_compare_name(const void *p1_arg, const void *p2_arg)
540{
541 const protocol_t *p1 = (const protocol_t *)p1_arg;
542 const protocol_t *p2 = (const protocol_t *)p2_arg;
543
544 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
545}
546
547static GSList *dissector_plugins;
548
549#ifdef HAVE_PLUGINS1
550void
551proto_register_plugin(const proto_plugin *plug)
552{
553 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
554}
555#else /* HAVE_PLUGINS */
556void
557proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
558{
559 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 559, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
560}
561#endif /* HAVE_PLUGINS */
562
563static void
564call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
565{
566 proto_plugin *plug = (proto_plugin *)data;
567
568 if (plug->register_protoinfo) {
569 plug->register_protoinfo();
570 }
571}
572
573static void
574call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
575{
576 proto_plugin *plug = (proto_plugin *)data;
577
578 if (plug->register_handoff) {
579 plug->register_handoff();
580 }
581}
582
583void proto_pre_init(void)
584{
585 saved_dir_queue = g_queue_new();
586
587 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
589 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
590
591 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
592 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
593 /* GHashTable has no key destructor so the cast is safe. */
594 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
595 }
596
597 gpa_hfinfo.len = 0;
598 gpa_hfinfo.allocated_len = 0;
599 gpa_hfinfo.hfi = NULL((void*)0);
600 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
601 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
602 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
603 deregistered_fields = g_ptr_array_new();
604 deregistered_data = g_ptr_array_new();
605 deregistered_slice = g_ptr_array_new();
606}
607
608/* initialize data structures and register protocols and fields */
609void
610proto_init(GSList *register_all_plugin_protocols_list,
611 GSList *register_all_plugin_handoffs_list,
612 register_entity_func register_func, register_entity_func handoff_func,
613 register_cb cb,
614 void *client_data)
615{
616 /* Initialize the ftype subsystem */
617 ftypes_initialize();
618
619 /* Initialize the address type subsystem */
620 address_types_initialize();
621
622 /* Register one special-case FT_TEXT_ONLY field for use when
623 converting wireshark to new-style proto_tree. These fields
624 are merely strings on the GUI tree; they are not filterable */
625 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
626
627 /* Register the pseudo-protocols used for exceptions. */
628 register_show_exception();
629 register_type_length_mismatch();
630 register_byte_array_string_decodinws_error();
631 register_date_time_string_decodinws_error();
632 register_string_errors();
633 ftypes_register_pseudofields();
634 col_register_protocol();
635
636 /* Have each built-in dissector register its protocols, fields,
637 dissector tables, and dissectors to be called through a
638 handle, and do whatever one-time initialization it needs to
639 do. */
640 if (register_func != NULL((void*)0))
641 register_func(cb, client_data);
642
643 /* Now call the registration routines for all epan plugins. */
644 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
645 ((void (*)(register_cb, void *))l->data)(cb, client_data);
646 }
647
648 /* Now call the registration routines for all dissector plugins. */
649 if (cb)
650 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
651 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
652
653 /* Now call the "handoff registration" routines of all built-in
654 dissectors; those routines register the dissector in other
655 dissectors' handoff tables, and fetch any dissector handles
656 they need. */
657 if (handoff_func != NULL((void*)0))
658 handoff_func(cb, client_data);
659
660 /* Now do the same with epan plugins. */
661 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
662 ((void (*)(register_cb, void *))l->data)(cb, client_data);
663 }
664
665 /* Now do the same with dissector plugins. */
666 if (cb)
667 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
668 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
669
670 /* sort the protocols by protocol name */
671 protocols = g_list_sort(protocols, proto_compare_name);
672
673 /* sort the dissector handles in dissector tables (for -G reports
674 * and -d error messages. The GUI sorts the handles itself.) */
675 packet_all_tables_sort_handles();
676
677 /* We've assigned all the subtree type values; allocate the array
678 for them, and zero it out. */
679 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
)))
;
680}
681
682static void
683proto_cleanup_base(void)
684{
685 protocol_t *protocol;
686 header_field_info *hfinfo;
687
688 /* Free the abbrev/ID hash table */
689 if (gpa_name_map) {
690 // XXX - We don't have a wmem_map_destroy, but
691 // it does get cleaned up when epan scope is
692 // destroyed
693 //g_hash_table_destroy(gpa_name_map);
694 gpa_name_map = NULL((void*)0);
695 }
696 if (gpa_protocol_aliases) {
697 g_hash_table_destroy(gpa_protocol_aliases);
698 gpa_protocol_aliases = NULL((void*)0);
699 }
700 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)
;
701 last_field_name = NULL((void*)0);
702
703 while (protocols) {
704 protocol = (protocol_t *)protocols->data;
705 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", 705
, __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", 705, "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", 705, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
706 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", 706, "protocol->proto_id == hfinfo->id"
))))
;
707
708 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)
;
709 if (protocol->parent_proto_id != -1) {
710 // pino protocol
711 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 711, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
712 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"
, 712, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
713 } else {
714 if (protocol->fields) {
715 g_ptr_array_free(protocol->fields, true1);
716 }
717 g_list_free(protocol->heur_list);
718 }
719 protocols = g_list_remove(protocols, protocol);
720 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
721 }
722
723 if (proto_names) {
724 g_hash_table_destroy(proto_names);
725 proto_names = NULL((void*)0);
726 }
727
728 if (proto_short_names) {
729 g_hash_table_destroy(proto_short_names);
730 proto_short_names = NULL((void*)0);
731 }
732
733 if (proto_filter_names) {
734 g_hash_table_destroy(proto_filter_names);
735 proto_filter_names = NULL((void*)0);
736 }
737
738 if (proto_reserved_filter_names) {
739 g_hash_table_destroy(proto_reserved_filter_names);
740 proto_reserved_filter_names = NULL((void*)0);
741 }
742
743 if (gpa_hfinfo.allocated_len) {
744 gpa_hfinfo.len = 0;
745 gpa_hfinfo.allocated_len = 0;
746 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)
;
747 gpa_hfinfo.hfi = NULL((void*)0);
748 }
749
750 if (deregistered_fields) {
751 g_ptr_array_free(deregistered_fields, true1);
752 deregistered_fields = NULL((void*)0);
753 }
754
755 if (deregistered_data) {
756 g_ptr_array_free(deregistered_data, true1);
757 deregistered_data = NULL((void*)0);
758 }
759
760 if (deregistered_slice) {
761 g_ptr_array_free(deregistered_slice, true1);
762 deregistered_slice = NULL((void*)0);
763 }
764
765 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)
;
766 tree_is_expanded = NULL((void*)0);
767
768 if (prefixes)
769 g_hash_table_destroy(prefixes);
770
771 if (saved_dir_queue != NULL((void*)0)) {
772 g_queue_clear_full(saved_dir_queue, g_free);
773 g_queue_free(saved_dir_queue);
774 saved_dir_queue = NULL((void*)0);
775 }
776}
777
778void
779proto_cleanup(void)
780{
781 proto_free_deregistered_fields();
782 proto_cleanup_base();
783
784 g_slist_free(dissector_plugins);
785 dissector_plugins = NULL((void*)0);
786}
787
788static bool_Bool
789ws_pushd(const char* dir)
790{
791 //Save the current working directory
792 const char* save_wd = get_current_working_dir();
793 if (save_wd != NULL((void*)0))
794 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
795
796 //Change to the new one
797#ifdef _WIN32
798 SetCurrentDirectory(utf_8to16(dir));
799 return true1;
800#else
801 return (chdir(dir) == 0);
802#endif
803}
804
805static bool_Bool
806ws_popd(void)
807{
808 int ret = 0;
809 char* saved_wd = g_queue_pop_head(saved_dir_queue);
810 if (saved_wd == NULL((void*)0))
811 return false0;
812
813 //Restore the previous one
814#ifdef _WIN32
815 SetCurrentDirectory(utf_8to16(saved_wd));
816#else
817 ret = chdir(saved_wd);
818#endif
819 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)
;
820 return (ret == 0);
821}
822
823void
824proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
825{
826 if (ws_pushd(dir))
827 {
828 func(param);
829 ws_popd();
830 }
831}
832
833static bool_Bool
834// NOLINTNEXTLINE(misc-no-recursion)
835proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
836 void *data)
837{
838 proto_node *pnode = tree;
839 proto_node *child;
840 proto_node *current;
841
842 if (func(pnode, data))
843 return true1;
844
845 child = pnode->first_child;
846 while (child != NULL((void*)0)) {
847 /*
848 * The routine we call might modify the child, e.g. by
849 * freeing it, so we get the child's successor before
850 * calling that routine.
851 */
852 current = child;
853 child = current->next;
854 // We recurse here, but we're limited by prefs.gui_max_tree_depth
855 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
856 return true1;
857 }
858
859 return false0;
860}
861
862void
863proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
864 void *data)
865{
866 proto_node *node = tree;
867 proto_node *current;
868
869 if (!node)
870 return;
871
872 node = node->first_child;
873 while (node != NULL((void*)0)) {
874 current = node;
875 node = current->next;
876 func((proto_tree *)current, data);
877 }
878}
879
880static void
881free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
882{
883 GPtrArray *ptrs = (GPtrArray *)value;
884 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
885 header_field_info *hfinfo;
886
887 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", 887, __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", 887, "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", 887, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
888 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
889 /* when a field is referenced by a filter this also
890 affects the refcount for the parent protocol so we need
891 to adjust the refcount for the parent as well
892 */
893 if (hfinfo->parent != -1) {
894 header_field_info *parent_hfinfo;
895 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", 895
, __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", 895, "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", 895, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
896 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
897 }
898 hfinfo->ref_type = HF_REF_TYPE_NONE;
899 }
900
901 g_ptr_array_free(ptrs, true1);
902}
903
904static void
905proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
906{
907 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
908
909 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
910
911 if (finfo) {
912 fvalue_free(finfo->value);
913 finfo->value = NULL((void*)0);
914 }
915}
916
917void
918proto_tree_reset(proto_tree *tree)
919{
920 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
921
922 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
923
924 /* free tree data */
925 if (tree_data->interesting_hfids) {
926 /* Free all the GPtrArray's in the interesting_hfids hash. */
927 g_hash_table_foreach(tree_data->interesting_hfids,
928 free_GPtrArray_value, NULL((void*)0));
929
930 /* And then remove all values. */
931 g_hash_table_remove_all(tree_data->interesting_hfids);
932 }
933
934 /* Reset track of the number of children */
935 tree_data->count = 0;
936
937 /* Reset our loop checks */
938 tree_data->idle_count_ds_tvb = NULL((void*)0);
939 tree_data->max_start = 0;
940 tree_data->start_idle_count = 0;
941
942 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
943}
944
945/* frees the resources that the dissection a proto_tree uses */
946void
947proto_tree_free(proto_tree *tree)
948{
949 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
950
951 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
952
953 /* free tree data */
954 if (tree_data->interesting_hfids) {
955 /* Free all the GPtrArray's in the interesting_hfids hash. */
956 g_hash_table_foreach(tree_data->interesting_hfids,
957 free_GPtrArray_value, NULL((void*)0));
958
959 /* And then destroy the hash. */
960 g_hash_table_destroy(tree_data->interesting_hfids);
961 }
962
963 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)
;
964
965 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
966}
967
968/* Is the parsing being done for a visible proto_tree or an invisible one?
969 * By setting this correctly, the proto_tree creation is sped up by not
970 * having to call vsnprintf and copy strings around.
971 */
972bool_Bool
973proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
974{
975 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
976
977 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
978
979 return old_visible;
980}
981
982void
983proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
984{
985 if (tree)
986 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
987}
988
989/* Assume dissector set only its protocol fields.
990 This function is called by dissectors and allows the speeding up of filtering
991 in wireshark; if this function returns false it is safe to reset tree to NULL
992 and thus skip calling most of the expensive proto_tree_add_...()
993 functions.
994 If the tree is visible we implicitly assume the field is referenced.
995*/
996bool_Bool
997proto_field_is_referenced(proto_tree *tree, int proto_id)
998{
999 register header_field_info *hfinfo;
1000
1001
1002 if (!tree)
1003 return false0;
1004
1005 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1006 return true1;
1007
1008 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", 1008, __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", 1008,
"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", 1008, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1009 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1010 return true1;
1011
1012 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1013 return true1;
1014
1015 return false0;
1016}
1017
1018
1019/* Finds a record in the hfinfo array by id. */
1020header_field_info *
1021proto_registrar_get_nth(unsigned hfindex)
1022{
1023 register header_field_info *hfinfo;
1024
1025 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", 1025, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1025,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1025, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1026 return hfinfo;
1027}
1028
1029
1030/* Prefix initialization
1031 * this allows for a dissector to register a display filter name prefix
1032 * so that it can delay the initialization of the hf array as long as
1033 * possible.
1034 */
1035
1036/* compute a hash for the part before the dot of a display filter */
1037static unsigned
1038prefix_hash (const void *key) {
1039 /* end the string at the dot and compute its hash */
1040 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1041 char* c = copy;
1042 unsigned tmp;
1043
1044 for (; *c; c++) {
1045 if (*c == '.') {
1046 *c = 0;
1047 break;
1048 }
1049 }
1050
1051 tmp = wmem_str_hash(copy);
1052 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1053 return tmp;
1054}
1055
1056/* are both strings equal up to the end or the dot? */
1057static gboolean
1058prefix_equal (const void *ap, const void *bp) {
1059 const char* a = (const char *)ap;
1060 const char* b = (const char *)bp;
1061
1062 do {
1063 char ac = *a++;
1064 char bc = *b++;
1065
1066 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1067
1068 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1069 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1070
1071 if (ac != bc) return FALSE(0);
1072 } while (1);
1073
1074 return FALSE(0);
1075}
1076
1077/* Register a new prefix for "delayed" initialization of field arrays */
1078void
1079proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1080 if (! prefixes ) {
1081 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1082 }
1083
1084 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1085}
1086
1087/* helper to call all prefix initializers */
1088static gboolean
1089initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1090 ((prefix_initializer_t)v)((const char *)k);
1091 return TRUE(!(0));
1092}
1093
1094/** Initialize every remaining uninitialized prefix. */
1095void
1096proto_initialize_all_prefixes(void) {
1097 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1098}
1099
1100/* Finds a record in the hfinfo array by name.
1101 * If it fails to find it in the already registered fields,
1102 * it tries to find and call an initializer in the prefixes
1103 * table and if so it looks again.
1104 */
1105
1106header_field_info *
1107proto_registrar_get_byname(const char *field_name)
1108{
1109 header_field_info *hfinfo;
1110 prefix_initializer_t pi;
1111
1112 if (!field_name)
1113 return NULL((void*)0);
1114
1115 if (g_strcmp0(field_name, last_field_name) == 0) {
1116 return last_hfinfo;
1117 }
1118
1119 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1120
1121 if (hfinfo) {
1122 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)
;
1123 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1124 last_hfinfo = hfinfo;
1125 return hfinfo;
1126 }
1127
1128 if (!prefixes)
1129 return NULL((void*)0);
1130
1131 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1132 pi(field_name);
1133 g_hash_table_remove(prefixes, field_name);
1134 } else {
1135 return NULL((void*)0);
1136 }
1137
1138 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1139
1140 if (hfinfo) {
1141 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)
;
1142 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1143 last_hfinfo = hfinfo;
1144 }
1145 return hfinfo;
1146}
1147
1148header_field_info*
1149proto_registrar_get_byalias(const char *alias_name)
1150{
1151 if (!alias_name) {
1152 return NULL((void*)0);
1153 }
1154
1155 /* Find our aliased protocol. */
1156 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1157 char *dot = strchr(an_copy, '.');
1158 if (dot) {
1159 *dot = '\0';
1160 }
1161 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1162 if (!proto_pfx) {
1163 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)
;
1164 return NULL((void*)0);
1165 }
1166
1167 /* Construct our aliased field and look it up. */
1168 GString *filter_name = g_string_new(proto_pfx);
1169 if (dot) {
1170 g_string_append_printf(filter_name, ".%s", dot+1);
1171 }
1172 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1173 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)
;
1174 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)))))
;
1175
1176 return hfinfo;
1177}
1178
1179int
1180proto_registrar_get_id_byname(const char *field_name)
1181{
1182 header_field_info *hfinfo;
1183
1184 hfinfo = proto_registrar_get_byname(field_name);
1185
1186 if (!hfinfo)
1187 return -1;
1188
1189 return hfinfo->id;
1190}
1191
1192static int
1193label_strcat_flags(const header_field_info *hfinfo)
1194{
1195 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1196 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1197
1198 return 0;
1199}
1200
1201static char *
1202format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1203 const uint8_t *bytes, unsigned length, size_t max_str_len)
1204{
1205 char *str = NULL((void*)0);
1206 const uint8_t *p;
1207 bool_Bool is_printable;
1208
1209 if (bytes) {
1210 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1211 /*
1212 * If all bytes are valid and printable UTF-8, show the
1213 * bytes as a string - in quotes to indicate that it's
1214 * a string.
1215 */
1216 if (isprint_utf8_string((const char*)bytes, length)) {
1217 str = wmem_strdup_printf(scope, "\"%.*s\"",
1218 (int)length, bytes);
1219 return str;
1220 }
1221 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1222 /*
1223 * Check whether all bytes are printable.
1224 */
1225 is_printable = true1;
1226 for (p = bytes; p < bytes+length; p++) {
1227 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1228 /* Not printable. */
1229 is_printable = false0;
1230 break;
1231 }
1232 }
1233
1234 /*
1235 * If all bytes are printable ASCII, show the bytes
1236 * as a string - in quotes to indicate that it's
1237 * a string.
1238 */
1239 if (is_printable) {
1240 str = wmem_strdup_printf(scope, "\"%.*s\"",
1241 (int)length, bytes);
1242 return str;
1243 }
1244 }
1245
1246 /*
1247 * Either it's not printable ASCII, or we don't care whether
1248 * it's printable ASCII; show it as hex bytes.
1249 */
1250 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1251 case SEP_DOT:
1252 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1253 break;
1254 case SEP_DASH:
1255 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1256 break;
1257 case SEP_COLON:
1258 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1259 break;
1260 case SEP_SPACE:
1261 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1262 break;
1263 case BASE_NONE:
1264 default:
1265 if (prefs.display_byte_fields_with_spaces) {
1266 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1267 } else {
1268 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1269 }
1270 break;
1271 }
1272 }
1273 else {
1274 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1275 str = wmem_strdup(scope, "<none>");
1276 } else {
1277 str = wmem_strdup(scope, "<MISSING>");
1278 }
1279 }
1280 return str;
1281}
1282
1283static char *
1284format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1285 const uint8_t *bytes, unsigned length)
1286{
1287 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1288}
1289
1290static void
1291ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1292{
1293 subtree_lvl *pushed_tree;
1294
1295 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"
, 1295, "ptvc->pushed_tree_max <= 256-8"))))
;
1296 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1297
1298 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1299 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1299, "pushed_tree != ((void*)0)"
))))
;
1300 ptvc->pushed_tree = pushed_tree;
1301}
1302
1303static void
1304ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1305{
1306 ptvc->pushed_tree = NULL((void*)0);
1307 ptvc->pushed_tree_max = 0;
1308 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", 1308, "ptvc->pushed_tree_index == 0"
))))
;
1309 ptvc->pushed_tree_index = 0;
1310}
1311
1312/* Allocates an initializes a ptvcursor_t with 3 variables:
1313 * proto_tree, tvbuff, and offset. */
1314ptvcursor_t *
1315ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1316{
1317 ptvcursor_t *ptvc;
1318
1319 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1320 ptvc->scope = scope;
1321 ptvc->tree = tree;
1322 ptvc->tvb = tvb;
1323 ptvc->offset = offset;
1324 ptvc->pushed_tree = NULL((void*)0);
1325 ptvc->pushed_tree_max = 0;
1326 ptvc->pushed_tree_index = 0;
1327 return ptvc;
1328}
1329
1330
1331/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1332void
1333ptvcursor_free(ptvcursor_t *ptvc)
1334{
1335 ptvcursor_free_subtree_levels(ptvc);
1336 wmem_free(ptvc->scope, ptvc);
1337}
1338
1339/* Returns tvbuff. */
1340tvbuff_t *
1341ptvcursor_tvbuff(ptvcursor_t *ptvc)
1342{
1343 return ptvc->tvb;
1344}
1345
1346/* Returns current offset. */
1347unsigned
1348ptvcursor_current_offset(ptvcursor_t *ptvc)
1349{
1350 return ptvc->offset;
1351}
1352
1353proto_tree *
1354ptvcursor_tree(ptvcursor_t *ptvc)
1355{
1356 if (!ptvc)
1357 return NULL((void*)0);
1358
1359 return ptvc->tree;
1360}
1361
1362void
1363ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1364{
1365 ptvc->tree = tree;
1366}
1367
1368/* creates a subtree, sets it as the working tree and pushes the old working tree */
1369proto_tree *
1370ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1371{
1372 subtree_lvl *subtree;
1373 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1374 ptvcursor_new_subtree_levels(ptvc);
1375
1376 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1377 subtree->tree = ptvc->tree;
1378 subtree->it= NULL((void*)0);
1379 ptvc->pushed_tree_index++;
1380 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1381}
1382
1383/* pops a subtree */
1384void
1385ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1386{
1387 subtree_lvl *subtree;
1388
1389 if (ptvc->pushed_tree_index <= 0)
1390 return;
1391
1392 ptvc->pushed_tree_index--;
1393 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1394 if (subtree->it != NULL((void*)0))
1395 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1396
1397 ptvc->tree = subtree->tree;
1398}
1399
1400/* saves the current tvb offset and the item in the current subtree level */
1401static void
1402ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1403{
1404 subtree_lvl *subtree;
1405
1406 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", 1406, "ptvc->pushed_tree_index > 0"
))))
;
1407
1408 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1409 subtree->it = it;
1410 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1411}
1412
1413/* Creates a subtree and adds it to the cursor as the working tree but does not
1414 * save the old working tree */
1415proto_tree *
1416ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1417{
1418 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1419 return ptvc->tree;
1420}
1421
1422static proto_tree *
1423ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1424{
1425 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1426 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1427 ptvcursor_subtree_set_item(ptvc, it);
1428 return ptvcursor_tree(ptvc);
1429}
1430
1431/* Add an item to the tree and create a subtree
1432 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1433 * In this case, when the subtree will be closed, the parent item length will
1434 * be equal to the advancement of the cursor since the creation of the subtree.
1435 */
1436proto_tree *
1437ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1438 const unsigned encoding, int ett_subtree)
1439{
1440 proto_item *it;
1441
1442 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1443 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1444}
1445
1446static proto_item *
1447proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1448
1449/* Add a text node 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 item length will be equal
1452 * to the advancement of the cursor since the creation of the subtree.
1453 */
1454proto_tree *
1455ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1456 int ett_subtree, const char *format, ...)
1457{
1458 proto_item *pi;
1459 va_list ap;
1460 header_field_info *hfinfo;
1461 proto_tree *tree;
1462
1463 tree = ptvcursor_tree(ptvc);
1464
1465 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1466
1467 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", 1467
, __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", 1467, "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", 1467, "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", 1467, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1468
1469 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1470 ptvcursor_current_offset(ptvc), length);
1471
1472 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1472, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1473
1474 va_start(ap, format)__builtin_va_start(ap, format);
1475 proto_tree_set_representation(pi, format, ap);
1476 va_end(ap)__builtin_va_end(ap);
1477
1478 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1479}
1480
1481/* Add a text-only node, leaving it to our caller to fill the text in */
1482static proto_item *
1483proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1484{
1485 proto_item *pi;
1486
1487 if (tree == NULL((void*)0))
1488 return NULL((void*)0);
1489
1490 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1491
1492 return pi;
1493}
1494
1495/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1496proto_item *
1497proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length,
1498 const char *format, ...)
1499{
1500 proto_item *pi;
1501 va_list ap;
1502 header_field_info *hfinfo;
1503
1504 if (length == -1) {
1505 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1506 } else {
1507 tvb_ensure_bytes_exist(tvb, start, length);
1508 }
1509
1510 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1511
1512 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", 1512
, __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", 1512, "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", 1512, "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", 1512, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1513
1514 pi = proto_tree_add_text_node(tree, tvb, start, length);
1515
1516 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1516, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1517
1518 va_start(ap, format)__builtin_va_start(ap, format);
1519 proto_tree_set_representation(pi, format, ap);
1520 va_end(ap)__builtin_va_end(ap);
1521
1522 return pi;
1523}
1524
1525/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1526proto_item *
1527proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1528 int length, const char *format, va_list ap)
1529{
1530 proto_item *pi;
1531 header_field_info *hfinfo;
1532
1533 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1534 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1535 * the length to be what's in the tvbuff if length is -1, and the
1536 * minimum of length and what's in the tvbuff if not.
1537 */
1538
1539 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1540
1541 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", 1541
, __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", 1541, "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", 1541, "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", 1541, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1542
1543 pi = proto_tree_add_text_node(tree, tvb, start, length);
1544
1545 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1545, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1546
1547 proto_tree_set_representation(pi, format, ap);
1548
1549 return pi;
1550}
1551
1552/* Add a text-only node that creates a subtree underneath.
1553 */
1554proto_tree *
1555proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1556{
1557 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1558}
1559
1560/* Add a text-only node that creates a subtree underneath.
1561 */
1562proto_tree *
1563proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1564{
1565 proto_tree *pt;
1566 proto_item *pi;
1567 va_list ap;
1568
1569 va_start(ap, format)__builtin_va_start(ap, format);
1570 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1571 va_end(ap)__builtin_va_end(ap);
1572
1573 if (tree_item != NULL((void*)0))
1574 *tree_item = pi;
1575
1576 pt = proto_item_add_subtree(pi, idx);
1577
1578 return pt;
1579}
1580
1581/* Add a text-only node for debugging purposes. The caller doesn't need
1582 * to worry about tvbuff, start, or length. Debug message gets sent to
1583 * STDOUT, too */
1584proto_item *
1585proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1586{
1587 proto_item *pi;
1588 va_list ap;
1589
1590 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1591
1592 if (pi) {
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 proto_tree_set_representation(pi, format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 }
1597 va_start(ap, format)__builtin_va_start(ap, format);
1598 vprintf(format, ap);
1599 va_end(ap)__builtin_va_end(ap);
1600 printf("\n");
1601
1602 return pi;
1603}
1604
1605proto_item *
1606proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1607{
1608 proto_item *pi;
1609 header_field_info *hfinfo;
1610
1611 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1612
1613 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", 1613
, __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", 1613, "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", 1613, "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", 1613, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1614
1615 pi = proto_tree_add_text_node(tree, tvb, start, length);
1616
1617 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1617, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1618
1619 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1620
1621 return pi;
1622}
1623
1624proto_item *
1625proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1626{
1627 proto_item *pi;
1628 header_field_info *hfinfo;
1629 char *str;
1630
1631 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1632
1633 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", 1633
, __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", 1633, "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", 1633, "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", 1633, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1634
1635 pi = proto_tree_add_text_node(tree, tvb, start, length);
1636
1637 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1637, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1638
1639 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1640 proto_item_set_text(pi, "%s", str);
1641 wmem_free(NULL((void*)0), str);
1642
1643 return pi;
1644}
1645
1646void proto_report_dissector_bug(const char *format, ...)
1647{
1648 va_list args;
1649
1650 if (wireshark_abort_on_dissector_bug) {
1651 /*
1652 * Try to have the error message show up in the crash
1653 * information.
1654 */
1655 va_start(args, format)__builtin_va_start(args, format);
1656 ws_vadd_crash_info(format, args);
1657 va_end(args)__builtin_va_end(args);
1658
1659 /*
1660 * Print the error message.
1661 */
1662 va_start(args, format)__builtin_va_start(args, format);
1663 vfprintf(stderrstderr, format, args);
1664 va_end(args)__builtin_va_end(args);
1665 putc('\n', stderrstderr);
1666
1667 /*
1668 * And crash.
1669 */
1670 abort();
1671 } else {
1672 va_start(args, format)__builtin_va_start(args, format);
1673 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1674 va_end(args)__builtin_va_end(args);
1675 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1675
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1676 }
1677}
1678
1679/* We could probably get away with changing is_error to a minimum length value. */
1680static void
1681report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1682{
1683 if (is_error) {
1684 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1685 } else {
1686 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1687 }
1688
1689 if (is_error) {
1690 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1691 }
1692}
1693
1694static uint32_t
1695get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1696{
1697 uint32_t value;
1698 bool_Bool length_error;
1699
1700 switch (length) {
1701
1702 case 1:
1703 value = tvb_get_uint8(tvb, offset);
1704 if (encoding & ENC_ZIGBEE0x40000000) {
1705 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1706 value = 0;
1707 }
1708 }
1709 break;
1710
1711 case 2:
1712 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1713 : tvb_get_ntohs(tvb, offset);
1714 if (encoding & ENC_ZIGBEE0x40000000) {
1715 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1716 value = 0;
1717 }
1718 }
1719 break;
1720
1721 case 3:
1722 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1723 : tvb_get_ntoh24(tvb, offset);
1724 break;
1725
1726 case 4:
1727 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1728 : tvb_get_ntohl(tvb, offset);
1729 break;
1730
1731 default:
1732 if (length < 1) {
1733 length_error = true1;
1734 value = 0;
1735 } else {
1736 length_error = false0;
1737 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1738 : tvb_get_ntohl(tvb, offset);
1739 }
1740 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1741 break;
1742 }
1743 return value;
1744}
1745
1746static inline uint64_t
1747get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1748{
1749 uint64_t value;
1750
1751 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1752
1753 if (length < 1 || length > 8) {
1754 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1755 }
1756
1757 return value;
1758}
1759
1760static int32_t
1761get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1762{
1763 int32_t value;
1764 bool_Bool length_error;
1765
1766 switch (length) {
1767
1768 case 1:
1769 value = tvb_get_int8(tvb, offset);
1770 break;
1771
1772 case 2:
1773 value = encoding ? tvb_get_letohis(tvb, offset)
1774 : tvb_get_ntohis(tvb, offset);
1775 break;
1776
1777 case 3:
1778 value = encoding ? tvb_get_letohi24(tvb, offset)
1779 : tvb_get_ntohi24(tvb, offset);
1780 break;
1781
1782 case 4:
1783 value = encoding ? tvb_get_letohil(tvb, offset)
1784 : tvb_get_ntohil(tvb, offset);
1785 break;
1786
1787 default:
1788 if (length < 1) {
1789 length_error = true1;
1790 value = 0;
1791 } else {
1792 length_error = false0;
1793 value = encoding ? tvb_get_letohil(tvb, offset)
1794 : tvb_get_ntohil(tvb, offset);
1795 }
1796 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1797 break;
1798 }
1799 return value;
1800}
1801
1802/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1803 * be cast-able as a int64_t. This is weird, but what the code has always done.
1804 */
1805static inline uint64_t
1806get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1807{
1808 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1809
1810 switch (length) {
1811 case 7:
1812 value = ws_sign_ext64(value, 56);
1813 break;
1814 case 6:
1815 value = ws_sign_ext64(value, 48);
1816 break;
1817 case 5:
1818 value = ws_sign_ext64(value, 40);
1819 break;
1820 case 4:
1821 value = ws_sign_ext64(value, 32);
1822 break;
1823 case 3:
1824 value = ws_sign_ext64(value, 24);
1825 break;
1826 case 2:
1827 value = ws_sign_ext64(value, 16);
1828 break;
1829 case 1:
1830 value = ws_sign_ext64(value, 8);
1831 break;
1832 }
1833
1834 return value;
1835}
1836
1837/* For FT_STRING */
1838static inline const uint8_t *
1839get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1840 int length, int *ret_length, const unsigned encoding)
1841{
1842 if (length == -1) {
1843 length = tvb_ensure_captured_length_remaining(tvb, start);
1844 }
1845 *ret_length = length;
1846 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1847}
1848
1849/* For FT_STRINGZ */
1850static inline const uint8_t *
1851get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1852 unsigned start, int length, int *ret_length, const unsigned encoding)
1853{
1854 const uint8_t *value;
1855
1856 if (length < -1) {
1857 report_type_length_mismatch(tree, "a string", length, true1);
1858 }
1859
1860 /* XXX - Ideally, every "null-terminated string which fits into a
1861 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1862 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1863 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1864 * as unknown length as well (since there is a trailing '\0', the real
1865 * length is never zero), allowing switching to unsigned lengths.
1866 */
1867 if (length == -1) {
1868 /* This can throw an exception */
1869 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1870 } else {
1871 /* In this case, length signifies the length of the string.
1872 *
1873 * This could either be a null-padded string, which doesn't
1874 * necessarily have a '\0' at the end, or a null-terminated
1875 * string, with a trailing '\0'. (Yes, there are cases
1876 * where you have a string that's both counted and null-
1877 * terminated.)
1878 *
1879 * In the first case, we must allocate a buffer of length
1880 * "length+1", to make room for a trailing '\0'.
1881 *
1882 * In the second case, we don't assume that there is a
1883 * trailing '\0' there, as the packet might be malformed.
1884 * (XXX - should we throw an exception if there's no
1885 * trailing '\0'?) Therefore, we allocate a buffer of
1886 * length "length+1", and put in a trailing '\0', just to
1887 * be safe.
1888 *
1889 * (XXX - this would change if we made string values counted
1890 * rather than null-terminated.)
1891 */
1892 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1893 }
1894 *ret_length = length;
1895 return value;
1896}
1897
1898/* For FT_UINT_STRING */
1899static inline const uint8_t *
1900get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1901 tvbuff_t *tvb, unsigned start, int length, int *ret_length,
1902 const unsigned encoding)
1903{
1904 uint32_t n;
1905 const uint8_t *value;
1906
1907 /* I believe it's ok if this is called with a NULL tree */
1908 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1909 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1910 length += n;
1911 *ret_length = length;
1912 return value;
1913}
1914
1915/* For FT_STRINGZPAD */
1916static inline const uint8_t *
1917get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1918 int length, int *ret_length, const unsigned encoding)
1919{
1920 /*
1921 * XXX - currently, string values are null-
1922 * terminated, so a "zero-padded" string
1923 * isn't special. If we represent string
1924 * values as something that includes a counted
1925 * array of bytes, we'll need to strip the
1926 * trailing NULs.
1927 */
1928 if (length == -1) {
1929 length = tvb_ensure_captured_length_remaining(tvb, start);
1930 }
1931 *ret_length = length;
1932 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1933}
1934
1935/* For FT_STRINGZTRUNC */
1936static inline const uint8_t *
1937get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1938 int length, int *ret_length, const unsigned encoding)
1939{
1940 /*
1941 * XXX - currently, string values are null-
1942 * terminated, so a "zero-truncated" string
1943 * isn't special. If we represent string
1944 * values as something that includes a counted
1945 * array of bytes, we'll need to strip everything
1946 * starting with the terminating NUL.
1947 */
1948 if (length == -1) {
1949 length = tvb_ensure_captured_length_remaining(tvb, start);
1950 }
1951 *ret_length = length;
1952 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1953}
1954
1955/*
1956 * Deltas between the epochs for various non-UN*X time stamp formats and
1957 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1958 * stamp format.
1959 */
1960
1961/*
1962 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1963 * XXX - if it's OK if this is unsigned, can we just use
1964 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1965 */
1966#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1967
1968/*
1969 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1970 */
1971#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1972
1973/* this can be called when there is no tree, so tree may be null */
1974static void
1975get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1976 const int length, const unsigned encoding, nstime_t *time_stamp,
1977 const bool_Bool is_relative)
1978{
1979 uint32_t tmpsecs;
1980 uint64_t tmp64secs;
1981 uint64_t todusecs;
1982
1983 switch (encoding) {
1984
1985 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1986 /*
1987 * If the length is 16, 8-byte seconds, followed
1988 * by 8-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 12, 8-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * If the length is 8, 4-byte seconds, followed
1996 * by 4-byte fractional time in nanoseconds,
1997 * both big-endian.
1998 *
1999 * For absolute times, the seconds are seconds
2000 * since the UN*X epoch.
2001 */
2002 if (length == 16) {
2003 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2004 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2005 } else if (length == 12) {
2006 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2007 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2008 } else if (length == 8) {
2009 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2010 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2011 } else if (length == 4) {
2012 /*
2013 * Backwards compatibility.
2014 * ENC_TIME_SECS_NSECS is 0; using
2015 * ENC_BIG_ENDIAN by itself with a 4-byte
2016 * time-in-seconds value was done in the
2017 * past.
2018 */
2019 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2020 time_stamp->nsecs = 0;
2021 } else {
2022 time_stamp->secs = 0;
2023 time_stamp->nsecs = 0;
2024 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2025 }
2026 break;
2027
2028 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2029 /*
2030 * If the length is 16, 8-byte seconds, followed
2031 * by 8-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 12, 8-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * If the length is 8, 4-byte seconds, followed
2039 * by 4-byte fractional time in nanoseconds,
2040 * both little-endian.
2041 *
2042 * For absolute times, the seconds are seconds
2043 * since the UN*X epoch.
2044 */
2045 if (length == 16) {
2046 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2047 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2048 } else if (length == 12) {
2049 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2050 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2051 } else if (length == 8) {
2052 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2053 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2054 } else if (length == 4) {
2055 /*
2056 * Backwards compatibility.
2057 * ENC_TIME_SECS_NSECS is 0; using
2058 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2059 * time-in-seconds value was done in the
2060 * past.
2061 */
2062 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2063 time_stamp->nsecs = 0;
2064 } else {
2065 time_stamp->secs = 0;
2066 time_stamp->nsecs = 0;
2067 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2068 }
2069 break;
2070
2071 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2072 /*
2073 * NTP time stamp, big-endian.
2074 * Only supported for absolute times.
2075 */
2076 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2076, "!is_relative"
))))
;
2077
2078 /* We need a temporary variable here so the unsigned math
2079 * works correctly (for years > 2036 according to RFC 2030
2080 * chapter 3).
2081 *
2082 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2083 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2084 * If bit 0 is not set, the time is in the range 2036-2104 and
2085 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2086 */
2087 tmpsecs = tvb_get_ntohl(tvb, start);
2088 if ((tmpsecs & 0x80000000) != 0)
2089 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2090 else
2091 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2092
2093 if (length == 8) {
2094 tmp64secs = tvb_get_ntoh64(tvb, start);
2095 if (tmp64secs == 0) {
2096 //This is "NULL" time
2097 time_stamp->secs = 0;
2098 time_stamp->nsecs = 0;
2099 } else {
2100 /*
2101 * Convert 1/2^32s of a second to
2102 * nanoseconds.
2103 */
2104 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2105 }
2106 } else if (length == 4) {
2107 /*
2108 * Backwards compatibility.
2109 */
2110 if (tmpsecs == 0) {
2111 //This is "NULL" time
2112 time_stamp->secs = 0;
2113 }
2114 time_stamp->nsecs = 0;
2115 } else {
2116 time_stamp->secs = 0;
2117 time_stamp->nsecs = 0;
2118 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2119 }
2120 break;
2121
2122 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2123 /*
2124 * NTP time stamp, little-endian.
2125 * Only supported for absolute times.
2126 *
2127 * NTP doesn't use this, because it's an Internet format
2128 * and hence big-endian. Any implementation must decide
2129 * whether the NTP timestamp is a 64-bit unsigned fixed
2130 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2131 * with a 32-bit unsigned seconds field followed by a
2132 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2133 * the previous two).
2134 *
2135 * XXX: We do the latter, but no dissector uses this format.
2136 * OTOH, ERF timestamps do the former, so perhaps we
2137 * should switch the interpretation so that packet-erf.c
2138 * could use this directly?
2139 */
2140 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2140, "!is_relative"
))))
;
2141
2142 /* We need a temporary variable here so the unsigned math
2143 * works correctly (for years > 2036 according to RFC 2030
2144 * chapter 3).
2145 *
2146 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2147 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2148 * If bit 0 is not set, the time is in the range 2036-2104 and
2149 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2150 */
2151 tmpsecs = tvb_get_letohl(tvb, start);
2152 if ((tmpsecs & 0x80000000) != 0)
2153 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2154 else
2155 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2156
2157 if (length == 8) {
2158 tmp64secs = tvb_get_letoh64(tvb, start);
2159 if (tmp64secs == 0) {
2160 //This is "NULL" time
2161 time_stamp->secs = 0;
2162 time_stamp->nsecs = 0;
2163 } else {
2164 /*
2165 * Convert 1/2^32s of a second to
2166 * nanoseconds.
2167 */
2168 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2169 }
2170 } else if (length == 4) {
2171 /*
2172 * Backwards compatibility.
2173 */
2174 if (tmpsecs == 0) {
2175 //This is "NULL" time
2176 time_stamp->secs = 0;
2177 }
2178 time_stamp->nsecs = 0;
2179 } else {
2180 time_stamp->secs = 0;
2181 time_stamp->nsecs = 0;
2182 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2183 }
2184 break;
2185
2186 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2187 /*
2188 * S/3x0 and z/Architecture TOD clock time stamp,
2189 * big-endian. The epoch is January 1, 1900,
2190 * 00:00:00 (proleptic?) UTC.
2191 *
2192 * Only supported for absolute times.
2193 */
2194 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2194, "!is_relative"
))))
;
2195 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2195, "length == 8"
))))
;
2196
2197 if (length == 8) {
2198 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2199 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2200 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2201 } else {
2202 time_stamp->secs = 0;
2203 time_stamp->nsecs = 0;
2204 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2205 }
2206 break;
2207
2208 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2209 /*
2210 * S/3x0 and z/Architecture TOD clock time stamp,
2211 * little-endian. The epoch is January 1, 1900,
2212 * 00:00:00 (proleptic?) UTC.
2213 *
2214 * Only supported for absolute times.
2215 */
2216 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2216, "!is_relative"
))))
;
2217
2218 if (length == 8) {
2219 todusecs = tvb_get_letoh64(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_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2230 /*
2231 * Time stamp using the same seconds/fraction format
2232 * as NTP, but with the origin of the time stamp being
2233 * the UNIX epoch rather than the NTP epoch; big-
2234 * endian.
2235 *
2236 * Only supported for absolute times.
2237 */
2238 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2238, "!is_relative"
))))
;
2239
2240 if (length == 8) {
2241 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2242 /*
2243 * Convert 1/2^32s of a second to nanoseconds.
2244 */
2245 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2246 } else {
2247 time_stamp->secs = 0;
2248 time_stamp->nsecs = 0;
2249 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2250 }
2251 break;
2252
2253 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2254 /*
2255 * Time stamp using the same seconds/fraction format
2256 * as NTP, but with the origin of the time stamp being
2257 * the UNIX epoch rather than the NTP epoch; little-
2258 * endian.
2259 *
2260 * Only supported for absolute times.
2261 *
2262 * The RTPS specification explicitly supports Little
2263 * Endian encoding. In one place, it states that its
2264 * Time_t representation "is the one defined by ...
2265 * RFC 1305", but in another explicitly defines it as
2266 * a struct consisting of an 32 bit unsigned seconds
2267 * field and a 32 bit unsigned fraction field, not a 64
2268 * bit fixed point, so we do that here.
2269 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2270 */
2271 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2271, "!is_relative"
))))
;
2272
2273 if (length == 8) {
2274 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2275 /*
2276 * Convert 1/2^32s of a second to nanoseconds.
2277 */
2278 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2279 } else {
2280 time_stamp->secs = 0;
2281 time_stamp->nsecs = 0;
2282 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2283 }
2284 break;
2285
2286 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2287 /*
2288 * MIP6 time stamp, big-endian.
2289 * A 64-bit unsigned integer field containing a timestamp. The
2290 * value indicates the number of seconds since January 1, 1970,
2291 * 00:00 UTC, by using a fixed point format. In this format, the
2292 * integer number of seconds is contained in the first 48 bits of
2293 * the field, and the remaining 16 bits indicate the number of
2294 * 1/65536 fractions of a second.
2295
2296 * Only supported for absolute times.
2297 */
2298 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2298, "!is_relative"
))))
;
2299
2300 if (length == 8) {
2301 /* We need a temporary variable here so the casting and fractions
2302 * of a second work correctly.
2303 */
2304 tmp64secs = tvb_get_ntoh48(tvb, start);
2305 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2306 tmpsecs <<= 16;
2307
2308 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2309 //This is "NULL" time
2310 time_stamp->secs = 0;
2311 time_stamp->nsecs = 0;
2312 } else {
2313 time_stamp->secs = (time_t)tmp64secs;
2314 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2315 }
2316 } else {
2317 time_stamp->secs = 0;
2318 time_stamp->nsecs = 0;
2319 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2320 }
2321 break;
2322
2323 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2324 /*
2325 * If the length is 16, 8-byte seconds, followed
2326 * by 8-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 12, 8-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * If the length is 8, 4-byte seconds, followed
2334 * by 4-byte fractional time in microseconds,
2335 * both big-endian.
2336 *
2337 * For absolute times, the seconds are seconds
2338 * since the UN*X epoch.
2339 */
2340 if (length == 16) {
2341 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2342 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2343 } else if (length == 12) {
2344 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2345 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2346 } else if (length == 8) {
2347 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2348 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2349 } else {
2350 time_stamp->secs = 0;
2351 time_stamp->nsecs = 0;
2352 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2353 }
2354 break;
2355
2356 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2357 /*
2358 * If the length is 16, 8-byte seconds, followed
2359 * by 8-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 12, 8-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * If the length is 8, 4-byte seconds, followed
2367 * by 4-byte fractional time in microseconds,
2368 * both little-endian.
2369 *
2370 * For absolute times, the seconds are seconds
2371 * since the UN*X epoch.
2372 */
2373 if (length == 16) {
2374 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2375 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2376 } else if (length == 12) {
2377 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2378 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2379 } else if (length == 8) {
2380 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2381 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2382 } else {
2383 time_stamp->secs = 0;
2384 time_stamp->nsecs = 0;
2385 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2386 }
2387 break;
2388
2389 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2390 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2391 /*
2392 * Seconds, 1 to 8 bytes.
2393 * For absolute times, it's seconds since the
2394 * UN*X epoch.
2395 */
2396 if (length >= 1 && length <= 8) {
2397 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2398 time_stamp->nsecs = 0;
2399 } else {
2400 time_stamp->secs = 0;
2401 time_stamp->nsecs = 0;
2402 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2403 }
2404 break;
2405
2406 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2407 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2408 /*
2409 * Milliseconds, 1 to 8 bytes.
2410 * For absolute times, it's milliseconds since the
2411 * UN*X epoch.
2412 */
2413 if (length >= 1 && length <= 8) {
2414 uint64_t msecs;
2415
2416 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2417 time_stamp->secs = (time_t)(msecs / 1000);
2418 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2419 } else {
2420 time_stamp->secs = 0;
2421 time_stamp->nsecs = 0;
2422 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2423 }
2424 break;
2425
2426 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2427 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2428 /*
2429 * Microseconds, 1 to 8 bytes.
2430 * For absolute times, it's microseconds since the
2431 * UN*X epoch.
2432 */
2433 if (length >= 1 && length <= 8) {
2434 uint64_t usecs;
2435
2436 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2437 time_stamp->secs = (time_t)(usecs / 1000000);
2438 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2439 } else {
2440 time_stamp->secs = 0;
2441 time_stamp->nsecs = 0;
2442 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2443 }
2444 break;
2445
2446 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2447 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2448 /*
2449 * nanoseconds, 1 to 8 bytes.
2450 * For absolute times, it's nanoseconds since the
2451 * UN*X epoch.
2452 */
2453
2454 if (length >= 1 && length <= 8) {
2455 uint64_t nsecs;
2456
2457 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2458 time_stamp->secs = (time_t)(nsecs / 1000000000);
2459 time_stamp->nsecs = (int)(nsecs % 1000000000);
2460 } else {
2461 time_stamp->secs = 0;
2462 time_stamp->nsecs = 0;
2463 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2464 }
2465 break;
2466
2467 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2468 /*
2469 * 1/64ths of a second since the UN*X epoch,
2470 * big-endian.
2471 *
2472 * Only supported for absolute times.
2473 */
2474 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2474, "!is_relative"
))))
;
2475
2476 if (length == 8) {
2477 /*
2478 * The upper 48 bits are seconds since the
2479 * UN*X epoch.
2480 */
2481 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2482 /*
2483 * The lower 16 bits are 1/2^16s of a second;
2484 * convert them to nanoseconds.
2485 *
2486 * XXX - this may give the impression of higher
2487 * precision than you actually get.
2488 */
2489 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2490 } else {
2491 time_stamp->secs = 0;
2492 time_stamp->nsecs = 0;
2493 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2494 }
2495 break;
2496
2497 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2498 /*
2499 * 1/64ths of a second since the UN*X epoch,
2500 * little-endian.
2501 *
2502 * Only supported for absolute times.
2503 */
2504 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2504, "!is_relative"
))))
;
2505
2506 if (length == 8) {
2507 /*
2508 * XXX - this is assuming that, if anybody
2509 * were ever to use this format - RFC 3971
2510 * doesn't, because that's an Internet
2511 * protocol, and those use network byte
2512 * order, i.e. big-endian - they'd treat it
2513 * as a 64-bit count of 1/2^16s of a second,
2514 * putting the upper 48 bits at the end.
2515 *
2516 * The lower 48 bits are seconds since the
2517 * UN*X epoch.
2518 */
2519 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2520 /*
2521 * The upper 16 bits are 1/2^16s of a second;
2522 * convert them to nanoseconds.
2523 *
2524 * XXX - this may give the impression of higher
2525 * precision than you actually get.
2526 */
2527 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2528 } else {
2529 time_stamp->secs = 0;
2530 time_stamp->nsecs = 0;
2531 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2532 }
2533 break;
2534
2535 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2536 /*
2537 * NTP time stamp, with 1-second resolution (i.e.,
2538 * seconds since the NTP epoch), big-endian.
2539 * Only supported for absolute times.
2540 */
2541 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2541, "!is_relative"
))))
;
2542
2543 if (length == 4) {
2544 /*
2545 * We need a temporary variable here so the unsigned math
2546 * works correctly (for years > 2036 according to RFC 2030
2547 * chapter 3).
2548 *
2549 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2550 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2551 * If bit 0 is not set, the time is in the range 2036-2104 and
2552 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2553 */
2554 tmpsecs = tvb_get_ntohl(tvb, start);
2555 if ((tmpsecs & 0x80000000) != 0)
2556 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2557 else
2558 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2559 time_stamp->nsecs = 0;
2560 } else {
2561 time_stamp->secs = 0;
2562 time_stamp->nsecs = 0;
2563 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2564 }
2565 break;
2566
2567 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2568 /*
2569 * NTP time stamp, with 1-second resolution (i.e.,
2570 * seconds since the NTP epoch), little-endian.
2571 * Only supported for absolute times.
2572 */
2573 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2573, "!is_relative"
))))
;
2574
2575 /*
2576 * We need a temporary variable here so the unsigned math
2577 * works correctly (for years > 2036 according to RFC 2030
2578 * chapter 3).
2579 *
2580 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2581 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2582 * If bit 0 is not set, the time is in the range 2036-2104 and
2583 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2584 */
2585 if (length == 4) {
2586 tmpsecs = tvb_get_letohl(tvb, start);
2587 if ((tmpsecs & 0x80000000) != 0)
2588 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2589 else
2590 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2591 time_stamp->nsecs = 0;
2592 } else {
2593 time_stamp->secs = 0;
2594 time_stamp->nsecs = 0;
2595 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2596 }
2597 break;
2598
2599 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2600 /*
2601 * Milliseconds, 6 to 8 bytes.
2602 * For absolute times, it's milliseconds since the
2603 * NTP epoch.
2604 *
2605 * ETSI TS 129.274 8.119 defines this as:
2606 * "a 48 bit unsigned integer in network order format
2607 * ...encoded as the number of milliseconds since
2608 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2609 * rounded value of 1000 x the value of the 64-bit
2610 * timestamp (Seconds + (Fraction / (1<<32))) defined
2611 * in clause 6 of IETF RFC 5905."
2612 *
2613 * Taken literally, the part after "i.e." would
2614 * mean that the value rolls over before reaching
2615 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2616 * when the 64 bit timestamp rolls over, and we have
2617 * to pick an NTP Era equivalence class to support
2618 * (such as 1968-01-20 to 2104-02-06).
2619 *
2620 * OTOH, the extra room might be used to store Era
2621 * information instead, in which case times until
2622 * 10819-08-03 can be represented with 6 bytes without
2623 * ambiguity. We handle both implementations, and assume
2624 * that times before 1968-01-20 are not represented.
2625 *
2626 * Only 6 bytes or more makes sense as an absolute
2627 * time. 5 bytes or fewer could express a span of
2628 * less than 35 years, either 1900-1934 or 2036-2070.
2629 */
2630 if (length >= 6 && length <= 8) {
2631 uint64_t msecs;
2632
2633 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2634 tmp64secs = (msecs / 1000);
2635 /*
2636 * Assume that times in the first half of NTP
2637 * Era 0 really represent times in the NTP
2638 * Era 1.
2639 */
2640 if (tmp64secs >= 0x80000000)
2641 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2642 else
2643 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2644 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2645 }
2646 else {
2647 time_stamp->secs = 0;
2648 time_stamp->nsecs = 0;
2649 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2650 }
2651 break;
2652
2653 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2654 /*
2655 * MP4 file time stamps, big-endian.
2656 * Only supported for absolute times.
2657 */
2658 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2658, "!is_relative"
))))
;
2659
2660 if (length == 8) {
2661 tmp64secs = tvb_get_ntoh64(tvb, start);
2662 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else if (length == 4) {
2665 tmpsecs = tvb_get_ntohl(tvb, start);
2666 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2667 time_stamp->nsecs = 0;
2668 } else {
2669 time_stamp->secs = 0;
2670 time_stamp->nsecs = 0;
2671 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2672 }
2673 break;
2674
2675 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2676 /*
2677 * Zigbee ZCL time stamps, big-endian.
2678 * Only supported for absolute times.
2679 */
2680 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2680, "!is_relative"
))))
;
2681
2682 if (length == 8) {
2683 tmp64secs = tvb_get_ntoh64(tvb, start);
2684 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 time_stamp->nsecs = 0;
2686 } else if (length == 4) {
2687 tmpsecs = tvb_get_ntohl(tvb, start);
2688 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2689 time_stamp->nsecs = 0;
2690 } else {
2691 time_stamp->secs = 0;
2692 time_stamp->nsecs = 0;
2693 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2694 }
2695 break;
2696
2697 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2698 /*
2699 * Zigbee ZCL time stamps, little-endian.
2700 * Only supported for absolute times.
2701 */
2702 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2702, "!is_relative"
))))
;
2703
2704 if (length == 8) {
2705 tmp64secs = tvb_get_letoh64(tvb, start);
2706 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 time_stamp->nsecs = 0;
2708 } else if (length == 4) {
2709 tmpsecs = tvb_get_letohl(tvb, start);
2710 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2711 time_stamp->nsecs = 0;
2712 } else {
2713 time_stamp->secs = 0;
2714 time_stamp->nsecs = 0;
2715 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2716 }
2717 break;
2718
2719 default:
2720 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2720))
;
2721 break;
2722 }
2723}
2724
2725static void
2726tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2727{
2728 const header_field_info *hfinfo = fi->hfinfo;
2729
2730 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2731 GPtrArray *ptrs = NULL((void*)0);
2732
2733 if (tree_data->interesting_hfids == NULL((void*)0)) {
2734 /* Initialize the hash because we now know that it is needed */
2735 tree_data->interesting_hfids =
2736 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2737 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2738 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2739 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2740 }
2741
2742 if (!ptrs) {
2743 /* First element triggers the creation of pointer array */
2744 ptrs = g_ptr_array_new();
2745 g_hash_table_insert(tree_data->interesting_hfids,
2746 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2747 }
2748
2749 g_ptr_array_add(ptrs, fi);
2750 }
2751}
2752
2753
2754/*
2755 * Validates that field length bytes are available starting from
2756 * start (pos/neg). Throws an exception if they aren't.
2757 */
2758static void
2759test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2760 unsigned start, int length, const unsigned encoding)
2761{
2762 int size = length;
2763
2764 if (!tvb)
2765 return;
2766
2767 if ((hfinfo->type == FT_STRINGZ) ||
2768 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2769 (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
))
))) {
2770 /* If we're fetching until the end of the TVB, only validate
2771 * that the offset is within range.
2772 */
2773 if (length == -1)
2774 size = 0;
2775 }
2776
2777 tvb_ensure_bytes_exist(tvb, start, size);
2778}
2779
2780static void
2781detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2782{
2783 bool_Bool found_stray_character = false0;
2784
2785 if (!string)
2786 return;
2787
2788 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2789 case ENC_ASCII0x00000000:
2790 case ENC_UTF_80x00000002:
2791 for (int i = (int)strlen(string); i < length; i++) {
2792 if (string[i] != '\0') {
2793 found_stray_character = true1;
2794 break;
2795 }
2796 }
2797 break;
2798
2799 default:
2800 break;
2801 }
2802
2803 if (found_stray_character) {
2804 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2805 }
2806}
2807
2808static void
2809free_fvalue_cb(void *data)
2810{
2811 fvalue_t *fv = (fvalue_t*)data;
2812 fvalue_free(fv);
2813}
2814
2815/* Add an item to a proto_tree, using the text label registered to that item;
2816 the item is extracted from the tvbuff handed to it. */
2817static proto_item *
2818proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2819 tvbuff_t *tvb, unsigned start, int length,
2820 unsigned encoding)
2821{
2822 proto_item *pi;
2823 uint32_t value, n;
2824 uint64_t value64;
2825 ws_in4_addr ipv4_value;
2826 float floatval;
2827 double doubleval;
2828 const char *stringval = NULL((void*)0);
2829 nstime_t time_stamp;
2830 bool_Bool length_error;
2831
2832 /* Ensure that the newly created fvalue_t is freed if we throw an
2833 * exception before adding it to the tree. (gcc creates clobbering
2834 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2835 * XXX: Move the new_field_info() call inside here?
2836 */
2837 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2838
2839 switch (new_fi->hfinfo->type) {
2840 case FT_NONE:
2841 /* no value to set for FT_NONE */
2842 break;
2843
2844 case FT_PROTOCOL:
2845 /* Set the protocol_tvb via the start offset, but include
2846 * rest of the ds_tvb so that if finfo_set_len is called
2847 * later it can be lengthened as much as possible. */
2848 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);
2849 break;
2850
2851 case FT_BYTES:
2852 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2853 break;
2854
2855 case FT_UINT_BYTES:
2856 n = get_uint_value(tree, tvb, start, length, encoding);
2857 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2858
2859 /* Instead of calling proto_item_set_len(), since we don't yet
2860 * have a proto_item, we set the field_info's length ourselves. */
2861 new_fi->length = n + length;
2862 break;
2863
2864 case FT_BOOLEAN:
2865 /*
2866 * Map all non-zero values to little-endian for
2867 * backwards compatibility.
2868 */
2869 if (encoding)
2870 encoding = ENC_LITTLE_ENDIAN0x80000000;
2871 proto_tree_set_boolean(new_fi,
2872 get_uint64_value(tree, tvb, start, length, encoding));
2873 break;
2874
2875 case FT_CHAR:
2876 /* XXX - make these just FT_UINT? */
2877 case FT_UINT8:
2878 case FT_UINT16:
2879 case FT_UINT24:
2880 case FT_UINT32:
2881 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2882 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2883 value = (uint32_t)value64;
2884 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2885 new_fi->flags |= FI_VARINT0x00040000;
2886 }
2887 }
2888 else {
2889 /*
2890 * Map all non-zero values to little-endian for
2891 * backwards compatibility.
2892 */
2893 if (encoding)
2894 encoding = ENC_LITTLE_ENDIAN0x80000000;
2895
2896 value = get_uint_value(tree, tvb, start, length, encoding);
2897 }
2898 proto_tree_set_uint(new_fi, value);
2899 break;
2900
2901 case FT_UINT40:
2902 case FT_UINT48:
2903 case FT_UINT56:
2904 case FT_UINT64:
2905 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2906 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2907 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2908 new_fi->flags |= FI_VARINT0x00040000;
2909 }
2910 }
2911 else {
2912 /*
2913 * Map all other non-zero values to little-endian for
2914 * backwards compatibility.
2915 */
2916 if (encoding)
2917 encoding = ENC_LITTLE_ENDIAN0x80000000;
2918
2919 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2920 }
2921 proto_tree_set_uint64(new_fi, value64);
2922 break;
2923
2924 /* XXX - make these just FT_INT? */
2925 case FT_INT8:
2926 case FT_INT16:
2927 case FT_INT24:
2928 case FT_INT32:
2929 /*
2930 * Map all non-zero values to little-endian for
2931 * backwards compatibility.
2932 */
2933 if (encoding)
2934 encoding = ENC_LITTLE_ENDIAN0x80000000;
2935 proto_tree_set_int(new_fi,
2936 get_int_value(tree, tvb, start, length, encoding));
2937 break;
2938
2939 case FT_INT40:
2940 case FT_INT48:
2941 case FT_INT56:
2942 case FT_INT64:
2943 /*
2944 * Map all non-zero values to little-endian for
2945 * backwards compatibility.
2946 */
2947 if (encoding)
2948 encoding = ENC_LITTLE_ENDIAN0x80000000;
2949 proto_tree_set_int64(new_fi,
2950 get_int64_value(tree, tvb, start, length, encoding));
2951 break;
2952
2953 case FT_IPv4:
2954 /*
2955 * Map all non-zero values to little-endian for
2956 * backwards compatibility.
2957 */
2958 if (encoding)
2959 encoding = ENC_LITTLE_ENDIAN0x80000000;
2960 if (length != FT_IPv4_LEN4) {
2961 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2962 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2963 }
2964 ipv4_value = tvb_get_ipv4(tvb, start);
2965 /*
2966 * NOTE: to support code written when
2967 * proto_tree_add_item() took a bool as its
2968 * last argument, with false meaning "big-endian"
2969 * and true meaning "little-endian", we treat any
2970 * non-zero value of "encoding" as meaning
2971 * "little-endian".
2972 */
2973 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);
2974 break;
2975
2976 case FT_IPXNET:
2977 if (length != FT_IPXNET_LEN4) {
2978 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2979 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2980 }
2981 proto_tree_set_ipxnet(new_fi,
2982 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2983 break;
2984
2985 case FT_IPv6:
2986 if (length != FT_IPv6_LEN16) {
2987 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2988 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2989 }
2990 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2991 break;
2992
2993 case FT_FCWWN:
2994 if (length != FT_FCWWN_LEN8) {
2995 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2996 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2997 }
2998 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2999 break;
3000
3001 case FT_AX25:
3002 if (length != 7) {
3003 length_error = length < 7 ? true1 : false0;
3004 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3005 }
3006 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3007 break;
3008
3009 case FT_VINES:
3010 if (length != VINES_ADDR_LEN6) {
3011 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3012 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3013 }
3014 proto_tree_set_vines_tvb(new_fi, tvb, start);
3015 break;
3016
3017 case FT_ETHER:
3018 if (length != FT_ETHER_LEN6) {
3019 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3020 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3021 }
3022 proto_tree_set_ether_tvb(new_fi, tvb, start);
3023 break;
3024
3025 case FT_EUI64:
3026 /*
3027 * Map all non-zero values to little-endian for
3028 * backwards compatibility.
3029 */
3030 if (encoding)
3031 encoding = ENC_LITTLE_ENDIAN0x80000000;
3032 if (length != FT_EUI64_LEN8) {
3033 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3034 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3035 }
3036 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3037 break;
3038 case FT_GUID:
3039 /*
3040 * Map all non-zero values to little-endian for
3041 * backwards compatibility.
3042 */
3043 if (encoding)
3044 encoding = ENC_LITTLE_ENDIAN0x80000000;
3045 if (length != FT_GUID_LEN16) {
3046 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3047 report_type_length_mismatch(tree, "a GUID", length, length_error);
3048 }
3049 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3050 break;
3051
3052 case FT_OID:
3053 case FT_REL_OID:
3054 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3055 break;
3056
3057 case FT_SYSTEM_ID:
3058 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3059 break;
3060
3061 case FT_FLOAT:
3062 /*
3063 * NOTE: to support code written when
3064 * proto_tree_add_item() took a bool as its
3065 * last argument, with false meaning "big-endian"
3066 * and true meaning "little-endian", we treat any
3067 * non-zero value of "encoding" as meaning
3068 * "little-endian".
3069 *
3070 * At some point in the future, we might
3071 * support non-IEEE-binary floating-point
3072 * formats in the encoding as well
3073 * (IEEE decimal, System/3x0, VAX).
3074 */
3075 if (encoding)
3076 encoding = ENC_LITTLE_ENDIAN0x80000000;
3077 if (length != 4) {
3078 length_error = length < 4 ? true1 : false0;
3079 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3080 }
3081 if (encoding)
3082 floatval = tvb_get_letohieee_float(tvb, start);
3083 else
3084 floatval = tvb_get_ntohieee_float(tvb, start);
3085 proto_tree_set_float(new_fi, floatval);
3086 break;
3087
3088 case FT_DOUBLE:
3089 /*
3090 * NOTE: to support code written when
3091 * proto_tree_add_item() took a bool as its
3092 * last argument, with false meaning "big-endian"
3093 * and true meaning "little-endian", we treat any
3094 * non-zero value of "encoding" as meaning
3095 * "little-endian".
3096 *
3097 * At some point in the future, we might
3098 * support non-IEEE-binary floating-point
3099 * formats in the encoding as well
3100 * (IEEE decimal, System/3x0, VAX).
3101 */
3102 if (encoding == true1)
3103 encoding = ENC_LITTLE_ENDIAN0x80000000;
3104 if (length != 8) {
3105 length_error = length < 8 ? true1 : false0;
3106 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3107 }
3108 if (encoding)
3109 doubleval = tvb_get_letohieee_double(tvb, start);
3110 else
3111 doubleval = tvb_get_ntohieee_double(tvb, start);
3112 proto_tree_set_double(new_fi, doubleval);
3113 break;
3114
3115 case FT_STRING:
3116 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3117 tvb, start, length, &length, encoding);
3118 proto_tree_set_string(new_fi, stringval);
3119
3120 /* Instead of calling proto_item_set_len(), since we
3121 * don't yet have a proto_item, we set the
3122 * field_info's length ourselves.
3123 *
3124 * XXX - our caller can't use that length to
3125 * advance an offset unless they arrange that
3126 * there always be a protocol tree into which
3127 * we're putting this item.
3128 */
3129 new_fi->length = length;
3130 break;
3131
3132 case FT_STRINGZ:
3133 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3134 tree, tvb, start, length, &length, encoding);
3135 proto_tree_set_string(new_fi, stringval);
3136
3137 /* Instead of calling proto_item_set_len(),
3138 * since we don't yet have a proto_item, we
3139 * set the field_info's length ourselves.
3140 *
3141 * XXX - our caller can't use that length to
3142 * advance an offset unless they arrange that
3143 * there always be a protocol tree into which
3144 * we're putting this item.
3145 */
3146 new_fi->length = length;
3147 break;
3148
3149 case FT_UINT_STRING:
3150 /*
3151 * NOTE: to support code written when
3152 * proto_tree_add_item() took a bool as its
3153 * last argument, with false meaning "big-endian"
3154 * and true meaning "little-endian", if the
3155 * encoding value is true, treat that as
3156 * ASCII with a little-endian length.
3157 *
3158 * This won't work for code that passes
3159 * arbitrary non-zero values; that code
3160 * will need to be fixed.
3161 */
3162 if (encoding == true1)
3163 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3164 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3165 tree, tvb, start, length, &length, encoding);
3166 proto_tree_set_string(new_fi, stringval);
3167
3168 /* Instead of calling proto_item_set_len(), since we
3169 * don't yet have a proto_item, we set the
3170 * field_info's length ourselves.
3171 *
3172 * XXX - our caller can't use that length to
3173 * advance an offset unless they arrange that
3174 * there always be a protocol tree into which
3175 * we're putting this item.
3176 */
3177 new_fi->length = length;
3178 break;
3179
3180 case FT_STRINGZPAD:
3181 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3182 tvb, start, length, &length, encoding);
3183 proto_tree_set_string(new_fi, stringval);
3184
3185 /* Instead of calling proto_item_set_len(), since we
3186 * don't yet have a proto_item, we set the
3187 * field_info's length ourselves.
3188 *
3189 * XXX - our caller can't use that length to
3190 * advance an offset unless they arrange that
3191 * there always be a protocol tree into which
3192 * we're putting this item.
3193 */
3194 new_fi->length = length;
3195 break;
3196
3197 case FT_STRINGZTRUNC:
3198 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3199 tvb, start, length, &length, encoding);
3200 proto_tree_set_string(new_fi, stringval);
3201
3202 /* Instead of calling proto_item_set_len(), since we
3203 * don't yet have a proto_item, we set the
3204 * field_info's length ourselves.
3205 *
3206 * XXX - our caller can't use that length to
3207 * advance an offset unless they arrange that
3208 * there always be a protocol tree into which
3209 * we're putting this item.
3210 */
3211 new_fi->length = length;
3212 break;
3213
3214 case FT_ABSOLUTE_TIME:
3215 /*
3216 * Absolute times can be in any of a number of
3217 * formats, and they can be big-endian or
3218 * little-endian.
3219 *
3220 * Historically FT_TIMEs were only timespecs;
3221 * the only question was whether they were stored
3222 * in big- or little-endian format.
3223 *
3224 * For backwards compatibility, we interpret an
3225 * encoding of 1 as meaning "little-endian timespec",
3226 * so that passing true is interpreted as that.
3227 */
3228 if (encoding == true1)
3229 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3230
3231 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3232
3233 proto_tree_set_time(new_fi, &time_stamp);
3234 break;
3235
3236 case FT_RELATIVE_TIME:
3237 /*
3238 * Relative times can be in any of a number of
3239 * formats, and they can be big-endian or
3240 * little-endian.
3241 *
3242 * Historically FT_TIMEs were only timespecs;
3243 * the only question was whether they were stored
3244 * in big- or little-endian format.
3245 *
3246 * For backwards compatibility, we interpret an
3247 * encoding of 1 as meaning "little-endian timespec",
3248 * so that passing true is interpreted as that.
3249 */
3250 if (encoding == true1)
3251 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3252
3253 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3254
3255 proto_tree_set_time(new_fi, &time_stamp);
3256 break;
3257 case FT_IEEE_11073_SFLOAT:
3258 if (encoding)
3259 encoding = ENC_LITTLE_ENDIAN0x80000000;
3260 if (length != 2) {
3261 length_error = length < 2 ? true1 : false0;
3262 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3263 }
3264
3265 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3266
3267 break;
3268 case FT_IEEE_11073_FLOAT:
3269 if (encoding)
3270 encoding = ENC_LITTLE_ENDIAN0x80000000;
3271 if (length != 4) {
3272 length_error = length < 4 ? true1 : false0;
3273 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3274 }
3275 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3276
3277 break;
3278 default:
3279 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))
3280 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))
3281 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))
3282 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))
;
3283 break;
3284 }
3285 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)
;
3286
3287 /* Don't add new node to proto_tree until now so that any exceptions
3288 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3289 /* XXX. wouldn't be better to add this item to tree, with some special
3290 * flag (FI_EXCEPTION?) to know which item caused exception? For
3291 * strings and bytes, we would have to set new_fi->value to something
3292 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3293 * could handle NULL values. */
3294 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3295 pi = proto_tree_add_node(tree, new_fi);
3296
3297 switch (new_fi->hfinfo->type) {
3298
3299 case FT_STRING:
3300 /* XXX: trailing stray character detection should be done
3301 * _before_ conversion to UTF-8, because conversion can change
3302 * the length, or else get_string_length should return a value
3303 * for the "length in bytes of the string after conversion
3304 * including internal nulls." (Noting that we do, for other
3305 * reasons, still need the "length in bytes in the field",
3306 * especially for FT_STRINGZ.)
3307 *
3308 * This is true even for ASCII and UTF-8, because
3309 * substituting REPLACEMENT CHARACTERS for illegal characters
3310 * can also do so (and for UTF-8 possibly even make the
3311 * string _shorter_).
3312 */
3313 detect_trailing_stray_characters(encoding, stringval, length, pi);
3314 break;
3315
3316 default:
3317 break;
3318 }
3319
3320 return pi;
3321}
3322
3323proto_item *
3324proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3325 const unsigned start, int length,
3326 const unsigned encoding, int32_t *retval)
3327{
3328 header_field_info *hfinfo;
3329 field_info *new_fi;
3330 int32_t value;
3331
3332 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", 3332, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3332,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3332, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3333
3334 switch (hfinfo->type) {
3335 case FT_INT8:
3336 case FT_INT16:
3337 case FT_INT24:
3338 case FT_INT32:
3339 break;
3340 case FT_INT64:
3341 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)
3342 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3343 default:
3344 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)
3345 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3346 }
3347
3348 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3349 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3350 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3351 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3352 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3353 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3354 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3355
3356 if (encoding & ENC_STRING0x07000000) {
3357 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3358 }
3359 /* I believe it's ok if this is called with a NULL tree */
3360 value = get_int_value(tree, tvb, start, length, encoding);
3361
3362 if (retval) {
3363 int no_of_bits;
3364 *retval = value;
3365 if (hfinfo->bitmask) {
3366 /* Mask out irrelevant portions */
3367 *retval &= (uint32_t)(hfinfo->bitmask);
3368 /* Shift bits */
3369 *retval >>= hfinfo_bitshift(hfinfo);
3370 }
3371 no_of_bits = ws_count_ones(hfinfo->bitmask);
3372 *retval = ws_sign_ext32(*retval, no_of_bits);
3373 }
3374
3375 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3376
3377 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", 3377
, __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", 3377, "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", 3377, "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", 3377, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3378
3379 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3380
3381 proto_tree_set_int(new_fi, value);
3382
3383 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3384
3385 return proto_tree_add_node(tree, new_fi);
3386}
3387
3388proto_item *
3389proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3390 const unsigned start, int length,
3391 const unsigned encoding, uint32_t *retval)
3392{
3393 header_field_info *hfinfo;
3394 field_info *new_fi;
3395 uint32_t value;
3396
3397 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", 3397, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3397,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3397, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3398
3399 switch (hfinfo->type) {
3400 case FT_CHAR:
3401 case FT_UINT8:
3402 case FT_UINT16:
3403 case FT_UINT24:
3404 case FT_UINT32:
3405 break;
3406 default:
3407 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)
3408 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)
;
3409 }
3410
3411 if (length == 0) {
3412 if (retval) {
3413 *retval = 0;
3414 }
3415 return NULL((void*)0);
3416 }
3417
3418 if (encoding & ENC_STRING0x07000000) {
3419 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3420 }
3421 /* I believe it's ok if this is called with a NULL tree */
3422 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3423 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3424 uint64_t temp64;
3425 tvb_get_varint(tvb, start, length, &temp64, encoding);
3426 value = (uint32_t)temp64;
3427 } else {
3428 value = get_uint_value(tree, tvb, start, length, encoding);
3429 }
3430
3431 if (retval) {
3432 *retval = value;
3433 if (hfinfo->bitmask) {
3434 /* Mask out irrelevant portions */
3435 *retval &= (uint32_t)(hfinfo->bitmask);
3436 /* Shift bits */
3437 *retval >>= hfinfo_bitshift(hfinfo);
3438 }
3439 }
3440
3441 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3442
3443 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", 3443
, __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", 3443, "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", 3443, "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", 3443, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3444
3445 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3446
3447 proto_tree_set_uint(new_fi, value);
3448
3449 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3450 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3451 new_fi->flags |= FI_VARINT0x00040000;
3452 }
3453 return proto_tree_add_node(tree, new_fi);
3454}
3455
3456proto_item *
3457proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3458 const unsigned start, int length,
3459 const unsigned encoding, uint32_t *retval)
3460{
3461 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3462}
3463
3464proto_item *
3465proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3466 const unsigned start, int length,
3467 const unsigned encoding, uint8_t *retval)
3468{
3469 /* TODO: further restrict by hfinfo->type ? */
3470 uint32_t val32;
3471 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3472 *retval = (uint8_t)val32;
3473 return item;
3474}
3475
3476proto_item *
3477proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3478 const unsigned start, int length,
3479 const unsigned encoding, uint16_t *retval)
3480{
3481 /* TODO: further restrict by hfinfo->type ? */
3482 uint32_t val32;
3483 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3484 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3485 return item;
3486}
3487
3488
3489/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3490 * and returns proto_item* and uint value retrieved*/
3491proto_item *
3492ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3493 const unsigned encoding, uint32_t *retval)
3494{
3495 field_info *new_fi;
3496 header_field_info *hfinfo;
3497 unsigned item_length;
3498 unsigned offset;
3499 uint32_t value;
3500
3501 offset = ptvc->offset;
3502 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", 3502, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3502,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3502, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3503
3504 switch (hfinfo->type) {
3505 case FT_CHAR:
3506 case FT_UINT8:
3507 case FT_UINT16:
3508 case FT_UINT24:
3509 case FT_UINT32:
3510 break;
3511 default:
3512 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)
3513 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)
;
3514 }
3515
3516 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3517 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3518
3519 /* I believe it's ok if this is called with a NULL tree */
3520 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3521 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3522
3523 if (retval) {
3524 *retval = value;
3525 if (hfinfo->bitmask) {
3526 /* Mask out irrelevant portions */
3527 *retval &= (uint32_t)(hfinfo->bitmask);
3528 /* Shift bits */
3529 *retval >>= hfinfo_bitshift(hfinfo);
3530 }
3531 }
3532
3533 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3534
3535 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3536
3537 /* Coast clear. Try and fake it */
3538 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", 3538
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3538, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3538, "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", 3538, __func__, "Adding %s would put more than %d 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); } } }
;
3539
3540 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3541
3542 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3543 offset, length, encoding);
3544}
3545
3546/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3547 * and returns proto_item* and int value retrieved*/
3548proto_item *
3549ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3550 const unsigned encoding, int32_t *retval)
3551{
3552 field_info *new_fi;
3553 header_field_info *hfinfo;
3554 unsigned item_length;
3555 unsigned offset;
3556 uint32_t value;
3557
3558 offset = ptvc->offset;
3559 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", 3559, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3559,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3559, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3560
3561 switch (hfinfo->type) {
3562 case FT_INT8:
3563 case FT_INT16:
3564 case FT_INT24:
3565 case FT_INT32:
3566 break;
3567 default:
3568 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)
3569 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3570 }
3571
3572 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3573 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3574
3575 /* I believe it's ok if this is called with a NULL tree */
3576 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3577 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3578
3579 if (retval) {
3580 int no_of_bits;
3581 *retval = value;
3582 if (hfinfo->bitmask) {
3583 /* Mask out irrelevant portions */
3584 *retval &= (uint32_t)(hfinfo->bitmask);
3585 /* Shift bits */
3586 *retval >>= hfinfo_bitshift(hfinfo);
3587 }
3588 no_of_bits = ws_count_ones(hfinfo->bitmask);
3589 *retval = ws_sign_ext32(*retval, no_of_bits);
3590 }
3591
3592 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3593
3594 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3595
3596 /* Coast clear. Try and fake it */
3597 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", 3597
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3597, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3597, "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", 3597, __func__, "Adding %s would put more than %d 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); } } }
;
3598
3599 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3600
3601 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3602 offset, length, encoding);
3603}
3604
3605/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3606 * and returns proto_item* and string value retrieved */
3607proto_item*
3608ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3609{
3610 header_field_info *hfinfo;
3611 field_info *new_fi;
3612 const uint8_t *value;
3613 unsigned item_length;
3614 unsigned offset;
3615
3616 offset = ptvc->offset;
3617
3618 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", 3618
, __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", 3618, "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", 3618, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3619
3620 switch (hfinfo->type) {
3621 case FT_STRING:
3622 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3623 break;
3624 case FT_STRINGZ:
3625 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3626 break;
3627 case FT_UINT_STRING:
3628 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3629 break;
3630 case FT_STRINGZPAD:
3631 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3632 break;
3633 case FT_STRINGZTRUNC:
3634 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3635 break;
3636 default:
3637 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)
3638 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)
;
3639 }
3640
3641 if (retval)
3642 *retval = value;
3643
3644 ptvcursor_advance(ptvc, item_length);
3645
3646 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3647
3648 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", 3648, __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", 3648,
"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", 3648, "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", 3648
, __func__, "Adding %s would put more than %d 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); } } }
;
3649
3650 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3651
3652 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3653 offset, length, encoding);
3654}
3655
3656/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3657 * and returns proto_item* and boolean value retrieved */
3658proto_item*
3659ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3660{
3661 header_field_info *hfinfo;
3662 field_info *new_fi;
3663 unsigned item_length;
3664 unsigned offset;
3665 uint64_t value, bitval;
3666
3667 offset = ptvc->offset;
3668 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", 3668, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3668,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3668, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3669
3670 if (hfinfo->type != FT_BOOLEAN) {
3671 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)
3672 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3673 }
3674
3675 if (length == 0) {
3676 if (retval) {
3677 *retval = 0;
3678 }
3679 return NULL((void*)0);
3680 }
3681 if (encoding & ENC_STRING0x07000000) {
3682 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3683 }
3684
3685 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3686 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3687
3688 /* I believe it's ok if this is called with a NULL tree */
3689 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3690
3691 if (retval) {
3692 bitval = value;
3693 if (hfinfo->bitmask) {
3694 /* Mask out irrelevant portions */
3695 bitval &= hfinfo->bitmask;
3696 }
3697 *retval = (bitval != 0);
3698 }
3699
3700 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3701
3702 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3703
3704 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", 3704, __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", 3704,
"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", 3704, "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", 3704
, __func__, "Adding %s would put more than %d 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); } } }
;
3705
3706 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3707
3708 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3709 offset, length, encoding);
3710}
3711
3712proto_item *
3713proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3714 const unsigned start, int length, const unsigned encoding, uint64_t *retval)
3715{
3716 header_field_info *hfinfo;
3717 field_info *new_fi;
3718 uint64_t value;
3719
3720 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", 3720, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3720,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3720, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3721
3722 switch (hfinfo->type) {
3723 case FT_UINT40:
3724 case FT_UINT48:
3725 case FT_UINT56:
3726 case FT_UINT64:
3727 break;
3728 default:
3729 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)
3730 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3731 }
3732
3733 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3734 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3735 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3736 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3737 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3738 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3739 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3740
3741 if (encoding & ENC_STRING0x07000000) {
3742 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3743 }
3744 /* I believe it's ok if this is called with a NULL tree */
3745 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3746 tvb_get_varint(tvb, start, length, &value, encoding);
3747 } else {
3748 value = get_uint64_value(tree, tvb, start, length, encoding);
3749 }
3750
3751 if (retval) {
3752 *retval = value;
3753 if (hfinfo->bitmask) {
3754 /* Mask out irrelevant portions */
3755 *retval &= hfinfo->bitmask;
3756 /* Shift bits */
3757 *retval >>= hfinfo_bitshift(hfinfo);
3758 }
3759 }
3760
3761 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3762
3763 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", 3763
, __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", 3763, "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", 3763, "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", 3763, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3764
3765 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3766
3767 proto_tree_set_uint64(new_fi, value);
3768
3769 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3770 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3771 new_fi->flags |= FI_VARINT0x00040000;
3772 }
3773
3774 return proto_tree_add_node(tree, new_fi);
3775}
3776
3777proto_item *
3778proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3779 const unsigned start, int length, const unsigned encoding, int64_t *retval)
3780{
3781 header_field_info *hfinfo;
3782 field_info *new_fi;
3783 int64_t value;
3784
3785 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", 3785, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3785,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3785, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3786
3787 switch (hfinfo->type) {
3788 case FT_INT40:
3789 case FT_INT48:
3790 case FT_INT56:
3791 case FT_INT64:
3792 break;
3793 default:
3794 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)
3795 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3796 }
3797
3798 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3799 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3800 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3801 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3802 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3803 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3804 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3805
3806 if (encoding & ENC_STRING0x07000000) {
3807 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3808 }
3809 /* I believe it's ok if this is called with a NULL tree */
3810 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3811 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3812 }
3813 else {
3814 value = get_int64_value(tree, tvb, start, length, encoding);
3815 }
3816
3817 if (retval) {
3818 *retval = value;
3819 }
3820
3821 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3822
3823 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", 3823
, __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", 3823, "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", 3823, "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", 3823, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3824
3825 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3826
3827 proto_tree_set_int64(new_fi, value);
3828
3829 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3830 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3831 new_fi->flags |= FI_VARINT0x00040000;
3832 }
3833
3834 return proto_tree_add_node(tree, new_fi);
3835}
3836
3837proto_item *
3838proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3839 const unsigned start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3840{
3841 header_field_info *hfinfo;
3842 field_info *new_fi;
3843 uint64_t value;
3844
3845 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", 3845, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3845,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3845, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3846
3847 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
))
)) {
3848 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)
3849 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3850 }
3851
3852 /* length validation for native number encoding caught by get_uint64_value() */
3853 /* length has to be -1 or > 0 regardless of encoding */
3854 if (length == 0)
3855 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
3856 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3857
3858 if (encoding & ENC_STRING0x07000000) {
3859 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3860 }
3861
3862 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3863
3864 if (retval) {
3865 *retval = value;
3866 if (hfinfo->bitmask) {
3867 /* Mask out irrelevant portions */
3868 *retval &= hfinfo->bitmask;
3869 /* Shift bits */
3870 *retval >>= hfinfo_bitshift(hfinfo);
3871 }
3872 }
3873
3874 if (lenretval) {
3875 *lenretval = length;
3876 }
3877
3878 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3879
3880 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", 3880
, __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", 3880, "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", 3880, "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", 3880, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3881
3882 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3883
3884 proto_tree_set_uint64(new_fi, value);
3885
3886 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3887 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3888 new_fi->flags |= FI_VARINT0x00040000;
3889 }
3890
3891 return proto_tree_add_node(tree, new_fi);
3892
3893}
3894
3895proto_item *
3896proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3897 const unsigned start, int length,
3898 const unsigned encoding, bool_Bool *retval)
3899{
3900 header_field_info *hfinfo;
3901 field_info *new_fi;
3902 uint64_t value, bitval;
3903
3904 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", 3904, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3904,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3904, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3905
3906 if (hfinfo->type != FT_BOOLEAN) {
3907 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)
3908 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3909 }
3910
3911 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3912 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3913 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3914 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3915 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3916 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3917 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3918
3919 if (encoding & ENC_STRING0x07000000) {
3920 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3921 }
3922 /* I believe it's ok if this is called with a NULL tree */
3923 value = get_uint64_value(tree, tvb, start, length, encoding);
3924
3925 if (retval) {
3926 bitval = value;
3927 if (hfinfo->bitmask) {
3928 /* Mask out irrelevant portions */
3929 bitval &= hfinfo->bitmask;
3930 }
3931 *retval = (bitval != 0);
3932 }
3933
3934 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3935
3936 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", 3936
, __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", 3936, "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", 3936, "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", 3936, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3937
3938 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3939
3940 proto_tree_set_boolean(new_fi, value);
3941
3942 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3943
3944 return proto_tree_add_node(tree, new_fi);
3945}
3946
3947proto_item *
3948proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3949 const unsigned start, int length,
3950 const unsigned encoding, float *retval)
3951{
3952 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3953 field_info *new_fi;
3954 float value;
3955
3956 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", 3956,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3957
3958 if (hfinfo->type != FT_FLOAT) {
3959 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)
;
3960 }
3961
3962 if (length != 4) {
3963 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3964 }
3965
3966 /* treat any nonzero encoding as little endian for backwards compatibility */
3967 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3968 if (retval) {
3969 *retval = value;
3970 }
3971
3972 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3973
3974 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", 3974
, __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", 3974, "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", 3974, "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", 3974, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3975
3976 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3977 if (encoding) {
3978 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3979 }
3980
3981 proto_tree_set_float(new_fi, value);
3982
3983 return proto_tree_add_node(tree, new_fi);
3984}
3985
3986proto_item *
3987proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3988 const unsigned start, int length,
3989 const unsigned encoding, double *retval)
3990{
3991 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3992 field_info *new_fi;
3993 double value;
3994
3995 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", 3995,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3996
3997 if (hfinfo->type != FT_DOUBLE) {
3998 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)
;
3999 }
4000
4001 if (length != 8) {
4002 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4003 }
4004
4005 /* treat any nonzero encoding as little endian for backwards compatibility */
4006 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4007 if (retval) {
4008 *retval = value;
4009 }
4010
4011 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4012
4013 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", 4013
, __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", 4013, "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", 4013, "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", 4013, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4014
4015 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4016 if (encoding) {
4017 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4018 }
4019
4020 proto_tree_set_double(new_fi, value);
4021
4022 return proto_tree_add_node(tree, new_fi);
4023}
4024
4025proto_item *
4026proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4027 const unsigned start, int length,
4028 const unsigned encoding, ws_in4_addr *retval)
4029{
4030 header_field_info *hfinfo;
4031 field_info *new_fi;
4032 ws_in4_addr value;
4033
4034 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", 4034, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4034,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4034, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4035
4036 switch (hfinfo->type) {
4037 case FT_IPv4:
4038 break;
4039 default:
4040 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)
4041 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4042 }
4043
4044 if (length != FT_IPv4_LEN4)
4045 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)
4046 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4047
4048 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4049 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4050 }
4051
4052 /*
4053 * NOTE: to support code written when proto_tree_add_item() took
4054 * a bool as its last argument, with false meaning "big-endian"
4055 * and true meaning "little-endian", we treat any non-zero value
4056 * of "encoding" as meaning "little-endian".
4057 */
4058 value = tvb_get_ipv4(tvb, start);
4059 if (encoding)
4060 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))))
;
4061
4062 if (retval) {
4063 *retval = value;
4064 }
4065
4066 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4067
4068 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", 4068
, __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", 4068, "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", 4068, "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", 4068, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4069
4070 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4071
4072 proto_tree_set_ipv4(new_fi, value);
4073
4074 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4075 return proto_tree_add_node(tree, new_fi);
4076}
4077
4078proto_item *
4079proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4080 const unsigned start, int length,
4081 const unsigned encoding, ws_in6_addr *addr)
4082{
4083 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4084 field_info *new_fi;
4085
4086 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", 4086,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4087
4088 switch (hfinfo->type) {
4089 case FT_IPv6:
4090 break;
4091 default:
4092 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)
4093 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4094 }
4095
4096 if (length != FT_IPv6_LEN16)
4097 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)
4098 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4099
4100 if (encoding) {
4101 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"
)
;
4102 }
4103
4104 tvb_get_ipv6(tvb, start, addr);
4105
4106 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4107
4108 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", 4108
, __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", 4108, "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", 4108, "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", 4108, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4109
4110 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4111
4112 proto_tree_set_ipv6(new_fi, addr);
4113
4114 return proto_tree_add_node(tree, new_fi);
4115}
4116
4117proto_item *
4118proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4119 const unsigned start, int length, const unsigned encoding, uint8_t *retval) {
4120
4121 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4122 field_info *new_fi;
4123
4124 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", 4124,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4125
4126 switch (hfinfo->type) {
4127 case FT_ETHER:
4128 break;
4129 default:
4130 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)
4131 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4132 }
4133
4134 if (length != FT_ETHER_LEN6)
4135 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)
4136 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4137
4138 if (encoding) {
4139 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"
)
;
4140 }
4141
4142 tvb_memcpy(tvb, retval, start, length);
4143
4144 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4145
4146 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", 4146
, __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", 4146, "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", 4146, "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", 4146, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4147
4148 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4149
4150 proto_tree_set_ether(new_fi, retval);
4151
4152 return proto_tree_add_node(tree, new_fi);
4153}
4154
4155
4156proto_item *
4157proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4158 tvbuff_t *tvb,
4159 const unsigned start, int length,
4160 const unsigned encoding,
4161 wmem_allocator_t *scope,
4162 const uint8_t **retval,
4163 int *lenretval)
4164{
4165 proto_item *pi;
4166 header_field_info *hfinfo;
4167 field_info *new_fi;
4168 const uint8_t *value;
4169
4170 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", 4170, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4170,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4170, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4171
4172 switch (hfinfo->type) {
4173 case FT_STRING:
4174 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4175 break;
4176 case FT_STRINGZ:
4177 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4178 break;
4179 case FT_UINT_STRING:
4180 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4181 break;
4182 case FT_STRINGZPAD:
4183 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4184 break;
4185 case FT_STRINGZTRUNC:
4186 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4187 break;
4188 default:
4189 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)
4190 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)
;
4191 }
4192
4193 if (retval)
4194 *retval = value;
4195
4196 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4197
4198 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", 4198
, __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", 4198, "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", 4198, "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", 4198, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4199
4200 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4201
4202 proto_tree_set_string(new_fi, (const char*)value);
4203
4204 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4205
4206 pi = proto_tree_add_node(tree, new_fi);
4207
4208 switch (hfinfo->type) {
4209
4210 case FT_STRINGZ:
4211 case FT_STRINGZPAD:
4212 case FT_STRINGZTRUNC:
4213 case FT_UINT_STRING:
4214 break;
4215
4216 case FT_STRING:
4217 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4218 break;
4219
4220 default:
4221 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4221
, __func__, "assertion \"not reached\" failed")
;
4222 }
4223
4224 return pi;
4225}
4226
4227proto_item *
4228proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4229 const unsigned start, int length,
4230 const unsigned encoding, wmem_allocator_t *scope,
4231 const uint8_t **retval)
4232{
4233 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4234 tvb, start, length, encoding, scope, retval, &length);
4235}
4236
4237proto_item *
4238proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4239 tvbuff_t *tvb,
4240 const unsigned start, int length,
4241 const unsigned encoding,
4242 wmem_allocator_t *scope,
4243 char **retval,
4244 int *lenretval)
4245{
4246 proto_item *pi;
4247 header_field_info *hfinfo;
4248 field_info *new_fi;
4249 const uint8_t *value;
4250 uint32_t n = 0;
4251
4252 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", 4252, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4252,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4252, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4253
4254 switch (hfinfo->type) {
4255 case FT_STRING:
4256 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4257 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4258 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4259 break;
4260 case FT_STRINGZ:
4261 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4262 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4263 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4264 break;
4265 case FT_UINT_STRING:
4266 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4267 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4268 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4269 break;
4270 case FT_STRINGZPAD:
4271 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4272 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4273 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4274 break;
4275 case FT_STRINGZTRUNC:
4276 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4277 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4278 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4279 break;
4280 case FT_BYTES:
4281 tvb_ensure_bytes_exist(tvb, start, length);
4282 value = tvb_get_ptr(tvb, start, length);
4283 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4284 *lenretval = length;
4285 break;
4286 case FT_UINT_BYTES:
4287 n = get_uint_value(tree, tvb, start, length, encoding);
4288 tvb_ensure_bytes_exist(tvb, start + length, n);
4289 value = tvb_get_ptr(tvb, start + length, n);
4290 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4291 *lenretval = length + n;
4292 break;
4293 default:
4294 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)
4295 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)
;
4296 }
4297
4298 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4299
4300 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", 4300
, __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", 4300, "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", 4300, "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", 4300, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4301
4302 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4303
4304 switch (hfinfo->type) {
4305
4306 case FT_STRING:
4307 case FT_STRINGZ:
4308 case FT_UINT_STRING:
4309 case FT_STRINGZPAD:
4310 case FT_STRINGZTRUNC:
4311 proto_tree_set_string(new_fi, (const char*)value);
4312 break;
4313
4314 case FT_BYTES:
4315 proto_tree_set_bytes(new_fi, value, length);
4316 break;
4317
4318 case FT_UINT_BYTES:
4319 proto_tree_set_bytes(new_fi, value, n);
4320 break;
4321
4322 default:
4323 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4323
, __func__, "assertion \"not reached\" failed")
;
4324 }
4325
4326 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4327
4328 pi = proto_tree_add_node(tree, new_fi);
4329
4330 switch (hfinfo->type) {
4331
4332 case FT_STRINGZ:
4333 case FT_STRINGZPAD:
4334 case FT_STRINGZTRUNC:
4335 case FT_UINT_STRING:
4336 break;
4337
4338 case FT_STRING:
4339 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4340 break;
4341
4342 case FT_BYTES:
4343 case FT_UINT_BYTES:
4344 break;
4345
4346 default:
4347 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4347
, __func__, "assertion \"not reached\" failed")
;
4348 }
4349
4350 return pi;
4351}
4352
4353proto_item *
4354proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4355 tvbuff_t *tvb,
4356 const unsigned start, int length,
4357 const unsigned encoding,
4358 wmem_allocator_t *scope,
4359 char **retval)
4360{
4361 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4362 tvb, start, length, encoding, scope, retval, &length);
4363}
4364
4365proto_item *
4366proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4367 tvbuff_t *tvb,
4368 const unsigned start, int length, const unsigned encoding,
4369 wmem_allocator_t *scope, char **retval)
4370{
4371 header_field_info *hfinfo;
4372 field_info *new_fi;
4373 nstime_t time_stamp;
4374 int flags;
4375
4376 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4376, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4376,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4376, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4377
4378 switch (hfinfo->type) {
4379 case FT_ABSOLUTE_TIME:
4380 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4381 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4382 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4383 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4384 }
4385 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4386 break;
4387 case FT_RELATIVE_TIME:
4388 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4389 *retval = rel_time_to_secs_str(scope, &time_stamp);
4390 break;
4391 default:
4392 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)
4393 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4394 }
4395
4396 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4397
4398 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", 4398
, __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", 4398, "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", 4398, "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", 4398, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4399
4400 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4401
4402 switch (hfinfo->type) {
4403
4404 case FT_ABSOLUTE_TIME:
4405 case FT_RELATIVE_TIME:
4406 proto_tree_set_time(new_fi, &time_stamp);
4407 break;
4408 default:
4409 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4409
, __func__, "assertion \"not reached\" failed")
;
4410 }
4411
4412 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4413
4414 return proto_tree_add_node(tree, new_fi);
4415}
4416
4417/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4418 and returns proto_item* */
4419proto_item *
4420ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4421 const unsigned encoding)
4422{
4423 field_info *new_fi;
4424 header_field_info *hfinfo;
4425 int item_length;
4426 unsigned offset;
4427
4428 offset = ptvc->offset;
4429 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", 4429, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4429,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4429, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4430 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4431 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4432
4433 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4434
4435 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4436
4437 /* Coast clear. Try and fake it */
4438 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", 4438
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4438, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4438, "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", 4438, __func__, "Adding %s would put more than %d 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); } } }
;
4439
4440 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4441
4442 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4443 offset, length, encoding);
4444}
4445
4446/* Add an item to a proto_tree, using the text label registered to that item;
4447 the item is extracted from the tvbuff handed to it. */
4448proto_item *
4449proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4450 const unsigned start, int length, const unsigned encoding)
4451{
4452 field_info *new_fi;
4453 int item_length;
4454
4455 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", 4455,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4456
4457 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4458 test_length(hfinfo, tvb, start, item_length, encoding);
4459
4460 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4461
4462 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", 4462
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4462, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4463
4464 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4465
4466 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4467}
4468
4469proto_item *
4470proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4471 const unsigned start, int length, const unsigned encoding)
4472{
4473 register header_field_info *hfinfo;
4474
4475 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", 4475, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4475,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4476 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4477}
4478
4479/* Add an item to a proto_tree, using the text label registered to that item;
4480 the item is extracted from the tvbuff handed to it.
4481
4482 Return the length of the item through the pointer. */
4483proto_item *
4484proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4485 tvbuff_t *tvb, const unsigned start,
4486 int length, const unsigned encoding,
4487 int *lenretval)
4488{
4489 field_info *new_fi;
4490 int item_length;
4491 proto_item *item;
4492
4493 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", 4493,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4494
4495 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4496 test_length(hfinfo, tvb, start, item_length, encoding);
4497
4498 if (!tree) {
4499 /*
4500 * We need to get the correct item length here.
4501 * That's normally done by proto_tree_new_item(),
4502 * but we won't be calling it.
4503 */
4504 *lenretval = get_full_length(hfinfo, tvb, start, length,
4505 item_length, encoding);
4506 return NULL((void*)0);
4507 }
4508
4509 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", 4516
, __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", 4516, "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", 4516, "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", 4516
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4510 /*((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", 4516
, __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", 4516, "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", 4516, "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", 4516
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4511 * 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", 4516
, __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", 4516, "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", 4516, "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", 4516
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4512 * 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", 4516
, __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", 4516, "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", 4516, "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", 4516
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4513 */((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", 4516
, __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", 4516, "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", 4516, "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", 4516
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4514 *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", 4516
, __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", 4516, "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", 4516, "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", 4516
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4515 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", 4516
, __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", 4516, "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", 4516, "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", 4516
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4516 })((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", 4516
, __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", 4516, "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", 4516, "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", 4516
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4517
4518 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4519
4520 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4521 *lenretval = new_fi->length;
4522 return item;
4523}
4524
4525proto_item *
4526proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4527 const unsigned start, int length,
4528 const unsigned encoding, int *lenretval)
4529{
4530 register header_field_info *hfinfo;
4531
4532 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", 4532, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4532,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4532, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4533 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4534}
4535
4536/* which FT_ types can use proto_tree_add_bytes_item() */
4537static inline bool_Bool
4538validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4539{
4540 return (type == FT_BYTES ||
4541 type == FT_UINT_BYTES ||
4542 type == FT_OID ||
4543 type == FT_REL_OID ||
4544 type == FT_SYSTEM_ID );
4545}
4546
4547/* Note: this does no validation that the byte array of an FT_OID or
4548 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4549 so I think it's ok to continue not validating it?
4550 */
4551proto_item *
4552proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4553 const unsigned start, unsigned length,
4554 const unsigned encoding,
4555 GByteArray *retval, unsigned *endoff, int *err)
4556{
4557 field_info *new_fi;
4558 GByteArray *bytes = retval;
4559 GByteArray *created_bytes = NULL((void*)0);
4560 bool_Bool failed = false0;
4561 uint32_t n = 0;
4562 header_field_info *hfinfo;
4563 bool_Bool generate = (bytes || tree) ? true1 : false0;
4564
4565 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", 4565, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4565,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4565, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4566
4567 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", 4567,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4568
4569 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", 4570, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4570 "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", 4570, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4571
4572 if (length == 0) {
4573 return NULL((void*)0);
4574 }
4575
4576 if (encoding & ENC_STR_NUM0x01000000) {
4577 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"
)
;
4578 }
4579
4580 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4581 if (hfinfo->type == FT_UINT_BYTES) {
4582 /* can't decode FT_UINT_BYTES from strings */
4583 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")
4584 "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")
;
4585 }
4586
4587 unsigned hex_encoding = encoding;
4588 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4589 /* If none of the separator values are used,
4590 * assume no separator (the common case). */
4591 hex_encoding |= ENC_SEP_NONE0x00010000;
4592#if 0
4593 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")
4594 "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")
;
4595#endif
4596 }
4597
4598 if (!bytes) {
4599 /* caller doesn't care about return value, but we need it to
4600 call tvb_get_string_bytes() and set the tree later */
4601 bytes = created_bytes = g_byte_array_new();
4602 }
4603
4604 /*
4605 * bytes might be NULL after this, but can't add expert
4606 * error until later; if it's NULL, just note that
4607 * it failed.
4608 */
4609 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4610 if (bytes == NULL((void*)0))
4611 failed = true1;
4612 }
4613 else if (generate) {
4614 tvb_ensure_bytes_exist(tvb, start, length);
4615
4616 if (hfinfo->type == FT_UINT_BYTES) {
4617 n = length; /* n is now the "header" length */
4618 length = get_uint_value(tree, tvb, start, n, encoding);
4619 /* length is now the value's length; only store the value in the array */
4620 tvb_ensure_bytes_exist(tvb, start + n, length);
4621 if (!bytes) {
4622 /* caller doesn't care about return value, but
4623 * we may need it to set the tree later */
4624 bytes = created_bytes = g_byte_array_new();
4625 }
4626 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4627 }
4628 else if (length > 0) {
4629 if (!bytes) {
4630 /* caller doesn't care about return value, but
4631 * we may need it to set the tree later */
4632 bytes = created_bytes = g_byte_array_new();
4633 }
4634 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4635 }
4636
4637 if (endoff)
4638 *endoff = start + n + length;
4639 }
4640
4641 if (err)
4642 *err = failed ? EINVAL22 : 0;
4643
4644 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); }
4645 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4646 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); }
4647 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); }
4648 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); }
4649 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4650 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4651
4652 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", 4658
, __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", 4658, "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", 4658, "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", 4658
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4653 {((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", 4658
, __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", 4658, "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", 4658, "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", 4658
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4654 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", 4658
, __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", 4658, "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", 4658, "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", 4658
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4655 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", 4658
, __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", 4658, "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", 4658, "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", 4658
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4656 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", 4658
, __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", 4658, "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", 4658, "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", 4658
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4657 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", 4658
, __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", 4658, "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", 4658, "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", 4658
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4658 } )((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", 4658
, __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", 4658, "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", 4658, "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", 4658
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4659
4660 /* n will be zero except when it's a FT_UINT_BYTES */
4661 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4662
4663 if (encoding & ENC_STRING0x07000000) {
4664 if (failed)
4665 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4666
4667 if (bytes)
4668 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4669 else
4670 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4671
4672 if (created_bytes)
4673 g_byte_array_free(created_bytes, true1);
4674 }
4675 else {
4676 /* n will be zero except when it's a FT_UINT_BYTES */
4677 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4678
4679 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4680 * use the byte array created above in this case.
4681 */
4682 if (created_bytes)
4683 g_byte_array_free(created_bytes, true1);
4684
4685 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4686 (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)
;
4687 }
4688
4689 return proto_tree_add_node(tree, new_fi);
4690}
4691
4692
4693proto_item *
4694proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4695 const unsigned start, const unsigned length,
4696 const unsigned encoding,
4697 nstime_t *retval, unsigned *endoff, int *err)
4698{
4699 field_info *new_fi;
4700 nstime_t time_stamp;
4701 int saved_err = 0;
4702 header_field_info *hfinfo;
4703
4704 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", 4704, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4704,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4704, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4705
4706 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", 4706,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4707
4708 if (length == 0) {
4709 if(retval) {
4710 nstime_set_zero(retval);
4711 }
4712 return NULL((void*)0);
4713 }
4714
4715 nstime_set_zero(&time_stamp);
4716
4717 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4718 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", 4718, ((hfinfo))->abbrev))))
;
4719 /* The only string format that could be a relative time is
4720 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4721 * relative to "now" currently.
4722 */
4723 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4724 saved_err = EINVAL22;
4725 }
4726 else {
4727 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", 4727, ((hfinfo))->abbrev))))
;
4728 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4729
4730 tvb_ensure_bytes_exist(tvb, start, length);
4731 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4732 if (endoff) *endoff = start + length;
4733 }
4734
4735 if (err) *err = saved_err;
4736
4737 if (retval) {
4738 retval->secs = time_stamp.secs;
4739 retval->nsecs = time_stamp.nsecs;
4740 }
4741
4742 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4743
4744 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", 4744
, __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", 4744, "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", 4744, "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", 4744, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4745
4746 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4747
4748 proto_tree_set_time(new_fi, &time_stamp);
4749
4750 if (encoding & ENC_STRING0x07000000) {
4751 if (saved_err)
4752 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4753 }
4754 else {
4755 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4756 (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)
;
4757 }
4758
4759 return proto_tree_add_node(tree, new_fi);
4760}
4761
4762/* Add a FT_NONE to a proto_tree */
4763proto_item *
4764proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4765 const unsigned start, int length, const char *format,
4766 ...)
4767{
4768 proto_item *pi;
4769 va_list ap;
4770 header_field_info *hfinfo;
4771
4772 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4773
4774 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", 4774
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4774, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4774, "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", 4774, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4775
4776 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", 4776
, ((hfinfo))->abbrev))))
;
4777
4778 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4779
4780 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4780, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4781
4782 va_start(ap, format)__builtin_va_start(ap, format);
4783 proto_tree_set_representation(pi, format, ap);
4784 va_end(ap)__builtin_va_end(ap);
4785
4786 /* no value to set for FT_NONE */
4787 return pi;
4788}
4789
4790/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4791 * offset, and returns proto_item* */
4792proto_item *
4793ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4794 const unsigned encoding)
4795{
4796 proto_item *item;
4797
4798 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4799 length, encoding);
4800
4801 return item;
4802}
4803
4804/* Advance the ptvcursor's offset within its tvbuff without
4805 * adding anything to the proto_tree. */
4806void
4807ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4808{
4809 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4810 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4811 }
4812}
4813
4814
4815static void
4816proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4817{
4818 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4818, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4819 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4820}
4821
4822/* Add a FT_PROTOCOL to a proto_tree */
4823proto_item *
4824proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4825 unsigned start, int length, const char *format, ...)
4826{
4827 proto_item *pi;
4828 field_info *new_fi;
4829 tvbuff_t *protocol_tvb;
4830 va_list ap;
4831 header_field_info *hfinfo;
4832 char* protocol_rep;
4833
4834 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4835
4836 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", 4836
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4836, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4836, "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", 4836, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4837
4838 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"
, 4838, ((hfinfo))->abbrev))))
;
4839
4840 /*
4841 * This can throw an exception when it calls get_hfi_length before
4842 * it allocates anything, if length is nonzero and start is past
4843 * the end of the tvb. Afterwards it can't throw an exception,
4844 * as length is clamped to the captured length remaining.
4845 */
4846 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4847 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4848 /* Start the protocol_tvb at the correct start offset, but allow it
4849 * to be lengthened later via finfo_set_len. */
4850 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4851
4852 va_start(ap, format)__builtin_va_start(ap, format);
4853 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4854 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4855 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)
;
4856 va_end(ap)__builtin_va_end(ap);
4857
4858 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4858, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4859
4860 va_start(ap, format)__builtin_va_start(ap, format);
4861 proto_tree_set_representation(pi, format, ap);
4862 va_end(ap)__builtin_va_end(ap);
4863
4864 return pi;
4865}
4866
4867/* Add a FT_BYTES to a proto_tree */
4868proto_item *
4869proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4870 int length, const uint8_t *start_ptr)
4871{
4872 proto_item *pi;
4873 header_field_info *hfinfo;
4874 int item_length;
4875
4876 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", 4876, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4876,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4876, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4877 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4878 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4879
4880 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4881
4882 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", 4882
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4882, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4882, "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", 4882, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4883
4884 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",
4884, ((hfinfo))->abbrev))))
;
4885
4886 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4887 start_ptr = tvb_get_ptr(tvb, start, length);
4888
4889 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4890 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4891
4892 return pi;
4893}
4894
4895/* Add a FT_BYTES to a proto_tree */
4896proto_item *
4897proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4898 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4899{
4900 proto_item *pi;
4901 header_field_info *hfinfo;
4902 int item_length;
4903
4904 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", 4904, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4904,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4904, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4905 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4906 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4907
4908 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4909
4910 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", 4910
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4910, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4910, "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", 4910, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4911
4912 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",
4912, ((hfinfo))->abbrev))))
;
4913
4914 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4915 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4916
4917 return pi;
4918}
4919
4920proto_item *
4921proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4922 unsigned start, int length,
4923 const uint8_t *start_ptr,
4924 const char *format, ...)
4925{
4926 proto_item *pi;
4927 va_list ap;
4928
4929 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4930
4931 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; }
;
4932
4933 va_start(ap, format)__builtin_va_start(ap, format);
4934 proto_tree_set_representation_value(pi, format, ap);
4935 va_end(ap)__builtin_va_end(ap);
4936
4937 return pi;
4938}
4939
4940proto_item *
4941proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4942 unsigned start, int length, const uint8_t *start_ptr,
4943 const char *format, ...)
4944{
4945 proto_item *pi;
4946 va_list ap;
4947
4948 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4949
4950 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; }
;
4951
4952 va_start(ap, format)__builtin_va_start(ap, format);
4953 proto_tree_set_representation(pi, format, ap);
4954 va_end(ap)__builtin_va_end(ap);
4955
4956 return pi;
4957}
4958
4959static void
4960proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4961{
4962 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4962, "length >= 0"
))))
;
4963 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", 4963, "start_ptr != ((void*)0) || length == 0"
))))
;
4964
4965 fvalue_set_bytes_data(fi->value, start_ptr, length);
4966}
4967
4968
4969static void
4970proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
4971{
4972 tvb_ensure_bytes_exist(tvb, offset, length);
4973 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4974}
4975
4976static void
4977proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4978{
4979 GByteArray *bytes;
4980
4981 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4981, "value != ((void*)0)"
))))
;
4982
4983 bytes = byte_array_dup(value);
4984
4985 fvalue_set_byte_array(fi->value, bytes);
4986}
4987
4988/* Add a FT_*TIME to a proto_tree */
4989proto_item *
4990proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4991 unsigned length, const nstime_t *value_ptr)
4992{
4993 proto_item *pi;
4994 header_field_info *hfinfo;
4995
4996 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4997
4998 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", 4998
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4998, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4998, "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", 4998, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4999
5000 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", 5000, ((hfinfo))->abbrev))))
;
5001
5002 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5003 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5004
5005 return pi;
5006}
5007
5008proto_item *
5009proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5010 unsigned start, unsigned length, nstime_t *value_ptr,
5011 const char *format, ...)
5012{
5013 proto_item *pi;
5014 va_list ap;
5015
5016 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5017 if (pi != tree) {
5018 va_start(ap, format)__builtin_va_start(ap, format);
5019 proto_tree_set_representation_value(pi, format, ap);
5020 va_end(ap)__builtin_va_end(ap);
5021 }
5022
5023 return pi;
5024}
5025
5026proto_item *
5027proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5028 unsigned start, unsigned length, nstime_t *value_ptr,
5029 const char *format, ...)
5030{
5031 proto_item *pi;
5032 va_list ap;
5033
5034 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5035 if (pi != tree) {
5036 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5036, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5037
5038 va_start(ap, format)__builtin_va_start(ap, format);
5039 proto_tree_set_representation(pi, format, ap);
5040 va_end(ap)__builtin_va_end(ap);
5041 }
5042
5043 return pi;
5044}
5045
5046/* Set the FT_*TIME value */
5047static void
5048proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5049{
5050 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5050, "value_ptr != ((void*)0)"
))))
;
5051
5052 fvalue_set_time(fi->value, value_ptr);
5053}
5054
5055/* Add a FT_IPXNET to a proto_tree */
5056proto_item *
5057proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5058 unsigned length, uint32_t value)
5059{
5060 proto_item *pi;
5061 header_field_info *hfinfo;
5062
5063 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5064
5065 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", 5065
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5065, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5065, "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", 5065, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5066
5067 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"
, 5067, ((hfinfo))->abbrev))))
;
5068
5069 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5070 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5071
5072 return pi;
5073}
5074
5075proto_item *
5076proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5077 unsigned start, unsigned length, uint32_t value,
5078 const char *format, ...)
5079{
5080 proto_item *pi;
5081 va_list ap;
5082
5083 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5084 if (pi != tree) {
5085 va_start(ap, format)__builtin_va_start(ap, format);
5086 proto_tree_set_representation_value(pi, format, ap);
5087 va_end(ap)__builtin_va_end(ap);
5088 }
5089
5090 return pi;
5091}
5092
5093proto_item *
5094proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5095 unsigned start, unsigned length, uint32_t value,
5096 const char *format, ...)
5097{
5098 proto_item *pi;
5099 va_list ap;
5100
5101 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5102 if (pi != tree) {
5103 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5103, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5104
5105 va_start(ap, format)__builtin_va_start(ap, format);
5106 proto_tree_set_representation(pi, format, ap);
5107 va_end(ap)__builtin_va_end(ap);
5108 }
5109
5110 return pi;
5111}
5112
5113/* Set the FT_IPXNET value */
5114static void
5115proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5116{
5117 fvalue_set_uinteger(fi->value, value);
5118}
5119
5120/* Add a FT_IPv4 to a proto_tree */
5121proto_item *
5122proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5123 unsigned length, ws_in4_addr value)
5124{
5125 proto_item *pi;
5126 header_field_info *hfinfo;
5127
5128 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5129
5130 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", 5130
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5130, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5130, "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", 5130, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5131
5132 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", 5132
, ((hfinfo))->abbrev))))
;
5133
5134 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5135 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5136
5137 return pi;
5138}
5139
5140proto_item *
5141proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5142 unsigned start, unsigned length, ws_in4_addr value,
5143 const char *format, ...)
5144{
5145 proto_item *pi;
5146 va_list ap;
5147
5148 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5149 if (pi != tree) {
5150 va_start(ap, format)__builtin_va_start(ap, format);
5151 proto_tree_set_representation_value(pi, format, ap);
5152 va_end(ap)__builtin_va_end(ap);
5153 }
5154
5155 return pi;
5156}
5157
5158proto_item *
5159proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5160 unsigned start, unsigned length, ws_in4_addr value,
5161 const char *format, ...)
5162{
5163 proto_item *pi;
5164 va_list ap;
5165
5166 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5167 if (pi != tree) {
5168 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5168, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5169
5170 va_start(ap, format)__builtin_va_start(ap, format);
5171 proto_tree_set_representation(pi, format, ap);
5172 va_end(ap)__builtin_va_end(ap);
5173 }
5174
5175 return pi;
5176}
5177
5178/* Set the FT_IPv4 value */
5179static void
5180proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5181{
5182 ipv4_addr_and_mask ipv4;
5183 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5184 fvalue_set_ipv4(fi->value, &ipv4);
5185}
5186
5187/* Add a FT_IPv6 to a proto_tree */
5188proto_item *
5189proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5190 unsigned length, const ws_in6_addr *value)
5191{
5192 proto_item *pi;
5193 header_field_info *hfinfo;
5194
5195 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5196
5197 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", 5197
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5197, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5197, "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", 5197, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5198
5199 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", 5199
, ((hfinfo))->abbrev))))
;
5200
5201 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5202 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5203
5204 return pi;
5205}
5206
5207proto_item *
5208proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5209 unsigned start, unsigned length,
5210 const ws_in6_addr *value_ptr,
5211 const char *format, ...)
5212{
5213 proto_item *pi;
5214 va_list ap;
5215
5216 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5217 if (pi != tree) {
5218 va_start(ap, format)__builtin_va_start(ap, format);
5219 proto_tree_set_representation_value(pi, format, ap);
5220 va_end(ap)__builtin_va_end(ap);
5221 }
5222
5223 return pi;
5224}
5225
5226proto_item *
5227proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5228 unsigned start, unsigned length,
5229 const ws_in6_addr *value_ptr,
5230 const char *format, ...)
5231{
5232 proto_item *pi;
5233 va_list ap;
5234
5235 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5236 if (pi != tree) {
5237 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5237, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5238
5239 va_start(ap, format)__builtin_va_start(ap, format);
5240 proto_tree_set_representation(pi, format, ap);
5241 va_end(ap)__builtin_va_end(ap);
5242 }
5243
5244 return pi;
5245}
5246
5247/* Set the FT_IPv6 value */
5248static void
5249proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5250{
5251 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5251, "value != ((void*)0)"
))))
;
5252 ipv6_addr_and_prefix ipv6;
5253 ipv6.addr = *value;
5254 ipv6.prefix = 128;
5255 fvalue_set_ipv6(fi->value, &ipv6);
5256}
5257
5258static void
5259proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5260{
5261 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5262}
5263
5264/* Set the FT_FCWWN value */
5265static void
5266proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5267{
5268 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5268, "value_ptr != ((void*)0)"
))))
;
5269 fvalue_set_fcwwn(fi->value, value_ptr);
5270}
5271
5272static void
5273proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5274{
5275 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5276}
5277
5278/* Add a FT_GUID to a proto_tree */
5279proto_item *
5280proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5281 unsigned length, const e_guid_t *value_ptr)
5282{
5283 proto_item *pi;
5284 header_field_info *hfinfo;
5285
5286 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5287
5288 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", 5288
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5288, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5288, "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", 5288, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5289
5290 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", 5290
, ((hfinfo))->abbrev))))
;
5291
5292 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5293 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5294
5295 return pi;
5296}
5297
5298proto_item *
5299proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5300 unsigned start, unsigned length,
5301 const e_guid_t *value_ptr,
5302 const char *format, ...)
5303{
5304 proto_item *pi;
5305 va_list ap;
5306
5307 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5308 if (pi != tree) {
5309 va_start(ap, format)__builtin_va_start(ap, format);
5310 proto_tree_set_representation_value(pi, format, ap);
5311 va_end(ap)__builtin_va_end(ap);
5312 }
5313
5314 return pi;
5315}
5316
5317proto_item *
5318proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5319 unsigned start, unsigned length, const e_guid_t *value_ptr,
5320 const char *format, ...)
5321{
5322 proto_item *pi;
5323 va_list ap;
5324
5325 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5326 if (pi != tree) {
5327 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5327, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5328
5329 va_start(ap, format)__builtin_va_start(ap, format);
5330 proto_tree_set_representation(pi, format, ap);
5331 va_end(ap)__builtin_va_end(ap);
5332 }
5333
5334 return pi;
5335}
5336
5337/* Set the FT_GUID value */
5338static void
5339proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5340{
5341 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5341, "value_ptr != ((void*)0)"
))))
;
5342 fvalue_set_guid(fi->value, value_ptr);
5343}
5344
5345static void
5346proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5347 const unsigned encoding)
5348{
5349 e_guid_t guid;
5350
5351 tvb_get_guid(tvb, start, &guid, encoding);
5352 proto_tree_set_guid(fi, &guid);
5353}
5354
5355/* Add a FT_OID to a proto_tree */
5356proto_item *
5357proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5358 unsigned length, const uint8_t* value_ptr)
5359{
5360 proto_item *pi;
5361 header_field_info *hfinfo;
5362
5363 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5364
5365 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", 5365
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5365, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5365, "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", 5365, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5366
5367 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", 5367
, ((hfinfo))->abbrev))))
;
5368
5369 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5370 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5371
5372 return pi;
5373}
5374
5375proto_item *
5376proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5377 unsigned start, unsigned length,
5378 const uint8_t* value_ptr,
5379 const char *format, ...)
5380{
5381 proto_item *pi;
5382 va_list ap;
5383
5384 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5385 if (pi != tree) {
5386 va_start(ap, format)__builtin_va_start(ap, format);
5387 proto_tree_set_representation_value(pi, format, ap);
5388 va_end(ap)__builtin_va_end(ap);
5389 }
5390
5391 return pi;
5392}
5393
5394proto_item *
5395proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5396 unsigned start, unsigned length, const uint8_t* value_ptr,
5397 const char *format, ...)
5398{
5399 proto_item *pi;
5400 va_list ap;
5401
5402 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5403 if (pi != tree) {
5404 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5404, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5405
5406 va_start(ap, format)__builtin_va_start(ap, format);
5407 proto_tree_set_representation(pi, format, ap);
5408 va_end(ap)__builtin_va_end(ap);
5409 }
5410
5411 return pi;
5412}
5413
5414/* Set the FT_OID value */
5415static void
5416proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5417{
5418 GByteArray *bytes;
5419
5420 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", 5420, "value_ptr != ((void*)0) || length == 0"
))))
;
5421
5422 bytes = g_byte_array_new();
5423 if (length > 0) {
5424 g_byte_array_append(bytes, value_ptr, length);
5425 }
5426 fvalue_set_byte_array(fi->value, bytes);
5427}
5428
5429static void
5430proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5431{
5432 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5433}
5434
5435/* Set the FT_SYSTEM_ID value */
5436static void
5437proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5438{
5439 GByteArray *bytes;
5440
5441 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", 5441, "value_ptr != ((void*)0) || length == 0"
))))
;
5442
5443 bytes = g_byte_array_new();
5444 if (length > 0) {
5445 g_byte_array_append(bytes, value_ptr, length);
5446 }
5447 fvalue_set_byte_array(fi->value, bytes);
5448}
5449
5450static void
5451proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5452{
5453 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5454}
5455
5456/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5457 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5458 * is destroyed. */
5459proto_item *
5460proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5461 int length, const char* value)
5462{
5463 proto_item *pi;
5464 header_field_info *hfinfo;
5465 int item_length;
5466
5467 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", 5467, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5467,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5467, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5468 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5469 /*
5470 * Special case - if the length is 0, skip the test, so that
5471 * we can have an empty string right after the end of the
5472 * packet. (This handles URL-encoded forms where the last field
5473 * has no value so the form ends right after the =.)
5474 *
5475 * XXX - length zero makes sense for FT_STRING, and more or less
5476 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5477 * for FT_STRINGZ (except that a number of fields that should be
5478 * one of the others are actually registered as FT_STRINGZ.)
5479 */
5480 if (item_length != 0)
5481 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5482
5483 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5484
5485 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", 5485
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5485, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5485, "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", 5485, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5486
5487 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", 5487, ((hfinfo))->abbrev))))
;
5488
5489 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5490 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5490, "length >= 0"
))))
;
5491
5492 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", 5492, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5493 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5494
5495 return pi;
5496}
5497
5498proto_item *
5499proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5500 unsigned start, int length, const char* value,
5501 const char *format,
5502 ...)
5503{
5504 proto_item *pi;
5505 va_list ap;
5506
5507 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5508 if (pi != tree) {
5509 va_start(ap, format)__builtin_va_start(ap, format);
5510 proto_tree_set_representation_value(pi, format, ap);
5511 va_end(ap)__builtin_va_end(ap);
5512 }
5513
5514 return pi;
5515}
5516
5517proto_item *
5518proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5519 unsigned start, int length, const char* value,
5520 const char *format, ...)
5521{
5522 proto_item *pi;
5523 va_list ap;
5524
5525 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5526 if (pi != tree) {
5527 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5527, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5528
5529 va_start(ap, format)__builtin_va_start(ap, format);
5530 proto_tree_set_representation(pi, format, ap);
5531 va_end(ap)__builtin_va_end(ap);
5532 }
5533
5534 return pi;
5535}
5536
5537/* Set the FT_STRING value */
5538static void
5539proto_tree_set_string(field_info *fi, const char* value)
5540{
5541 if (value) {
5542 fvalue_set_string(fi->value, value);
5543 } else {
5544 /*
5545 * XXX - why is a null value for a string field
5546 * considered valid?
5547 */
5548 fvalue_set_string(fi->value, "[ Null ]");
5549 }
5550}
5551
5552/* Set the FT_AX25 value */
5553static void
5554proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5555{
5556 fvalue_set_ax25(fi->value, value);
5557}
5558
5559static void
5560proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5561{
5562 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5563}
5564
5565/* Set the FT_VINES value */
5566static void
5567proto_tree_set_vines(field_info *fi, const uint8_t* value)
5568{
5569 fvalue_set_vines(fi->value, value);
5570}
5571
5572static void
5573proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5574{
5575 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5576}
5577
5578/* Add a FT_ETHER to a proto_tree */
5579proto_item *
5580proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5581 unsigned length, const uint8_t* value)
5582{
5583 proto_item *pi;
5584 header_field_info *hfinfo;
5585
5586 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5587
5588 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", 5588
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5588, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5588, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5588, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5589
5590 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",
5590, ((hfinfo))->abbrev))))
;
5591
5592 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5593 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5594
5595 return pi;
5596}
5597
5598proto_item *
5599proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5600 unsigned start, unsigned length, const uint8_t* value,
5601 const char *format, ...)
5602{
5603 proto_item *pi;
5604 va_list ap;
5605
5606 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5607 if (pi != tree) {
5608 va_start(ap, format)__builtin_va_start(ap, format);
5609 proto_tree_set_representation_value(pi, format, ap);
5610 va_end(ap)__builtin_va_end(ap);
5611 }
5612
5613 return pi;
5614}
5615
5616proto_item *
5617proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5618 unsigned start, unsigned length, const uint8_t* value,
5619 const char *format, ...)
5620{
5621 proto_item *pi;
5622 va_list ap;
5623
5624 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5625 if (pi != tree) {
5626 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5626, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5627
5628 va_start(ap, format)__builtin_va_start(ap, format);
5629 proto_tree_set_representation(pi, format, ap);
5630 va_end(ap)__builtin_va_end(ap);
5631 }
5632
5633 return pi;
5634}
5635
5636/* Set the FT_ETHER value */
5637static void
5638proto_tree_set_ether(field_info *fi, const uint8_t* value)
5639{
5640 fvalue_set_ether(fi->value, value);
5641}
5642
5643static void
5644proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5645{
5646 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5647}
5648
5649/* Add a FT_BOOLEAN to a proto_tree */
5650proto_item *
5651proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5652 int length, uint64_t value)
5653{
5654 proto_item *pi;
5655 header_field_info *hfinfo;
5656
5657 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5658
5659 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", 5659
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5659, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5659, "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", 5659, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5660
5661 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"
, 5661, ((hfinfo))->abbrev))))
;
5662
5663 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5664 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5665
5666 return pi;
5667}
5668
5669proto_item *
5670proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5671 tvbuff_t *tvb, unsigned start, int length,
5672 uint64_t value, const char *format, ...)
5673{
5674 proto_item *pi;
5675 va_list ap;
5676
5677 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5678 if (pi != tree) {
5679 va_start(ap, format)__builtin_va_start(ap, format);
5680 proto_tree_set_representation_value(pi, format, ap);
5681 va_end(ap)__builtin_va_end(ap);
5682 }
5683
5684 return pi;
5685}
5686
5687proto_item *
5688proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5689 unsigned start, int length, uint64_t value,
5690 const char *format, ...)
5691{
5692 proto_item *pi;
5693 va_list ap;
5694
5695 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5696 if (pi != tree) {
5697 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5697, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5698
5699 va_start(ap, format)__builtin_va_start(ap, format);
5700 proto_tree_set_representation(pi, format, ap);
5701 va_end(ap)__builtin_va_end(ap);
5702 }
5703
5704 return pi;
5705}
5706
5707/* Set the FT_BOOLEAN value */
5708static void
5709proto_tree_set_boolean(field_info *fi, uint64_t value)
5710{
5711 proto_tree_set_uint64(fi, value);
5712}
5713
5714/* Generate, into "buf", a string showing the bits of a bitfield.
5715 Return a pointer to the character after that string. */
5716static char *
5717other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5718{
5719 int i = 0;
5720 uint64_t bit;
5721 char *p;
5722
5723 p = buf;
5724
5725 /* This is a devel error. It is safer to stop here. */
5726 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5726, "width >= 1"
))))
;
5727
5728 bit = UINT64_C(1)1UL << (width - 1);
5729 for (;;) {
5730 if (mask & bit) {
5731 /* This bit is part of the field. Show its value. */
5732 if (val & bit)
5733 *p++ = '1';
5734 else
5735 *p++ = '0';
5736 } else {
5737 /* This bit is not part of the field. */
5738 *p++ = '.';
5739 }
5740 bit >>= 1;
5741 i++;
5742 if (i >= width)
5743 break;
5744 if (i % 4 == 0)
5745 *p++ = ' ';
5746 }
5747 *p = '\0';
5748 return p;
5749}
5750
5751static char *
5752decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5753{
5754 char *p;
5755
5756 p = other_decode_bitfield_value(buf, val, mask, width);
5757 p = g_stpcpy(p, " = ");
5758
5759 return p;
5760}
5761
5762static char *
5763other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5764{
5765 int i = 0;
5766 uint64_t bit;
5767 char *p;
5768
5769 p = buf;
5770
5771 /* This is a devel error. It is safer to stop here. */
5772 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5772, "width >= 1"
))))
;
5773
5774 bit = UINT64_C(1)1UL << (width - 1);
5775 for (;;) {
5776 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5777 (mask & bit)) {
5778 /* This bit is part of the field. Show its value. */
5779 if (val & bit)
5780 *p++ = '1';
5781 else
5782 *p++ = '0';
5783 } else {
5784 /* This bit is not part of the field. */
5785 *p++ = '.';
5786 }
5787 bit >>= 1;
5788 i++;
5789 if (i >= width)
5790 break;
5791 if (i % 4 == 0)
5792 *p++ = ' ';
5793 }
5794
5795 *p = '\0';
5796 return p;
5797}
5798
5799static char *
5800decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5801{
5802 char *p;
5803
5804 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5805 p = g_stpcpy(p, " = ");
5806
5807 return p;
5808}
5809
5810/* Add a FT_FLOAT to a proto_tree */
5811proto_item *
5812proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5813 int length, float value)
5814{
5815 proto_item *pi;
5816 header_field_info *hfinfo;
5817
5818 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5819
5820 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5820
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5820, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5820, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5820, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5821
5822 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_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",
5822, ((hfinfo))->abbrev))))
;
5823
5824 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5825 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5826
5827 return pi;
5828}
5829
5830proto_item *
5831proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5832 unsigned start, int length, float value,
5833 const char *format, ...)
5834{
5835 proto_item *pi;
5836 va_list ap;
5837
5838 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5839 if (pi != tree) {
5840 va_start(ap, format)__builtin_va_start(ap, format);
5841 proto_tree_set_representation_value(pi, format, ap);
5842 va_end(ap)__builtin_va_end(ap);
5843 }
5844
5845 return pi;
5846}
5847
5848proto_item *
5849proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5850 unsigned start, int length, float value,
5851 const char *format, ...)
5852{
5853 proto_item *pi;
5854 va_list ap;
5855
5856 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5857 if (pi != tree) {
5858 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5858, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5859
5860 va_start(ap, format)__builtin_va_start(ap, format);
5861 proto_tree_set_representation(pi, format, ap);
5862 va_end(ap)__builtin_va_end(ap);
5863 }
5864
5865 return pi;
5866}
5867
5868/* Set the FT_FLOAT value */
5869static void
5870proto_tree_set_float(field_info *fi, float value)
5871{
5872 fvalue_set_floating(fi->value, value);
5873}
5874
5875/* Add a FT_DOUBLE to a proto_tree */
5876proto_item *
5877proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5878 int length, double value)
5879{
5880 proto_item *pi;
5881 header_field_info *hfinfo;
5882
5883 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5884
5885 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5885
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5885, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5885, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5885, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5886
5887 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"
, 5887, ((hfinfo))->abbrev))))
;
5888
5889 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5890 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5891
5892 return pi;
5893}
5894
5895proto_item *
5896proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5897 unsigned start, int length, double value,
5898 const char *format, ...)
5899{
5900 proto_item *pi;
5901 va_list ap;
5902
5903 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5904 if (pi != tree) {
5905 va_start(ap, format)__builtin_va_start(ap, format);
5906 proto_tree_set_representation_value(pi, format, ap);
5907 va_end(ap)__builtin_va_end(ap);
5908 }
5909
5910 return pi;
5911}
5912
5913proto_item *
5914proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5915 unsigned start, int length, double value,
5916 const char *format, ...)
5917{
5918 proto_item *pi;
5919 va_list ap;
5920
5921 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5922 if (pi != tree) {
5923 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5923, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5924
5925 va_start(ap, format)__builtin_va_start(ap, format);
5926 proto_tree_set_representation(pi, format, ap);
5927 va_end(ap)__builtin_va_end(ap);
5928 }
5929
5930 return pi;
5931}
5932
5933/* Set the FT_DOUBLE value */
5934static void
5935proto_tree_set_double(field_info *fi, double value)
5936{
5937 fvalue_set_floating(fi->value, value);
5938}
5939
5940/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5941proto_item *
5942proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5943 int length, uint32_t value)
5944{
5945 proto_item *pi = NULL((void*)0);
5946 header_field_info *hfinfo;
5947
5948 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5949
5950 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", 5950
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5950, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5950, "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", 5950, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5951
5952 switch (hfinfo->type) {
5953 case FT_CHAR:
5954 case FT_UINT8:
5955 case FT_UINT16:
5956 case FT_UINT24:
5957 case FT_UINT32:
5958 case FT_FRAMENUM:
5959 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5960 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5961 break;
5962
5963 default:
5964 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)
5965 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)
;
5966 }
5967
5968 return pi;
5969}
5970
5971proto_item *
5972proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5973 unsigned start, int length, uint32_t value,
5974 const char *format, ...)
5975{
5976 proto_item *pi;
5977 va_list ap;
5978
5979 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5980 if (pi != tree) {
5981 va_start(ap, format)__builtin_va_start(ap, format);
5982 proto_tree_set_representation_value(pi, format, ap);
5983 va_end(ap)__builtin_va_end(ap);
5984 }
5985
5986 return pi;
5987}
5988
5989proto_item *
5990proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5991 unsigned start, int length, uint32_t value,
5992 const char *format, ...)
5993{
5994 proto_item *pi;
5995 va_list ap;
5996
5997 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5998 if (pi != tree) {
5999 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5999, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6000
6001 va_start(ap, format)__builtin_va_start(ap, format);
6002 proto_tree_set_representation(pi, format, ap);
6003 va_end(ap)__builtin_va_end(ap);
6004 }
6005
6006 return pi;
6007}
6008
6009/* Set the FT_UINT{8,16,24,32} value */
6010static void
6011proto_tree_set_uint(field_info *fi, uint32_t value)
6012{
6013 const header_field_info *hfinfo;
6014 uint32_t integer;
6015
6016 hfinfo = fi->hfinfo;
6017 integer = value;
6018
6019 if (hfinfo->bitmask) {
6020 /* Mask out irrelevant portions */
6021 integer &= (uint32_t)(hfinfo->bitmask);
6022
6023 /* Shift bits */
6024 integer >>= hfinfo_bitshift(hfinfo);
6025
6026 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6027 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)
;
6028 }
6029
6030 fvalue_set_uinteger(fi->value, integer);
6031}
6032
6033/* Add FT_UINT{40,48,56,64} to a proto_tree */
6034proto_item *
6035proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6036 int length, uint64_t value)
6037{
6038 proto_item *pi = NULL((void*)0);
6039 header_field_info *hfinfo;
6040
6041 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6042
6043 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", 6043
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6043, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6043, "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", 6043, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6044
6045 switch (hfinfo->type) {
6046 case FT_UINT40:
6047 case FT_UINT48:
6048 case FT_UINT56:
6049 case FT_UINT64:
6050 case FT_FRAMENUM:
6051 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6052 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6053 break;
6054
6055 default:
6056 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)
6057 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)
;
6058 }
6059
6060 return pi;
6061}
6062
6063proto_item *
6064proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6065 unsigned start, int length, uint64_t value,
6066 const char *format, ...)
6067{
6068 proto_item *pi;
6069 va_list ap;
6070
6071 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6072 if (pi != tree) {
6073 va_start(ap, format)__builtin_va_start(ap, format);
6074 proto_tree_set_representation_value(pi, format, ap);
6075 va_end(ap)__builtin_va_end(ap);
6076 }
6077
6078 return pi;
6079}
6080
6081proto_item *
6082proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6083 unsigned start, int length, uint64_t value,
6084 const char *format, ...)
6085{
6086 proto_item *pi;
6087 va_list ap;
6088
6089 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6090 if (pi != tree) {
6091 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6091, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6092
6093 va_start(ap, format)__builtin_va_start(ap, format);
6094 proto_tree_set_representation(pi, format, ap);
6095 va_end(ap)__builtin_va_end(ap);
6096 }
6097
6098 return pi;
6099}
6100
6101/* Set the FT_UINT{40,48,56,64} value */
6102static void
6103proto_tree_set_uint64(field_info *fi, uint64_t value)
6104{
6105 const header_field_info *hfinfo;
6106 uint64_t integer;
6107
6108 hfinfo = fi->hfinfo;
6109 integer = value;
6110
6111 if (hfinfo->bitmask) {
6112 /* Mask out irrelevant portions */
6113 integer &= hfinfo->bitmask;
6114
6115 /* Shift bits */
6116 integer >>= hfinfo_bitshift(hfinfo);
6117
6118 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6119 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)
;
6120 }
6121
6122 fvalue_set_uinteger64(fi->value, integer);
6123}
6124
6125/* Add FT_INT{8,16,24,32} to a proto_tree */
6126proto_item *
6127proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6128 int length, int32_t value)
6129{
6130 proto_item *pi = NULL((void*)0);
6131 header_field_info *hfinfo;
6132
6133 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6134
6135 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", 6135
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6135, "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", 6135, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6136
6137 switch (hfinfo->type) {
6138 case FT_INT8:
6139 case FT_INT16:
6140 case FT_INT24:
6141 case FT_INT32:
6142 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6143 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6144 break;
6145
6146 default:
6147 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)
6148 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6149 }
6150
6151 return pi;
6152}
6153
6154proto_item *
6155proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6156 unsigned start, int length, int32_t value,
6157 const char *format, ...)
6158{
6159 proto_item *pi;
6160 va_list ap;
6161
6162 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6163 if (pi != tree) {
6164 va_start(ap, format)__builtin_va_start(ap, format);
6165 proto_tree_set_representation_value(pi, format, ap);
6166 va_end(ap)__builtin_va_end(ap);
6167 }
6168
6169 return pi;
6170}
6171
6172proto_item *
6173proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6174 unsigned start, int length, int32_t value,
6175 const char *format, ...)
6176{
6177 proto_item *pi;
6178 va_list ap;
6179
6180 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6181 if (pi != tree) {
6182 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6182, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6183
6184 va_start(ap, format)__builtin_va_start(ap, format);
6185 proto_tree_set_representation(pi, format, ap);
6186 va_end(ap)__builtin_va_end(ap);
6187 }
6188
6189 return pi;
6190}
6191
6192/* Set the FT_INT{8,16,24,32} value */
6193static void
6194proto_tree_set_int(field_info *fi, int32_t value)
6195{
6196 const header_field_info *hfinfo;
6197 uint32_t integer;
6198 int no_of_bits;
6199
6200 hfinfo = fi->hfinfo;
6201 integer = (uint32_t) value;
6202
6203 if (hfinfo->bitmask) {
6204 /* Mask out irrelevant portions */
6205 integer &= (uint32_t)(hfinfo->bitmask);
6206
6207 /* Shift bits */
6208 integer >>= hfinfo_bitshift(hfinfo);
6209
6210 no_of_bits = ws_count_ones(hfinfo->bitmask);
6211 integer = ws_sign_ext32(integer, no_of_bits);
6212
6213 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6214 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)
;
6215 }
6216
6217 fvalue_set_sinteger(fi->value, integer);
6218}
6219
6220/* Add FT_INT{40,48,56,64} to a proto_tree */
6221proto_item *
6222proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6223 int length, int64_t value)
6224{
6225 proto_item *pi = NULL((void*)0);
6226 header_field_info *hfinfo;
6227
6228 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6229
6230 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", 6230
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6230, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6230, "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", 6230, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6231
6232 switch (hfinfo->type) {
6233 case FT_INT40:
6234 case FT_INT48:
6235 case FT_INT56:
6236 case FT_INT64:
6237 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6238 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6239 break;
6240
6241 default:
6242 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)
6243 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6244 }
6245
6246 return pi;
6247}
6248
6249proto_item *
6250proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6251 unsigned start, int length, int64_t value,
6252 const char *format, ...)
6253{
6254 proto_item *pi;
6255 va_list ap;
6256
6257 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6258 if (pi != tree) {
6259 va_start(ap, format)__builtin_va_start(ap, format);
6260 proto_tree_set_representation_value(pi, format, ap);
6261 va_end(ap)__builtin_va_end(ap);
6262 }
6263
6264 return pi;
6265}
6266
6267/* Set the FT_INT{40,48,56,64} value */
6268static void
6269proto_tree_set_int64(field_info *fi, int64_t value)
6270{
6271 const header_field_info *hfinfo;
6272 uint64_t integer;
6273 int no_of_bits;
6274
6275 hfinfo = fi->hfinfo;
6276 integer = value;
6277
6278 if (hfinfo->bitmask) {
6279 /* Mask out irrelevant portions */
6280 integer &= hfinfo->bitmask;
6281
6282 /* Shift bits */
6283 integer >>= hfinfo_bitshift(hfinfo);
6284
6285 no_of_bits = ws_count_ones(hfinfo->bitmask);
6286 integer = ws_sign_ext64(integer, no_of_bits);
6287
6288 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6289 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)
;
6290 }
6291
6292 fvalue_set_sinteger64(fi->value, integer);
6293}
6294
6295proto_item *
6296proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6297 unsigned start, int length, int64_t value,
6298 const char *format, ...)
6299{
6300 proto_item *pi;
6301 va_list ap;
6302
6303 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6304 if (pi != tree) {
6305 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6305, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6306
6307 va_start(ap, format)__builtin_va_start(ap, format);
6308 proto_tree_set_representation(pi, format, ap);
6309 va_end(ap)__builtin_va_end(ap);
6310 }
6311
6312 return pi;
6313}
6314
6315/* Add a FT_EUI64 to a proto_tree */
6316proto_item *
6317proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6318 int length, const uint64_t value)
6319{
6320 proto_item *pi;
6321 header_field_info *hfinfo;
6322
6323 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6324
6325 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", 6325
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6325, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6325, "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", 6325, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6326
6327 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",
6327, ((hfinfo))->abbrev))))
;
6328
6329 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6330 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6331
6332 return pi;
6333}
6334
6335proto_item *
6336proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6337 unsigned start, int length, const uint64_t value,
6338 const char *format, ...)
6339{
6340 proto_item *pi;
6341 va_list ap;
6342
6343 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6344 if (pi != tree) {
6345 va_start(ap, format)__builtin_va_start(ap, format);
6346 proto_tree_set_representation_value(pi, format, ap);
6347 va_end(ap)__builtin_va_end(ap);
6348 }
6349
6350 return pi;
6351}
6352
6353proto_item *
6354proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6355 unsigned start, int length, const uint64_t value,
6356 const char *format, ...)
6357{
6358 proto_item *pi;
6359 va_list ap;
6360
6361 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6362 if (pi != tree) {
6363 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6363, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6364
6365 va_start(ap, format)__builtin_va_start(ap, format);
6366 proto_tree_set_representation(pi, format, ap);
6367 va_end(ap)__builtin_va_end(ap);
6368 }
6369
6370 return pi;
6371}
6372
6373/* Set the FT_EUI64 value */
6374static void
6375proto_tree_set_eui64(field_info *fi, const uint64_t value)
6376{
6377 uint8_t v[FT_EUI64_LEN8];
6378 phtonu64(v, value);
6379 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6380}
6381
6382static void
6383proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6384{
6385 if (encoding)
6386 {
6387 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6388 } else {
6389 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6390 }
6391}
6392
6393proto_item *
6394proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6395 const mac_hf_list_t *list_generic,
6396 int idx, tvbuff_t *tvb,
6397 proto_tree *tree, unsigned offset)
6398{
6399 uint8_t addr[6];
6400 const char *addr_name = NULL((void*)0);
6401 const char *oui_name = NULL((void*)0);
6402 proto_item *addr_item = NULL((void*)0);
6403 proto_tree *addr_tree = NULL((void*)0);
6404 proto_item *ret_val = NULL((void*)0);
6405
6406 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6407 return NULL((void*)0);
6408 }
6409
6410 /* Resolve what we can of the address */
6411 tvb_memcpy(tvb, addr, offset, sizeof addr);
6412 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6413 addr_name = get_ether_name(addr);
6414 }
6415 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6416 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6417 }
6418
6419 /* Add the item for the specific address type */
6420 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6421 if (idx >= 0) {
6422 addr_tree = proto_item_add_subtree(ret_val, idx);
6423 }
6424 else {
6425 addr_tree = tree;
6426 }
6427
6428 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6429 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6430 tvb, offset, 6, addr_name);
6431 proto_item_set_generated(addr_item);
6432 proto_item_set_hidden(addr_item);
6433 }
6434
6435 if (list_specific->hf_oui != NULL((void*)0)) {
6436 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6437 proto_item_set_generated(addr_item);
6438 proto_item_set_hidden(addr_item);
6439
6440 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6441 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6442 proto_item_set_generated(addr_item);
6443 proto_item_set_hidden(addr_item);
6444 }
6445 }
6446
6447 if (list_specific->hf_lg != NULL((void*)0)) {
6448 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6449 }
6450 if (list_specific->hf_ig != NULL((void*)0)) {
6451 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6452 }
6453
6454 /* Were we given a list for generic address fields? If not, stop here */
6455 if (list_generic == NULL((void*)0)) {
6456 return ret_val;
6457 }
6458
6459 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6460 proto_item_set_hidden(addr_item);
6461
6462 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6463 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6464 tvb, offset, 6, addr_name);
6465 proto_item_set_generated(addr_item);
6466 proto_item_set_hidden(addr_item);
6467 }
6468
6469 if (list_generic->hf_oui != NULL((void*)0)) {
6470 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6471 proto_item_set_generated(addr_item);
6472 proto_item_set_hidden(addr_item);
6473
6474 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6475 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6476 proto_item_set_generated(addr_item);
6477 proto_item_set_hidden(addr_item);
6478 }
6479 }
6480
6481 if (list_generic->hf_lg != NULL((void*)0)) {
6482 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6483 proto_item_set_hidden(addr_item);
6484 }
6485 if (list_generic->hf_ig != NULL((void*)0)) {
6486 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6487 proto_item_set_hidden(addr_item);
6488 }
6489 return ret_val;
6490}
6491
6492static proto_item *
6493proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6494{
6495 proto_node *pnode, *tnode, *sibling;
6496 field_info *tfi;
6497 unsigned depth = 1;
6498
6499 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6499, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6500
6501 /*
6502 * Restrict our depth. proto_tree_traverse_pre_order and
6503 * proto_tree_traverse_post_order (and possibly others) are recursive
6504 * so we need to be mindful of our stack size.
6505 */
6506 if (tree->first_child == NULL((void*)0)) {
6507 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6508 depth++;
6509 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6510 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__)), 6513)))
6511 "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__)), 6513)))
6512 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__)), 6513)))
6513 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__)), 6513)))
;
6514 }
6515 }
6516 }
6517
6518 /*
6519 * Make sure "tree" is ready to have subtrees under it, by
6520 * checking whether it's been given an ett_ value.
6521 *
6522 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6523 * node of the protocol tree. That node is not displayed,
6524 * so it doesn't need an ett_ value to remember whether it
6525 * was expanded.
6526 */
6527 tnode = tree;
6528 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6529 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6530 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"
, 6531)
6531 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"
, 6531)
;
6532 /* XXX - is it safe to continue here? */
6533 }
6534
6535 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6536 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6537 pnode->parent = tnode;
6538 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6539 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6540 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6541
6542 if (tnode->last_child != NULL((void*)0)) {
6543 sibling = tnode->last_child;
6544 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6544, "sibling->next == ((void*)0)"
))))
;
6545 sibling->next = pnode;
6546 } else
6547 tnode->first_child = pnode;
6548 tnode->last_child = pnode;
6549
6550 /* We should not be adding a fake node for an interesting field */
6551 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", 6551, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6552
6553 /* XXX - Should the proto_item have a header_field_info member, at least
6554 * for faked items, to know what hfi was faked? (Some dissectors look at
6555 * the tree items directly.)
6556 */
6557 return (proto_item *)pnode;
6558}
6559
6560/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6561static proto_item *
6562proto_tree_add_node(proto_tree *tree, field_info *fi)
6563{
6564 proto_node *pnode, *tnode, *sibling;
6565 field_info *tfi;
6566 unsigned depth = 1;
6567
6568 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6568, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6569
6570 /*
6571 * Restrict our depth. proto_tree_traverse_pre_order and
6572 * proto_tree_traverse_post_order (and possibly others) are recursive
6573 * so we need to be mindful of our stack size.
6574 */
6575 if (tree->first_child == NULL((void*)0)) {
6576 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6577 depth++;
6578 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6579 fvalue_free(fi->value);
6580 fi->value = NULL((void*)0);
6581 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__)), 6584)))
6582 "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__)), 6584)))
6583 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__)), 6584)))
6584 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__)), 6584)))
;
6585 }
6586 }
6587 }
6588
6589 /*
6590 * Make sure "tree" is ready to have subtrees under it, by
6591 * checking whether it's been given an ett_ value.
6592 *
6593 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6594 * node of the protocol tree. That node is not displayed,
6595 * so it doesn't need an ett_ value to remember whether it
6596 * was expanded.
6597 */
6598 tnode = tree;
6599 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6600 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6601 /* Since we are not adding fi to a node, its fvalue won't get
6602 * freed by proto_tree_free_node(), so free it now.
6603 */
6604 fvalue_free(fi->value);
6605 fi->value = NULL((void*)0);
6606 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", 6607)
6607 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", 6607)
;
6608 /* XXX - is it safe to continue here? */
6609 }
6610
6611 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6612 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6613 pnode->parent = tnode;
6614 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6615 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6616 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6617
6618 if (tnode->last_child != NULL((void*)0)) {
6619 sibling = tnode->last_child;
6620 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6620, "sibling->next == ((void*)0)"
))))
;
6621 sibling->next = pnode;
6622 } else
6623 tnode->first_child = pnode;
6624 tnode->last_child = pnode;
6625
6626 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6627
6628 return (proto_item *)pnode;
6629}
6630
6631
6632/* Generic way to allocate field_info and add to proto_tree.
6633 * Sets *pfi to address of newly-allocated field_info struct */
6634static proto_item *
6635proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6636 int *length)
6637{
6638 proto_item *pi;
6639 field_info *fi;
6640 int item_length;
6641
6642 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6643 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6644 pi = proto_tree_add_node(tree, fi);
6645
6646 return pi;
6647}
6648
6649/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6650 * Eventually this should replace the other function.
6651 * Sets *pfi to address of newly-allocated field_info struct */
6652static proto_item *
6653proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6654 unsigned *length)
6655{
6656 proto_item *pi;
6657 field_info *fi;
6658 unsigned item_length;
6659
6660 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6661 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6662 pi = proto_tree_add_node(tree, fi);
6663
6664 return pi;
6665}
6666
6667static void
6668get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6669 int *item_length, const unsigned encoding)
6670{
6671 int length_remaining;
6672
6673 /*
6674 * We only allow a null tvbuff if the item has a zero length,
6675 * i.e. if there's no data backing it.
6676 */
6677 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", 6677, "tvb != ((void*)0) || *length == 0"
))))
;
6678
6679 /*
6680 * XXX - in some protocols, there are 32-bit unsigned length
6681 * fields, so lengths in protocol tree and tvbuff routines
6682 * should really be unsigned. We should have, for those
6683 * field types for which "to the end of the tvbuff" makes sense,
6684 * additional routines that take no length argument and
6685 * add fields that run to the end of the tvbuff.
6686 */
6687 if (*length == -1) {
6688 /*
6689 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6690 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6691 * of -1 means "set the length to what remains in the
6692 * tvbuff".
6693 *
6694 * The assumption is either that
6695 *
6696 * 1) the length of the item can only be determined
6697 * by dissection (typically true of items with
6698 * subitems, which are probably FT_NONE or
6699 * FT_PROTOCOL)
6700 *
6701 * or
6702 *
6703 * 2) if the tvbuff is "short" (either due to a short
6704 * snapshot length or due to lack of reassembly of
6705 * fragments/segments/whatever), we want to display
6706 * what's available in the field (probably FT_BYTES
6707 * or FT_STRING) and then throw an exception later
6708 *
6709 * or
6710 *
6711 * 3) the field is defined to be "what's left in the
6712 * packet"
6713 *
6714 * so we set the length to what remains in the tvbuff so
6715 * that, if we throw an exception while dissecting, it
6716 * has what is probably the right value.
6717 *
6718 * For FT_STRINGZ, it means "the string is null-terminated,
6719 * not null-padded; set the length to the actual length
6720 * of the string", and if the tvbuff if short, we just
6721 * throw an exception.
6722 *
6723 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6724 * it means "find the end of the string",
6725 * and if the tvbuff if short, we just throw an exception.
6726 *
6727 * It's not valid for any other type of field. For those
6728 * fields, we treat -1 the same way we treat other
6729 * negative values - we assume the length is a Really
6730 * Big Positive Number, and throw a ReportedBoundsError
6731 * exception, under the assumption that the Really Big
6732 * Length would run past the end of the packet.
6733 */
6734 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
))
)) {
6735 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6736 /*
6737 * Leave the length as -1, so our caller knows
6738 * it was -1.
6739 */
6740 *item_length = *length;
6741 return;
6742 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6743 switch (tvb_get_uint8(tvb, start) >> 6)
6744 {
6745 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6746 *item_length = 1;
6747 break;
6748 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6749 *item_length = 2;
6750 break;
6751 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6752 *item_length = 4;
6753 break;
6754 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6755 *item_length = 8;
6756 break;
6757 }
6758 }
6759 }
6760
6761 switch (hfinfo->type) {
6762
6763 case FT_PROTOCOL:
6764 case FT_NONE:
6765 case FT_BYTES:
6766 case FT_STRING:
6767 case FT_STRINGZPAD:
6768 case FT_STRINGZTRUNC:
6769 /*
6770 * We allow FT_PROTOCOLs to be zero-length -
6771 * for example, an ONC RPC NULL procedure has
6772 * neither arguments nor reply, so the
6773 * payload for that protocol is empty.
6774 *
6775 * We also allow the others to be zero-length -
6776 * because that's the way the code has been for a
6777 * long, long time.
6778 *
6779 * However, we want to ensure that the start
6780 * offset is not *past* the byte past the end
6781 * of the tvbuff: we throw an exception in that
6782 * case.
6783 */
6784 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6785 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6785, "*length >= 0"
))))
;
6786 break;
6787
6788 case FT_STRINGZ:
6789 /*
6790 * Leave the length as -1, so our caller knows
6791 * it was -1.
6792 */
6793 break;
6794
6795 default:
6796 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6797 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6797))
;
6798 }
6799 *item_length = *length;
6800 } else {
6801 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6802 /*
6803 * These types are for interior nodes of the
6804 * tree, and don't have data associated with
6805 * them; if the length is negative (XXX - see
6806 * above) or goes past the end of the tvbuff,
6807 * cut it short at the end of the tvbuff.
6808 * That way, if this field is selected in
6809 * Wireshark, we don't highlight stuff past
6810 * the end of the data.
6811 *
6812 * If we don't have a tvb, then length must be zero,
6813 * per the DISSECTOR_ASSERT() above.
6814 *
6815 * If we do have a tvb, and the length requested is
6816 * nonzero, we want to ensure that the start offset
6817 * is not *past* the byte past the end of the tvbuff
6818 * data: we throw an exception in that case as above.
6819 */
6820 if (tvb && *length) {
6821 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6822 if (*length < 0 ||
6823 (*length > 0 &&
6824 (length_remaining < *length)))
6825 *length = length_remaining;
6826 }
6827 }
6828 *item_length = *length;
6829 if (*item_length < 0) {
6830 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6831 }
6832 }
6833}
6834
6835static void
6836get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6837 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6838{
6839 unsigned length_remaining;
6840
6841 /*
6842 * We only allow a null tvbuff if the item has a zero length,
6843 * i.e. if there's no data backing it.
6844 */
6845 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", 6845, "tvb != ((void*)0) || *length == 0"
))))
;
6846
6847
6848 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6849 /*
6850 * These types are for interior nodes of the
6851 * tree, and don't have data associated with
6852 * them; if the length is negative (XXX - see
6853 * above) or goes past the end of the tvbuff,
6854 * cut it short at the end of the tvbuff.
6855 * That way, if this field is selected in
6856 * Wireshark, we don't highlight stuff past
6857 * the end of the data.
6858 *
6859 * If we don't have a tvb, then length must be zero,
6860 * per the DISSECTOR_ASSERT() above.
6861 *
6862 * If we do have a tvb, and the length requested is
6863 * nonzero, we want to ensure that the start offset
6864 * is not *past* the byte past the end of the tvbuff
6865 * data: we throw an exception in that case as above.
6866 * (If the length requested is zero, then it's quite
6867 * likely that the start offset is the byte past the
6868 * end, but that's ok.)
6869 */
6870 if (tvb && *length) {
6871 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6872 if (length_remaining < *length) {
6873 *length = length_remaining;
6874 }
6875 }
6876 }
6877 *item_length = *length;
6878}
6879
6880static int
6881get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6882 int length, unsigned item_length, const int encoding)
6883{
6884 uint32_t n;
6885
6886 /*
6887 * We need to get the correct item length here.
6888 * That's normally done by proto_tree_new_item(),
6889 * but we won't be calling it.
6890 */
6891 switch (hfinfo->type) {
6892
6893 case FT_NONE:
6894 case FT_PROTOCOL:
6895 case FT_BYTES:
6896 /*
6897 * The length is the specified length.
6898 */
6899 break;
6900
6901 case FT_UINT_BYTES:
6902 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6903 item_length += n;
6904 if ((int)item_length < length) {
6905 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6906 }
6907 break;
6908
6909 /* XXX - make these just FT_UINT? */
6910 case FT_UINT8:
6911 case FT_UINT16:
6912 case FT_UINT24:
6913 case FT_UINT32:
6914 case FT_UINT40:
6915 case FT_UINT48:
6916 case FT_UINT56:
6917 case FT_UINT64:
6918 /* XXX - make these just FT_INT? */
6919 case FT_INT8:
6920 case FT_INT16:
6921 case FT_INT24:
6922 case FT_INT32:
6923 case FT_INT40:
6924 case FT_INT48:
6925 case FT_INT56:
6926 case FT_INT64:
6927 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6928 if (length < -1) {
6929 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6930 }
6931 if (length == -1) {
6932 uint64_t dummy;
6933 /* This can throw an exception */
6934 /* XXX - do this without fetching the varint? */
6935 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6936 if (length == 0) {
6937 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6938 }
6939 }
6940 item_length = length;
6941 break;
6942 }
6943
6944 /*
6945 * The length is the specified length.
6946 */
6947 break;
6948
6949 case FT_BOOLEAN:
6950 case FT_CHAR:
6951 case FT_IPv4:
6952 case FT_IPXNET:
6953 case FT_IPv6:
6954 case FT_FCWWN:
6955 case FT_AX25:
6956 case FT_VINES:
6957 case FT_ETHER:
6958 case FT_EUI64:
6959 case FT_GUID:
6960 case FT_OID:
6961 case FT_REL_OID:
6962 case FT_SYSTEM_ID:
6963 case FT_FLOAT:
6964 case FT_DOUBLE:
6965 case FT_STRING:
6966 /*
6967 * The length is the specified length.
6968 */
6969 break;
6970
6971 case FT_STRINGZ:
6972 if (length < -1) {
6973 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6974 }
6975 if (length == -1) {
6976 /* This can throw an exception */
6977 item_length = tvb_strsize_enc(tvb, start, encoding);
6978 }
6979 break;
6980
6981 case FT_UINT_STRING:
6982 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6983 item_length += n;
6984 if ((int)item_length < length) {
6985 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6986 }
6987 break;
6988
6989 case FT_STRINGZPAD:
6990 case FT_STRINGZTRUNC:
6991 case FT_ABSOLUTE_TIME:
6992 case FT_RELATIVE_TIME:
6993 case FT_IEEE_11073_SFLOAT:
6994 case FT_IEEE_11073_FLOAT:
6995 /*
6996 * The length is the specified length.
6997 */
6998 break;
6999
7000 default:
7001 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
))
7002 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
))
7003 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
))
7004 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
))
;
7005 break;
7006 }
7007 return item_length;
7008}
7009
7010// This was arbitrarily chosen, but if you're adding 50K items to the tree
7011// without advancing the offset you should probably take a long, hard look
7012// at what you're doing.
7013// We *could* make this a configurable option, but I (Gerald) would like to
7014// avoid adding yet another nerd knob.
7015# define PROTO_TREE_MAX_IDLE50000 50000
7016static field_info *
7017new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7018 const unsigned start, const int item_length)
7019{
7020 field_info *fi;
7021
7022 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7023
7024 fi->hfinfo = hfinfo;
7025 fi->start = start;
7026 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7027 /* add the data source tvbuff */
7028 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7029
7030 // If our start offset hasn't advanced after adding many items it probably
7031 // means we're in a large or infinite loop.
7032 if (fi->start > 0) {
7033 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7034 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7035 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7036 if (wireshark_abort_on_too_many_items) {
7037 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", 7038
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7038 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7038
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7039 }
7040 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7041 * but if not, we should hit the max item error earlier,
7042 * so we shouldn't need to reset the tree count to
7043 * ensure that the exception handler can add the item. */
7044 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)))
7045 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)))
7046 "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)))
7047 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)))
;
7048 }
7049 } else {
7050 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7051 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7052 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7053 }
7054 }
7055 fi->length = item_length;
7056 fi->tree_type = -1;
7057 fi->flags = 0;
7058 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7059 /* If the tree is not visible, set the item hidden, unless we
7060 * need the representation or length and can't fake them.
7061 */
7062 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7063 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7064 }
7065 }
7066 fi->value = fvalue_new(fi->hfinfo->type);
7067 fi->rep = NULL((void*)0);
7068
7069 fi->appendix_start = 0;
7070 fi->appendix_length = 0;
7071
7072 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7073 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7074
7075 return fi;
7076}
7077
7078static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7079{
7080 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7081 return 0;
7082 }
7083
7084 /* Search for field name */
7085 char *ptr = strstr(representation, hfinfo->name);
7086 if (!ptr) {
7087 return 0;
7088 }
7089
7090 /* Check if field name ends with the ": " delimiter */
7091 ptr += strlen(hfinfo->name);
7092 if (strncmp(ptr, ": ", 2) == 0) {
7093 ptr += 2;
7094 }
7095
7096 /* Return offset to after field name */
7097 return ptr - representation;
7098}
7099
7100static size_t label_find_name_pos(const item_label_t *rep)
7101{
7102 size_t name_pos = 0;
7103
7104 /* If the value_pos is too small or too large, we can't find the expected format */
7105 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7106 return 0;
7107 }
7108
7109 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7110 if (rep->representation[rep->value_pos-2] == ':') {
7111 name_pos = rep->value_pos - 2;
7112 }
7113
7114 return name_pos;
7115}
7116
7117/* If the protocol tree is to be visible, set the representation of a
7118 proto_tree entry with the name of the field for the item and with
7119 the value formatted with the supplied printf-style format and
7120 argument list. */
7121static void
7122proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7123{
7124 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7124, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7125
7126 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7127 * items string representation */
7128 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7129 size_t name_pos, ret = 0;
7130 char *str;
7131 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7132 const header_field_info *hf;
7133
7134 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7134, "fi"))))
;
7135
7136 hf = fi->hfinfo;
7137
7138 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;
;
7139 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))
)) {
7140 uint64_t val;
7141 char *p;
7142
7143 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)
)
7144 val = fvalue_get_uinteger(fi->value);
7145 else
7146 val = fvalue_get_uinteger64(fi->value);
7147
7148 val <<= hfinfo_bitshift(hf);
7149
7150 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7151 ret = (p - fi->rep->representation);
7152 }
7153
7154 /* put in the hf name */
7155 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)
;
7156
7157 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7158 /* If possible, Put in the value of the string */
7159 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7160 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"
, 7160, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7161 fi->rep->value_pos = ret;
7162 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7163 if (ret >= ITEM_LABEL_LENGTH240) {
7164 /* Uh oh, we don't have enough room. Tell the user
7165 * that the field is truncated.
7166 */
7167 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7168 }
7169 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7170 }
7171}
7172
7173/* If the protocol tree is to be visible, set the representation of a
7174 proto_tree entry with the representation formatted with the supplied
7175 printf-style format and argument list. */
7176static void
7177proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7178{
7179 size_t ret; /*tmp return value */
7180 char *str;
7181 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7182
7183 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7183, "fi"))))
;
7184
7185 if (!proto_item_is_hidden(pi)) {
7186 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;
;
7187
7188 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7189 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"
, 7189, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7190 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7191 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7192 if (ret >= ITEM_LABEL_LENGTH240) {
7193 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7194 size_t name_pos = label_find_name_pos(fi->rep);
7195 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7196 }
7197 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7198 }
7199}
7200
7201static int
7202proto_strlcpy(char *dest, const char *src, size_t dest_size)
7203{
7204 if (dest_size == 0) return 0;
7205
7206 size_t res = g_strlcpy(dest, src, dest_size);
7207
7208 /* At most dest_size - 1 characters will be copied
7209 * (unless dest_size is 0). */
7210 if (res >= dest_size)
7211 res = dest_size - 1;
7212 return (int) res;
7213}
7214
7215static header_field_info *
7216hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7217{
7218 header_field_info *dup_hfinfo;
7219
7220 if (hfinfo->same_name_prev_id == -1)
7221 return NULL((void*)0);
7222 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", 7222
, __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", 7222, "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", 7222,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7223 return dup_hfinfo;
7224}
7225
7226static void
7227hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7228{
7229 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)
;
7230 last_field_name = NULL((void*)0);
7231
7232 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7233 /* No hfinfo with the same name */
7234 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7235 return;
7236 }
7237
7238 if (hfinfo->same_name_next) {
7239 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7240 }
7241
7242 if (hfinfo->same_name_prev_id != -1) {
7243 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7244 same_name_prev->same_name_next = hfinfo->same_name_next;
7245 if (!hfinfo->same_name_next) {
7246 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7247 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7248 }
7249 }
7250}
7251
7252int
7253proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7254{
7255 const header_field_info *hfinfo = finfo->hfinfo;
7256 int label_len = 0;
7257 char *tmp_str;
7258 const char *str;
7259 const uint8_t *bytes;
7260 uint32_t number;
7261 uint64_t number64;
7262 const char *hf_str_val;
7263 char number_buf[NUMBER_LABEL_LENGTH80];
7264 const char *number_out;
7265 address addr;
7266 const ipv4_addr_and_mask *ipv4;
7267 const ipv6_addr_and_prefix *ipv6;
7268
7269 switch (hfinfo->type) {
7270
7271 case FT_NONE:
7272 case FT_PROTOCOL:
7273 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7274
7275 case FT_UINT_BYTES:
7276 case FT_BYTES:
7277 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7278 hfinfo,
7279 fvalue_get_bytes_data(finfo->value),
7280 (unsigned)fvalue_length2(finfo->value),
7281 label_str_size);
7282 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7283 wmem_free(NULL((void*)0), tmp_str);
7284 break;
7285
7286 case FT_ABSOLUTE_TIME:
7287 {
7288 const nstime_t *value = fvalue_get_time(finfo->value);
7289 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7290 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7291 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7292 }
7293 if (hfinfo->strings) {
7294 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7295 if (time_string != NULL((void*)0)) {
7296 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7297 break;
7298 }
7299 }
7300 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7301 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7302 wmem_free(NULL((void*)0), tmp_str);
7303 break;
7304 }
7305
7306 case FT_RELATIVE_TIME:
7307 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7308 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7309 wmem_free(NULL((void*)0), tmp_str);
7310 break;
7311
7312 case FT_BOOLEAN:
7313 number64 = fvalue_get_uinteger64(finfo->value);
7314 label_len = proto_strlcpy(display_label_str,
7315 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7316 break;
7317
7318 case FT_CHAR:
7319 number = fvalue_get_uinteger(finfo->value);
7320
7321 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7322 char tmp[ITEM_LABEL_LENGTH240];
7323 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7324
7325 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7325, "fmtfunc"))))
;
7326 fmtfunc(tmp, number);
7327
7328 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7329
7330 } else if (hfinfo->strings) {
7331 number_out = hf_try_val_to_str(number, hfinfo);
7332
7333 if (!number_out) {
7334 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7335 }
7336
7337 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7338
7339 } else {
7340 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7341
7342 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7343 }
7344
7345 break;
7346
7347 /* XXX - make these just FT_NUMBER? */
7348 case FT_INT8:
7349 case FT_INT16:
7350 case FT_INT24:
7351 case FT_INT32:
7352 case FT_UINT8:
7353 case FT_UINT16:
7354 case FT_UINT24:
7355 case FT_UINT32:
7356 case FT_FRAMENUM:
7357 hf_str_val = NULL((void*)0);
7358 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
))
?
7359 (uint32_t) fvalue_get_sinteger(finfo->value) :
7360 fvalue_get_uinteger(finfo->value);
7361
7362 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7363 char tmp[ITEM_LABEL_LENGTH240];
7364 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7365
7366 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7366, "fmtfunc"))))
;
7367 fmtfunc(tmp, number);
7368
7369 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7370
7371 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7372 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7373 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7374 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7375 hf_str_val = hf_try_val_to_str(number, hfinfo);
7376 if (hf_str_val)
7377 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7378 } else {
7379 number_out = hf_try_val_to_str(number, hfinfo);
7380
7381 if (!number_out) {
7382 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7383 }
7384
7385 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7386 }
7387 } else {
7388 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7389
7390 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7391 }
7392
7393 break;
7394
7395 case FT_INT40:
7396 case FT_INT48:
7397 case FT_INT56:
7398 case FT_INT64:
7399 case FT_UINT40:
7400 case FT_UINT48:
7401 case FT_UINT56:
7402 case FT_UINT64:
7403 hf_str_val = NULL((void*)0);
7404 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
))
?
7405 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7406 fvalue_get_uinteger64(finfo->value);
7407
7408 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7409 char tmp[ITEM_LABEL_LENGTH240];
7410 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7411
7412 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7412, "fmtfunc64"
))))
;
7413 fmtfunc64(tmp, number64);
7414
7415 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7416 } else if (hfinfo->strings) {
7417 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7418 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7419 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7420 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7421 if (hf_str_val)
7422 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7423 } else {
7424 number_out = hf_try_val64_to_str(number64, hfinfo);
7425
7426 if (!number_out)
7427 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7428
7429 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7430 }
7431 } else {
7432 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7433
7434 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7435 }
7436
7437 break;
7438
7439 case FT_EUI64:
7440 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7441 tmp_str = address_to_display(NULL((void*)0), &addr);
7442 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7443 wmem_free(NULL((void*)0), tmp_str);
7444 break;
7445
7446 case FT_IPv4:
7447 ipv4 = fvalue_get_ipv4(finfo->value);
7448 //XXX: Should we ignore the mask?
7449 set_address_ipv4(&addr, ipv4);
7450 tmp_str = address_to_display(NULL((void*)0), &addr);
7451 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7452 wmem_free(NULL((void*)0), tmp_str);
7453 free_address(&addr);
7454 break;
7455
7456 case FT_IPv6:
7457 ipv6 = fvalue_get_ipv6(finfo->value);
7458 set_address_ipv6(&addr, ipv6);
7459 tmp_str = address_to_display(NULL((void*)0), &addr);
7460 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7461 wmem_free(NULL((void*)0), tmp_str);
7462 free_address(&addr);
7463 break;
7464
7465 case FT_FCWWN:
7466 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7467 tmp_str = address_to_display(NULL((void*)0), &addr);
7468 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7469 wmem_free(NULL((void*)0), tmp_str);
7470 break;
7471
7472 case FT_ETHER:
7473 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7474 tmp_str = address_to_display(NULL((void*)0), &addr);
7475 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7476 wmem_free(NULL((void*)0), tmp_str);
7477 break;
7478
7479 case FT_GUID:
7480 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7481 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7482 wmem_free(NULL((void*)0), tmp_str);
7483 break;
7484
7485 case FT_REL_OID:
7486 bytes = fvalue_get_bytes_data(finfo->value);
7487 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7488 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7489 wmem_free(NULL((void*)0), tmp_str);
7490 break;
7491
7492 case FT_OID:
7493 bytes = fvalue_get_bytes_data(finfo->value);
7494 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7495 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7496 wmem_free(NULL((void*)0), tmp_str);
7497 break;
7498
7499 case FT_SYSTEM_ID:
7500 bytes = fvalue_get_bytes_data(finfo->value);
7501 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7502 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7503 wmem_free(NULL((void*)0), tmp_str);
7504 break;
7505
7506 case FT_FLOAT:
7507 case FT_DOUBLE:
7508 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7509 break;
7510
7511 case FT_IEEE_11073_SFLOAT:
7512 case FT_IEEE_11073_FLOAT:
7513 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7514 break;
7515
7516 case FT_STRING:
7517 case FT_STRINGZ:
7518 case FT_UINT_STRING:
7519 case FT_STRINGZPAD:
7520 case FT_STRINGZTRUNC:
7521 str = fvalue_get_string(finfo->value);
7522 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7523 if (label_len >= label_str_size) {
7524 /* Truncation occurred. Get the real length
7525 * copied (not including '\0') */
7526 label_len = label_str_size ? label_str_size - 1 : 0;
7527 }
7528 break;
7529
7530 default:
7531 /* First try ftype string representation */
7532 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7533 if (!tmp_str) {
7534 /* Default to show as bytes */
7535 bytes = fvalue_get_bytes_data(finfo->value);
7536 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7537 }
7538 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7539 wmem_free(NULL((void*)0), tmp_str);
7540 break;
7541 }
7542 return label_len;
7543}
7544
7545const char *
7546proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7547 char *result, char *expr, const int size)
7548{
7549 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7550 GPtrArray *finfos;
7551 field_info *finfo = NULL((void*)0);
7552 header_field_info* hfinfo;
7553 const char *abbrev = NULL((void*)0);
7554
7555 char *str;
7556 col_custom_t *field_idx;
7557 int field_id;
7558 int ii = 0;
7559
7560 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7560, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7561 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7562 field_id = field_idx->field_id;
7563 if (field_id == 0) {
7564 GPtrArray *fvals = NULL((void*)0);
7565 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7566 if (fvals != NULL((void*)0)) {
7567
7568 // XXX - Handling occurrences is unusual when more
7569 // than one field is involved, e.g. there's four
7570 // results for tcp.port + tcp.port. We may really
7571 // want to apply it to the operands, not the output.
7572 // Note that occurrences are not quite the same as
7573 // the layer operator (should the grammar support
7574 // both?)
7575 /* Calculate single index or set outer boundaries */
7576 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7577 if (occurrence < 0) {
7578 i = occurrence + len;
7579 last = i;
7580 } else if (occurrence > 0) {
7581 i = occurrence - 1;
7582 last = i;
7583 } else {
7584 i = 0;
7585 last = len - 1;
7586 }
7587 if (i < 0 || i >= len) {
7588 g_ptr_array_unref(fvals);
7589 continue;
7590 }
7591 for (; i <= last; i++) {
7592 /* XXX - We could have a "resolved" result
7593 * for types where the value depends only
7594 * on the type, e.g. FT_IPv4, and not on
7595 * hfinfo->strings. Supporting the latter
7596 * requires knowing which hfinfo matched
7597 * if there are multiple with the same
7598 * abbreviation. In any case, we need to
7599 * know the expected return type of the
7600 * field expression.
7601 */
7602 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7603 if (offset_r && (offset_r < (size - 1)))
7604 result[offset_r++] = ',';
7605 if (offset_e && (offset_e < (size - 1)))
7606 expr[offset_e++] = ',';
7607 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7608 // col_{add,append,set}_* calls ws_label_strcpy
7609 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7610
7611 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7612 }
7613 g_ptr_array_unref(fvals);
7614 } else if (passed) {
7615 // XXX - Occurrence doesn't make sense for a test
7616 // output, it should be applied to the operands.
7617 if (offset_r && (offset_r < (size - 1)))
7618 result[offset_r++] = ',';
7619 if (offset_e && (offset_e < (size - 1)))
7620 expr[offset_e++] = ',';
7621 /* Prevent multiple check marks */
7622 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7623 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7624 } else {
7625 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7626 }
7627 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7628 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7629 } else {
7630 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7631 }
7632 }
7633 continue;
7634 }
7635 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", 7635
, __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", 7635,
"(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", 7635,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7636
7637 /* do we need to rewind ? */
7638 if (!hfinfo)
7639 return "";
7640
7641 if (occurrence < 0) {
7642 /* Search other direction */
7643 while (hfinfo->same_name_prev_id != -1) {
7644 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", 7644
, __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", 7644, "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", 7644,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7645 }
7646 }
7647
7648 prev_len = 0; /* Reset handled occurrences */
7649
7650 while (hfinfo) {
7651 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7652
7653 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7654 if (occurrence < 0) {
7655 hfinfo = hfinfo->same_name_next;
7656 } else {
7657 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7658 }
7659 continue;
7660 }
7661
7662 /* Are there enough occurrences of the field? */
7663 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7664 if (occurrence < 0) {
7665 hfinfo = hfinfo->same_name_next;
7666 } else {
7667 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7668 }
7669 prev_len += len;
7670 continue;
7671 }
7672
7673 /* Calculate single index or set outer boundaries */
7674 if (occurrence < 0) {
7675 i = occurrence + len + prev_len;
7676 last = i;
7677 } else if (occurrence > 0) {
7678 i = occurrence - 1 - prev_len;
7679 last = i;
7680 } else {
7681 i = 0;
7682 last = len - 1;
7683 }
7684
7685 prev_len += len; /* Count handled occurrences */
7686
7687 while (i <= last) {
7688 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7689
7690 if (offset_r && (offset_r < (size - 1)))
7691 result[offset_r++] = ',';
7692
7693 if (display_details) {
7694 char representation[ITEM_LABEL_LENGTH240];
7695 size_t offset = 0;
7696
7697 if (finfo->rep && finfo->rep->value_len) {
7698 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7699 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7700 } else {
7701 proto_item_fill_label(finfo, representation, &offset);
7702 }
7703 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7704 } else {
7705 switch (hfinfo->type) {
7706
7707 case FT_NONE:
7708 case FT_PROTOCOL:
7709 /* Prevent multiple check marks */
7710 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7711 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7712 } else {
7713 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7714 }
7715 break;
7716
7717 default:
7718 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7719 break;
7720 }
7721 }
7722
7723 if (offset_e && (offset_e < (size - 1)))
7724 expr[offset_e++] = ',';
7725
7726 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
))
)) {
7727 const char *hf_str_val;
7728 /* Integer types with BASE_NONE never get the numeric value. */
7729 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7730 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7731 } 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
)
) {
7732 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7733 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7734 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7735 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7736 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7737 }
7738 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7739 offset_e = (int)strlen(expr);
7740 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7741 /* Prevent multiple check marks */
7742 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7743 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7744 } else {
7745 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7746 }
7747 } else {
7748 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7749 // col_{add,append,set}_* calls ws_label_strcpy
7750 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7751 wmem_free(NULL((void*)0), str);
7752 }
7753 i++;
7754 }
7755
7756 /* XXX: Why is only the first abbreviation returned for a multifield
7757 * custom column? */
7758 if (!abbrev) {
7759 /* Store abbrev for return value */
7760 abbrev = hfinfo->abbrev;
7761 }
7762
7763 if (occurrence == 0) {
7764 /* Fetch next hfinfo with same name (abbrev) */
7765 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7766 } else {
7767 hfinfo = NULL((void*)0);
7768 }
7769 }
7770 }
7771
7772 if (offset_r >= (size - 1)) {
7773 mark_truncated(result, 0, size, NULL((void*)0));
7774 }
7775 if (offset_e >= (size - 1)) {
7776 mark_truncated(expr, 0, size, NULL((void*)0));
7777 }
7778 return abbrev ? abbrev : "";
7779}
7780
7781char *
7782proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7783{
7784 int len, prev_len, last, i;
7785 GPtrArray *finfos;
7786 field_info *finfo = NULL((void*)0);
7787 header_field_info* hfinfo;
7788
7789 char *filter = NULL((void*)0);
7790 GPtrArray *filter_array;
7791
7792 col_custom_t *col_custom;
7793 int field_id;
7794
7795 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7795, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7796 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7797 for (GSList *iter = field_ids; iter; iter = iter->next) {
7798 col_custom = (col_custom_t*)iter->data;
7799 field_id = col_custom->field_id;
7800 if (field_id == 0) {
7801 GPtrArray *fvals = NULL((void*)0);
7802 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7803 if (fvals != NULL((void*)0)) {
7804 // XXX - Handling occurrences is unusual when more
7805 // than one field is involved, e.g. there's four
7806 // results for tcp.port + tcp.port. We really
7807 // want to apply it to the operands, not the output.
7808 /* Calculate single index or set outer boundaries */
7809 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7810 if (occurrence < 0) {
7811 i = occurrence + len;
7812 last = i;
7813 } else if (occurrence > 0) {
7814 i = occurrence - 1;
7815 last = i;
7816 } else {
7817 i = 0;
7818 last = len - 1;
7819 }
7820 if (i < 0 || i >= len) {
7821 g_ptr_array_unref(fvals);
7822 continue;
7823 }
7824 for (; i <= last; i++) {
7825 /* XXX - Should multiple values for one
7826 * field use set membership to reduce
7827 * verbosity, here and below? */
7828 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7829 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7830 wmem_free(NULL((void*)0), str);
7831 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7832 g_ptr_array_add(filter_array, filter);
7833 }
7834 }
7835 g_ptr_array_unref(fvals);
7836 } else if (passed) {
7837 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7838 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7839 g_ptr_array_add(filter_array, filter);
7840 }
7841 } else {
7842 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7843 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7844 g_ptr_array_add(filter_array, filter);
7845 }
7846 }
7847 continue;
7848 }
7849
7850 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", 7850
, __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", 7850,
"(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", 7850,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7851
7852 /* do we need to rewind ? */
7853 if (!hfinfo)
7854 return NULL((void*)0);
7855
7856 if (occurrence < 0) {
7857 /* Search other direction */
7858 while (hfinfo->same_name_prev_id != -1) {
7859 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", 7859
, __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", 7859, "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", 7859,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7860 }
7861 }
7862
7863 prev_len = 0; /* Reset handled occurrences */
7864
7865 while (hfinfo) {
7866 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7867
7868 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7869 if (occurrence < 0) {
7870 hfinfo = hfinfo->same_name_next;
7871 } else {
7872 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7873 }
7874 continue;
7875 }
7876
7877 /* Are there enough occurrences of the field? */
7878 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7879 if (occurrence < 0) {
7880 hfinfo = hfinfo->same_name_next;
7881 } else {
7882 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7883 }
7884 prev_len += len;
7885 continue;
7886 }
7887
7888 /* Calculate single index or set outer boundaries */
7889 if (occurrence < 0) {
7890 i = occurrence + len + prev_len;
7891 last = i;
7892 } else if (occurrence > 0) {
7893 i = occurrence - 1 - prev_len;
7894 last = i;
7895 } else {
7896 i = 0;
7897 last = len - 1;
7898 }
7899
7900 prev_len += len; /* Count handled occurrences */
7901
7902 while (i <= last) {
7903 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7904
7905 filter = proto_construct_match_selected_string(finfo, edt);
7906 if (filter) {
7907 /* Only add the same expression once (especially for FT_PROTOCOL).
7908 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7909 */
7910 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7911 g_ptr_array_add(filter_array, filter);
7912 }
7913 }
7914 i++;
7915 }
7916
7917 if (occurrence == 0) {
7918 /* Fetch next hfinfo with same name (abbrev) */
7919 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7920 } else {
7921 hfinfo = NULL((void*)0);
7922 }
7923 }
7924 }
7925
7926 g_ptr_array_add(filter_array, NULL((void*)0));
7927
7928 /* XXX: Should this be || or && ? */
7929 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7930
7931 g_ptr_array_free(filter_array, true1);
7932
7933 return output;
7934}
7935
7936/* Set text of proto_item after having already been created. */
7937void
7938proto_item_set_text(proto_item *pi, const char *format, ...)
7939{
7940 field_info *fi = NULL((void*)0);
7941 va_list ap;
7942
7943 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7944
7945 fi = PITEM_FINFO(pi)((pi)->finfo);
7946 if (fi == NULL((void*)0))
7947 return;
7948
7949 if (fi->rep) {
7950 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7951 fi->rep = NULL((void*)0);
7952 }
7953
7954 va_start(ap, format)__builtin_va_start(ap, format);
7955 proto_tree_set_representation(pi, format, ap);
7956 va_end(ap)__builtin_va_end(ap);
7957}
7958
7959/* Append to text of proto_item after having already been created. */
7960void
7961proto_item_append_text(proto_item *pi, const char *format, ...)
7962{
7963 field_info *fi = NULL((void*)0);
7964 size_t curlen;
7965 char *str;
7966 va_list ap;
7967
7968 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7969
7970 fi = PITEM_FINFO(pi)((pi)->finfo);
7971 if (fi == NULL((void*)0)) {
7972 return;
7973 }
7974
7975 if (!proto_item_is_hidden(pi)) {
7976 /*
7977 * If we don't already have a representation,
7978 * generate the default representation.
7979 */
7980 if (fi->rep == NULL((void*)0)) {
7981 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;
;
7982 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7983 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7984 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7985 (strncmp(format, ": ", 2) == 0)) {
7986 fi->rep->value_pos += 2;
7987 }
7988 }
7989 if (fi->rep) {
7990 curlen = strlen(fi->rep->representation);
7991 /* curlen doesn't include the \0 byte.
7992 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7993 * the representation has already been truncated (of an up
7994 * to 4 byte UTF-8 character) or is just at the maximum length
7995 * unless we search for " [truncated]" (which may not be
7996 * at the start.)
7997 * It's safer to do nothing.
7998 */
7999 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8000 va_start(ap, format)__builtin_va_start(ap, format);
8001 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8002 va_end(ap)__builtin_va_end(ap);
8003 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"
, 8003, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8004 /* Keep fi->rep->value_pos */
8005 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8006 if (curlen >= ITEM_LABEL_LENGTH240) {
8007 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8008 size_t name_pos = label_find_name_pos(fi->rep);
8009 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8010 }
8011 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8012 }
8013 }
8014 }
8015}
8016
8017/* Prepend to text of proto_item after having already been created. */
8018void
8019proto_item_prepend_text(proto_item *pi, const char *format, ...)
8020{
8021 field_info *fi = NULL((void*)0);
8022 size_t pos;
8023 char representation[ITEM_LABEL_LENGTH240];
8024 char *str;
8025 va_list ap;
8026
8027 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8028
8029 fi = PITEM_FINFO(pi)((pi)->finfo);
8030 if (fi == NULL((void*)0)) {
8031 return;
8032 }
8033
8034 if (!proto_item_is_hidden(pi)) {
8035 /*
8036 * If we don't already have a representation,
8037 * generate the default representation.
8038 */
8039 if (fi->rep == NULL((void*)0)) {
8040 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;
;
8041 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8042 } else
8043 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8044
8045 va_start(ap, format)__builtin_va_start(ap, format);
8046 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8047 va_end(ap)__builtin_va_end(ap);
8048 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"
, 8048, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8049 fi->rep->value_pos += strlen(str);
8050 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8051 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8052 /* XXX: As above, if the old representation is close to the label
8053 * length, it might already be marked as truncated. */
8054 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8055 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8056 size_t name_pos = label_find_name_pos(fi->rep);
8057 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8058 }
8059 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8060 }
8061}
8062
8063static void
8064finfo_set_len(field_info *fi, const unsigned length)
8065{
8066 unsigned length_remaining;
8067
8068 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8069 if (length > length_remaining)
8070 fi->length = length_remaining;
8071 else
8072 fi->length = length;
8073
8074 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8075 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8076 fvalue_set_protocol_length(fi->value, fi->length);
8077 }
8078
8079 /*
8080 * You cannot just make the "len" field of a GByteArray
8081 * larger, if there's no data to back that length;
8082 * you can only make it smaller.
8083 */
8084 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8085 GBytes *bytes = fvalue_get_bytes(fi->value);
8086 size_t size;
8087 const void *data = g_bytes_get_data(bytes, &size);
8088 if ((size_t)fi->length <= size) {
8089 fvalue_set_bytes_data(fi->value, data, fi->length);
8090 }
8091 g_bytes_unref(bytes);
8092 }
8093}
8094
8095void
8096proto_item_set_len(proto_item *pi, const unsigned length)
8097{
8098 field_info *fi;
8099
8100 if (pi == NULL((void*)0))
8101 return;
8102
8103 fi = PITEM_FINFO(pi)((pi)->finfo);
8104 if (fi == NULL((void*)0))
8105 return;
8106
8107 finfo_set_len(fi, length);
8108}
8109
8110/*
8111 * Sets the length of the item based on its start and on the specified
8112 * offset, which is the offset past the end of the item; as the start
8113 * in the item is relative to the beginning of the data source tvbuff,
8114 * we need to pass in a tvbuff - the end offset is relative to the beginning
8115 * of that tvbuff.
8116 */
8117void
8118proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8119{
8120 field_info *fi;
8121 unsigned length;
8122
8123 if (pi == NULL((void*)0))
8124 return;
8125
8126 fi = PITEM_FINFO(pi)((pi)->finfo);
8127 if (fi == NULL((void*)0))
8128 return;
8129
8130 if (G_LIKELY(tvb)(tvb)) {
8131 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"
, 8131, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8132 end += tvb_raw_offset(tvb);
8133 } else {
8134 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", 8134, "((void*)0) == fi->ds_tvb"
))))
;
8135 }
8136 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8136, "end >= fi->start"
))))
;
8137 length = end - fi->start;
8138
8139 finfo_set_len(fi, length);
8140}
8141
8142unsigned
8143proto_item_get_len(const proto_item *pi)
8144{
8145 /* XXX - The only use case where this is really guaranteed to work is
8146 * increasing the length of an item (which has no effect if the item
8147 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8148 *
8149 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8150 *
8151 * Should there be a macro or function to do that, and possibly this
8152 * be deprecated? As a bonus, we could handle overflow.
8153 */
8154 field_info *fi;
8155
8156 if (!pi)
8157 return 0;
8158 fi = PITEM_FINFO(pi)((pi)->finfo);
8159 if (fi) {
8160 return fi->length;
8161 }
8162 return 0;
8163}
8164
8165void
8166proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8167 if (!ti) {
8168 return;
8169 }
8170 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)
;
8171 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)
;
8172}
8173
8174char *
8175proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8176{
8177 field_info *fi;
8178
8179 if (!pi)
8180 return wmem_strdup(scope, "");
8181 fi = PITEM_FINFO(pi)((pi)->finfo);
8182 if (!fi)
8183 return wmem_strdup(scope, "");
8184 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8184, "fi->hfinfo != ((void*)0)"
))))
;
8185 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8186}
8187
8188proto_tree *
8189proto_tree_create_root(packet_info *pinfo)
8190{
8191 proto_node *pnode;
8192
8193 /* Initialize the proto_node */
8194 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8195 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8196 pnode->parent = NULL((void*)0);
8197 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8198 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)))
;
8199
8200 /* Make sure we can access pinfo everywhere */
8201 pnode->tree_data->pinfo = pinfo;
8202
8203 /* Don't initialize the tree_data_t. Wait until we know we need it */
8204 pnode->tree_data->interesting_hfids = NULL((void*)0);
8205
8206 /* Set the default to false so it's easier to
8207 * find errors; if we expect to see the protocol tree
8208 * but for some reason the default 'visible' is not
8209 * changed, then we'll find out very quickly. */
8210 pnode->tree_data->visible = false0;
8211
8212 /* Make sure that we fake protocols (if possible) */
8213 pnode->tree_data->fake_protocols = true1;
8214
8215 /* Keep track of the number of children */
8216 pnode->tree_data->count = 0;
8217
8218 /* Initialize our loop checks */
8219 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8220 pnode->tree_data->max_start = 0;
8221 pnode->tree_data->start_idle_count = 0;
8222
8223 return (proto_tree *)pnode;
8224}
8225
8226
8227/* "prime" a proto_tree with a single hfid that a dfilter
8228 * is interested in. */
8229void
8230proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8231{
8232 header_field_info *hfinfo;
8233
8234 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", 8234, __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", 8234, "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", 8234, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8235 /* this field is referenced by a filter so increase the refcount.
8236 also increase the refcount for the parent, i.e the protocol.
8237 Don't increase the refcount if we're already printing the
8238 type, as that is a superset of direct reference.
8239 */
8240 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8241 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8242 }
8243 /* only increase the refcount if there is a parent.
8244 if this is a protocol and not a field then parent will be -1
8245 and there is no parent to add any refcounting for.
8246 */
8247 if (hfinfo->parent != -1) {
8248 header_field_info *parent_hfinfo;
8249 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", 8249
, __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", 8249,
"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", 8249,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8250
8251 /* Mark parent as indirectly referenced unless it is already directly
8252 * referenced, i.e. the user has specified the parent in a filter.
8253 */
8254 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8255 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8256 }
8257}
8258
8259/* "prime" a proto_tree with a single hfid that a dfilter
8260 * is interested in. */
8261void
8262proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8263{
8264 header_field_info *hfinfo;
8265
8266 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", 8266, __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", 8266, "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", 8266, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8267 /* this field is referenced by an (output) filter so increase the refcount.
8268 also increase the refcount for the parent, i.e the protocol.
8269 */
8270 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8271 /* only increase the refcount if there is a parent.
8272 if this is a protocol and not a field then parent will be -1
8273 and there is no parent to add any refcounting for.
8274 */
8275 if (hfinfo->parent != -1) {
8276 header_field_info *parent_hfinfo;
8277 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", 8277
, __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", 8277,
"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", 8277,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8278
8279 /* Mark parent as indirectly referenced unless it is already directly
8280 * referenced, i.e. the user has specified the parent in a filter.
8281 */
8282 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8283 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8284 }
8285}
8286
8287proto_tree *
8288proto_item_add_subtree(proto_item *pi, const int idx) {
8289 field_info *fi;
8290
8291 if (!pi)
8292 return NULL((void*)0);
8293
8294 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", 8294, "idx >= 0 && idx < num_tree_types"
))))
;
8295
8296 fi = PITEM_FINFO(pi)((pi)->finfo);
8297 if (!fi)
8298 return (proto_tree *)pi;
8299
8300 fi->tree_type = idx;
8301
8302 return (proto_tree *)pi;
8303}
8304
8305proto_tree *
8306proto_item_get_subtree(proto_item *pi) {
8307 field_info *fi;
8308
8309 if (!pi)
8310 return NULL((void*)0);
8311 fi = PITEM_FINFO(pi)((pi)->finfo);
8312 if ( (fi) && (fi->tree_type == -1) )
8313 return NULL((void*)0);
8314 return (proto_tree *)pi;
8315}
8316
8317proto_item *
8318proto_item_get_parent(const proto_item *ti) {
8319 if (!ti)
8320 return NULL((void*)0);
8321 return ti->parent;
8322}
8323
8324proto_item *
8325proto_item_get_parent_nth(proto_item *ti, int gen) {
8326 if (!ti)
8327 return NULL((void*)0);
8328 while (gen--) {
8329 ti = ti->parent;
8330 if (!ti)
8331 return NULL((void*)0);
8332 }
8333 return ti;
8334}
8335
8336
8337proto_item *
8338proto_tree_get_parent(proto_tree *tree) {
8339 if (!tree)
8340 return NULL((void*)0);
8341 return (proto_item *)tree;
8342}
8343
8344proto_tree *
8345proto_tree_get_parent_tree(proto_tree *tree) {
8346 if (!tree)
8347 return NULL((void*)0);
8348
8349 /* we're the root tree, there's no parent
8350 return ourselves so the caller has at least a tree to attach to */
8351 if (!tree->parent)
8352 return tree;
8353
8354 return (proto_tree *)tree->parent;
8355}
8356
8357proto_tree *
8358proto_tree_get_root(proto_tree *tree) {
8359 if (!tree)
8360 return NULL((void*)0);
8361 while (tree->parent) {
8362 tree = tree->parent;
8363 }
8364 return tree;
8365}
8366
8367void
8368proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8369 proto_item *item_to_move)
8370{
8371 /* This function doesn't generate any values. It only reorganizes the protocol tree
8372 * so we can bail out immediately if it isn't visible. */
8373 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8374 return;
8375
8376 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", 8376, "item_to_move->parent == tree"
))))
;
8377 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", 8377, "fixed_item->parent == tree"
))))
;
8378
8379 /*** cut item_to_move out ***/
8380
8381 /* is item_to_move the first? */
8382 if (tree->first_child == item_to_move) {
8383 /* simply change first child to next */
8384 tree->first_child = item_to_move->next;
8385
8386 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", 8386, "tree->last_child != item_to_move"
))))
;
8387 } else {
8388 proto_item *curr_item;
8389 /* find previous and change it's next */
8390 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8391 if (curr_item->next == item_to_move) {
8392 break;
8393 }
8394 }
8395
8396 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8396, "curr_item"
))))
;
8397
8398 curr_item->next = item_to_move->next;
8399
8400 /* fix last_child if required */
8401 if (tree->last_child == item_to_move) {
8402 tree->last_child = curr_item;
8403 }
8404 }
8405
8406 /*** insert to_move after fixed ***/
8407 item_to_move->next = fixed_item->next;
8408 fixed_item->next = item_to_move;
8409 if (tree->last_child == fixed_item) {
8410 tree->last_child = item_to_move;
8411 }
8412}
8413
8414void
8415proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8416 const unsigned length)
8417{
8418 field_info *fi;
8419
8420 if (tree == NULL((void*)0))
8421 return;
8422
8423 fi = PTREE_FINFO(tree)((tree)->finfo);
8424 if (fi == NULL((void*)0))
8425 return;
8426
8427 /* We don't store a separate data source tvb for the appendix, so
8428 * it must be from the same data source. (XXX - Are there any
8429 * situations where it makes sense to have an appendix from a
8430 * different data source?) */
8431 if (G_LIKELY(tvb)(tvb)) {
8432 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"
, 8432, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8433 start += tvb_raw_offset(tvb);
8434 } else {
8435 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", 8435, "((void*)0) == fi->ds_tvb"
))))
;
8436 }
8437
8438 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8439 * main body? */
8440
8441 fi->appendix_start = start;
8442 fi->appendix_length = length;
8443}
8444
8445static void
8446check_protocol_filter_name_or_fail(const char *filter_name)
8447{
8448 /* Require at least two characters. */
8449 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8450 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)
;
8451 }
8452
8453 if (proto_check_field_name(filter_name) != '\0') {
8454 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)
8455 " 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)
8456 " 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)
;
8457 }
8458
8459 /* Check that it doesn't match some very common numeric forms. */
8460 if (filter_name[0] == '0' &&
8461 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8462 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8463 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])
8464 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])
;
8465 }
8466
8467 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8468
8469 /* Check that it contains at least one letter. */
8470 bool_Bool have_letter = false0;
8471 for (const char *s = filter_name; *s != '\0'; s++) {
8472 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8473 have_letter = true1;
8474 break;
8475 }
8476 }
8477 if (!have_letter) {
8478 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)
8479 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8480 }
8481
8482 /* Check for reserved keywords. */
8483 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8484 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)
8485 " 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)
;
8486 }
8487}
8488
8489int
8490proto_register_protocol(const char *name, const char *short_name,
8491 const char *filter_name)
8492{
8493 protocol_t *protocol;
8494 header_field_info *hfinfo;
8495
8496 check_protocol_filter_name_or_fail(filter_name);
8497
8498 /*
8499 * Add this protocol to the list of known protocols;
8500 * the list is sorted by protocol short name.
8501 */
8502 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8503 protocol->name = name;
8504 protocol->short_name = short_name;
8505 protocol->filter_name = filter_name;
8506 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8507 protocol->is_enabled = true1; /* protocol is enabled by default */
8508 protocol->enabled_by_default = true1; /* see previous comment */
8509 protocol->can_toggle = true1;
8510 protocol->parent_proto_id = -1;
8511 protocol->heur_list = NULL((void*)0);
8512
8513 /* List will be sorted later by name, when all protocols completed registering */
8514 protocols = g_list_prepend(protocols, protocol);
8515 /*
8516 * Make sure there's not already a protocol with any of those
8517 * names. Crash if there is, as that's an error in the code
8518 * or an inappropriate plugin.
8519 * This situation has to be fixed to not register more than one
8520 * protocol with the same name.
8521 */
8522 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8523 /* ws_error will terminate the program */
8524 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)
8525 " 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)
;
8526 }
8527 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8528 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)
8529 " 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)
;
8530 }
8531 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8532 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)
8533 " 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)
;
8534 }
8535
8536 /* Here we allocate a new header_field_info struct */
8537 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8538 hfinfo->name = name;
8539 hfinfo->abbrev = filter_name;
8540 hfinfo->type = FT_PROTOCOL;
8541 hfinfo->display = BASE_NONE;
8542 hfinfo->strings = protocol;
8543 hfinfo->bitmask = 0;
8544 hfinfo->ref_type = HF_REF_TYPE_NONE;
8545 hfinfo->blurb = NULL((void*)0);
8546 hfinfo->parent = -1; /* This field differentiates protos and fields */
8547
8548 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8549 return protocol->proto_id;
8550}
8551
8552int
8553proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8554{
8555 protocol_t *protocol;
8556 header_field_info *hfinfo;
8557
8558 /*
8559 * Helper protocols don't need the strict rules as a "regular" protocol
8560 * Just register it in a list and make a hf_ field from it
8561 */
8562 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8563 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)
;
8564 }
8565
8566 if (parent_proto <= 0) {
8567 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)
8568 " 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)
;
8569 }
8570
8571 check_protocol_filter_name_or_fail(filter_name);
8572
8573 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8574 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8575 protocol->name = name;
8576 protocol->short_name = short_name;
8577 protocol->filter_name = filter_name;
8578 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8579
8580 /* Enabling and toggling is really determined by parent protocol,
8581 but provide default values here */
8582 protocol->is_enabled = true1;
8583 protocol->enabled_by_default = true1;
8584 protocol->can_toggle = true1;
8585
8586 protocol->parent_proto_id = parent_proto;
8587 protocol->heur_list = NULL((void*)0);
8588
8589 /* List will be sorted later by name, when all protocols completed registering */
8590 protocols = g_list_prepend(protocols, protocol);
8591
8592 /* Here we allocate a new header_field_info struct */
8593 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8594 hfinfo->name = name;
8595 hfinfo->abbrev = filter_name;
8596 hfinfo->type = field_type;
8597 hfinfo->display = BASE_NONE;
8598 if (field_type == FT_BYTES) {
8599 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8600 }
8601 hfinfo->strings = protocol;
8602 hfinfo->bitmask = 0;
8603 hfinfo->ref_type = HF_REF_TYPE_NONE;
8604 hfinfo->blurb = NULL((void*)0);
8605 hfinfo->parent = -1; /* This field differentiates protos and fields */
8606
8607 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8608 return protocol->proto_id;
8609}
8610
8611bool_Bool
8612proto_deregister_protocol(const char *short_name)
8613{
8614 protocol_t *protocol;
8615 header_field_info *hfinfo;
8616 int proto_id;
8617 unsigned i;
8618
8619 proto_id = proto_get_id_by_short_name(short_name);
8620 protocol = find_protocol_by_id(proto_id);
8621 if (protocol == NULL((void*)0))
8622 return false0;
8623
8624 g_hash_table_remove(proto_names, protocol->name);
8625 g_hash_table_remove(proto_short_names, (void *)short_name);
8626 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8627
8628 if (protocol->fields) {
8629 for (i = 0; i < protocol->fields->len; i++) {
8630 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8631 hfinfo_remove_from_gpa_name_map(hfinfo);
8632 expert_deregister_expertinfo(hfinfo->abbrev);
8633 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8634 }
8635 g_ptr_array_free(protocol->fields, true1);
8636 protocol->fields = NULL((void*)0);
8637 }
8638
8639 g_list_free(protocol->heur_list);
8640
8641 /* Remove this protocol from the list of known protocols */
8642 protocols = g_list_remove(protocols, protocol);
8643
8644 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8645 wmem_map_remove(gpa_name_map, protocol->filter_name);
8646
8647 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)
;
8648 last_field_name = NULL((void*)0);
8649
8650 return true1;
8651}
8652
8653void
8654proto_register_alias(const int proto_id, const char *alias_name)
8655{
8656 protocol_t *protocol;
8657
8658 protocol = find_protocol_by_id(proto_id);
8659 if (alias_name && protocol) {
8660 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8661 }
8662}
8663
8664/*
8665 * Routines to use to iterate over the protocols.
8666 * The argument passed to the iterator routines is an opaque cookie to
8667 * their callers; it's the GList pointer for the current element in
8668 * the list.
8669 * The ID of the protocol is returned, or -1 if there is no protocol.
8670 */
8671int
8672proto_get_first_protocol(void **cookie)
8673{
8674 protocol_t *protocol;
8675
8676 if (protocols == NULL((void*)0))
8677 return -1;
8678 *cookie = protocols;
8679 protocol = (protocol_t *)protocols->data;
8680 return protocol->proto_id;
8681}
8682
8683int
8684proto_get_data_protocol(void *cookie)
8685{
8686 GList *list_item = (GList *)cookie;
8687
8688 protocol_t *protocol = (protocol_t *)list_item->data;
8689 return protocol->proto_id;
8690}
8691
8692int
8693proto_get_next_protocol(void **cookie)
8694{
8695 GList *list_item = (GList *)*cookie;
8696 protocol_t *protocol;
8697
8698 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8699 if (list_item == NULL((void*)0))
8700 return -1;
8701 *cookie = list_item;
8702 protocol = (protocol_t *)list_item->data;
8703 return protocol->proto_id;
8704}
8705
8706header_field_info *
8707proto_get_first_protocol_field(const int proto_id, void **cookie)
8708{
8709 protocol_t *protocol = find_protocol_by_id(proto_id);
8710
8711 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8712 return NULL((void*)0);
8713
8714 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8715 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8716}
8717
8718header_field_info *
8719proto_get_next_protocol_field(const int proto_id, void **cookie)
8720{
8721 protocol_t *protocol = find_protocol_by_id(proto_id);
8722 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8723
8724 i++;
8725
8726 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8727 return NULL((void*)0);
8728
8729 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8730 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8731}
8732
8733protocol_t *
8734find_protocol_by_id(const int proto_id)
8735{
8736 header_field_info *hfinfo;
8737
8738 if (proto_id <= 0)
8739 return NULL((void*)0);
8740
8741 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", 8741, __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", 8741,
"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", 8741, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8742 if (hfinfo->type != FT_PROTOCOL) {
8743 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", 8743, "hfinfo->display & 0x00004000"
))))
;
8744 }
8745 return (protocol_t *)hfinfo->strings;
8746}
8747
8748int
8749proto_get_id(const protocol_t *protocol)
8750{
8751 return protocol->proto_id;
8752}
8753
8754bool_Bool
8755proto_name_already_registered(const char *name)
8756{
8757 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8757, "name", "No name present"))))
;
8758
8759 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8760 return true1;
8761 return false0;
8762}
8763
8764int
8765proto_get_id_by_filter_name(const char *filter_name)
8766{
8767 const protocol_t *protocol = NULL((void*)0);
8768
8769 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", 8769,
"filter_name", "No filter name present"))))
;
8770
8771 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8772
8773 if (protocol == NULL((void*)0))
8774 return -1;
8775 return protocol->proto_id;
8776}
8777
8778int
8779proto_get_id_by_short_name(const char *short_name)
8780{
8781 const protocol_t *protocol = NULL((void*)0);
8782
8783 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", 8783,
"short_name", "No short name present"))))
;
8784
8785 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8786
8787 if (protocol == NULL((void*)0))
8788 return -1;
8789 return protocol->proto_id;
8790}
8791
8792const char *
8793proto_get_protocol_name(const int proto_id)
8794{
8795 protocol_t *protocol;
8796
8797 protocol = find_protocol_by_id(proto_id);
8798
8799 if (protocol == NULL((void*)0))
8800 return NULL((void*)0);
8801 return protocol->name;
8802}
8803
8804const char *
8805proto_get_protocol_short_name(const protocol_t *protocol)
8806{
8807 if (protocol == NULL((void*)0))
8808 return "(none)";
8809 return protocol->short_name;
8810}
8811
8812const char *
8813proto_get_protocol_long_name(const protocol_t *protocol)
8814{
8815 if (protocol == NULL((void*)0))
8816 return "(none)";
8817 return protocol->name;
8818}
8819
8820const char *
8821proto_get_protocol_filter_name(const int proto_id)
8822{
8823 protocol_t *protocol;
8824
8825 protocol = find_protocol_by_id(proto_id);
8826 if (protocol == NULL((void*)0))
8827 return "(none)";
8828 return protocol->filter_name;
8829}
8830
8831void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8832{
8833 heur_dtbl_entry_t* heuristic_dissector;
8834
8835 if (protocol == NULL((void*)0))
8836 return;
8837
8838 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8839 if (heuristic_dissector != NULL((void*)0))
8840 {
8841 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8842 }
8843}
8844
8845void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8846{
8847 if (protocol == NULL((void*)0))
8848 return;
8849
8850 g_list_foreach(protocol->heur_list, func, user_data);
8851}
8852
8853void
8854proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8855 bool_Bool *is_tcp, bool_Bool *is_udp,
8856 bool_Bool *is_sctp, bool_Bool *is_tls,
8857 bool_Bool *is_rtp,
8858 bool_Bool *is_lte_rlc)
8859{
8860 wmem_list_frame_t *protos = wmem_list_head(layers);
8861 int proto_id;
8862 const char *proto_name;
8863
8864 /* Walk the list of a available protocols in the packet and
8865 attempt to find "major" ones. */
8866 /* It might make more sense to assemble and return a bitfield. */
8867 while (protos != NULL((void*)0))
8868 {
8869 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8870 proto_name = proto_get_protocol_filter_name(proto_id);
8871
8872 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8873 (!strcmp(proto_name, "ipv6")))) {
8874 *is_ip = true1;
8875 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8876 *is_tcp = true1;
8877 } else if (is_udp && !strcmp(proto_name, "udp")) {
8878 *is_udp = true1;
8879 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8880 *is_sctp = true1;
8881 } else if (is_tls && !strcmp(proto_name, "tls")) {
8882 *is_tls = true1;
8883 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8884 *is_rtp = true1;
8885 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8886 *is_lte_rlc = true1;
8887 }
8888
8889 protos = wmem_list_frame_next(protos);
8890 }
8891}
8892
8893bool_Bool
8894proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8895{
8896 wmem_list_frame_t *protos = wmem_list_head(layers);
8897 int proto_id;
8898 const char *name;
8899
8900 /* Walk the list of a available protocols in the packet and
8901 attempt to find the specified protocol. */
8902 while (protos != NULL((void*)0))
8903 {
8904 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8905 name = proto_get_protocol_filter_name(proto_id);
8906
8907 if (!strcmp(name, proto_name))
8908 {
8909 return true1;
8910 }
8911
8912 protos = wmem_list_frame_next(protos);
8913 }
8914
8915 return false0;
8916}
8917
8918char *
8919proto_list_layers(const packet_info *pinfo)
8920{
8921 wmem_strbuf_t *buf;
8922 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8923
8924 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8925
8926 /* Walk the list of layers in the packet and
8927 return a string of all entries. */
8928 while (layers != NULL((void*)0))
8929 {
8930 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8931
8932 layers = wmem_list_frame_next(layers);
8933 if (layers != NULL((void*)0)) {
8934 wmem_strbuf_append_c(buf, ':');
8935 }
8936 }
8937
8938 return wmem_strbuf_finalize(buf);
8939}
8940
8941uint8_t
8942proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8943{
8944 int *proto_layer_num_ptr;
8945
8946 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8947 if (proto_layer_num_ptr == NULL((void*)0)) {
8948 return 0;
8949 }
8950
8951 return (uint8_t)*proto_layer_num_ptr;
8952}
8953
8954bool_Bool
8955proto_is_pino(const protocol_t *protocol)
8956{
8957 return (protocol->parent_proto_id != -1);
8958}
8959
8960bool_Bool
8961// NOLINTNEXTLINE(misc-no-recursion)
8962proto_is_protocol_enabled(const protocol_t *protocol)
8963{
8964 if (protocol == NULL((void*)0))
8965 return false0;
8966
8967 //parent protocol determines enable/disable for helper dissectors
8968 if (proto_is_pino(protocol))
8969 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8970
8971 return protocol->is_enabled;
8972}
8973
8974bool_Bool
8975// NOLINTNEXTLINE(misc-no-recursion)
8976proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8977{
8978 //parent protocol determines enable/disable for helper dissectors
8979 if (proto_is_pino(protocol))
8980 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8981
8982 return protocol->enabled_by_default;
8983}
8984
8985bool_Bool
8986// NOLINTNEXTLINE(misc-no-recursion)
8987proto_can_toggle_protocol(const int proto_id)
8988{
8989 protocol_t *protocol;
8990
8991 protocol = find_protocol_by_id(proto_id);
8992 //parent protocol determines toggling for helper dissectors
8993 if (proto_is_pino(protocol))
8994 return proto_can_toggle_protocol(protocol->parent_proto_id);
8995
8996 return protocol->can_toggle;
8997}
8998
8999void
9000proto_disable_by_default(const int proto_id)
9001{
9002 protocol_t *protocol;
9003
9004 protocol = find_protocol_by_id(proto_id);
9005 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9005, "protocol->can_toggle"
))))
;
9006 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", 9006, "proto_is_pino(protocol) == 0"
))))
;
9007 protocol->is_enabled = false0;
9008 protocol->enabled_by_default = false0;
9009}
9010
9011void
9012proto_set_decoding(const int proto_id, const bool_Bool enabled)
9013{
9014 protocol_t *protocol;
9015
9016 protocol = find_protocol_by_id(proto_id);
9017 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9017, "protocol->can_toggle"
))))
;
9018 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", 9018, "proto_is_pino(protocol) == 0"
))))
;
9019 protocol->is_enabled = enabled;
9020}
9021
9022void
9023proto_disable_all(void)
9024{
9025 /* This doesn't explicitly disable heuristic protocols,
9026 * but the heuristic doesn't get called if the parent
9027 * protocol isn't enabled.
9028 */
9029 protocol_t *protocol;
9030 GList *list_item = protocols;
9031
9032 if (protocols == NULL((void*)0))
9033 return;
9034
9035 while (list_item) {
9036 protocol = (protocol_t *)list_item->data;
9037 if (protocol->can_toggle) {
9038 protocol->is_enabled = false0;
9039 }
9040 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9041 }
9042}
9043
9044static void
9045heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9046{
9047 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9048
9049 heur->enabled = heur->enabled_by_default;
9050}
9051
9052void
9053proto_reenable_all(void)
9054{
9055 protocol_t *protocol;
9056 GList *list_item = protocols;
9057
9058 if (protocols == NULL((void*)0))
9059 return;
9060
9061 while (list_item) {
9062 protocol = (protocol_t *)list_item->data;
9063 if (protocol->can_toggle)
9064 protocol->is_enabled = protocol->enabled_by_default;
9065 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9066 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9067 }
9068}
9069
9070void
9071proto_set_cant_toggle(const int proto_id)
9072{
9073 protocol_t *protocol;
9074
9075 protocol = find_protocol_by_id(proto_id);
9076 protocol->can_toggle = false0;
9077}
9078
9079static int
9080proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9081{
9082 g_ptr_array_add(proto->fields, hfi);
9083
9084 return proto_register_field_init(hfi, parent);
9085}
9086
9087/* for use with static arrays only, since we don't allocate our own copies
9088of the header_field_info struct contained within the hf_register_info struct */
9089void
9090proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9091{
9092 hf_register_info *ptr = hf;
9093 protocol_t *proto;
9094 int i;
9095
9096 proto = find_protocol_by_id(parent);
9097
9098 /* if (proto == NULL) - error or return? */
9099
9100 if (proto->fields == NULL((void*)0)) {
9101 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9102 * GLib introduced g_ptr_array_new_from_array, which might have
9103 * given a reason to actually use it. (#17774)
9104 */
9105 proto->fields = g_ptr_array_sized_new(num_records);
9106 }
9107
9108 for (i = 0; i < num_records; i++, ptr++) {
9109 /*
9110 * Make sure we haven't registered this yet.
9111 * Most fields have variables associated with them that
9112 * are initialized to 0; some are initialized to -1 (which
9113 * was the standard before 4.4).
9114 *
9115 * XXX - Since this is called almost 300000 times at startup,
9116 * it might be nice to compare to only 0 and require
9117 * dissectors to pass in zero for unregistered fields.
9118 */
9119 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9120 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9121 "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)
9122 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9123 return;
9124 }
9125
9126 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9127 }
9128}
9129
9130/* deregister already registered fields */
9131void
9132proto_deregister_field (const int parent, int hf_id)
9133{
9134 header_field_info *hfi;
9135 protocol_t *proto;
9136 unsigned i;
9137
9138 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)
;
9139 last_field_name = NULL((void*)0);
9140
9141 if (hf_id == -1 || hf_id == 0)
9142 return;
9143
9144 proto = find_protocol_by_id (parent);
9145 if (!proto || proto->fields == NULL((void*)0)) {
9146 return;
9147 }
9148
9149 for (i = 0; i < proto->fields->len; i++) {
9150 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9151 if (hfi->id == hf_id) {
9152 /* Found the hf_id in this protocol */
9153 wmem_map_remove(gpa_name_map, hfi->abbrev);
9154 g_ptr_array_remove_index_fast(proto->fields, i);
9155 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9156 return;
9157 }
9158 }
9159}
9160
9161/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9162void
9163proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9164{
9165 header_field_info *hfinfo;
9166 protocol_t *proto;
9167
9168 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)
;
9169 last_field_name = NULL((void*)0);
9170
9171 proto = find_protocol_by_id(parent);
9172 if (proto && proto->fields && proto->fields->len > 0) {
9173 unsigned i = proto->fields->len;
9174 do {
9175 i--;
9176
9177 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9178 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) )
) {
9179 hfinfo_remove_from_gpa_name_map(hfinfo);
9180 expert_deregister_expertinfo(hfinfo->abbrev);
9181 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9182 g_ptr_array_remove_index_fast(proto->fields, i);
9183 }
9184 } while (i > 0);
9185 }
9186}
9187
9188void
9189proto_add_deregistered_data (void *data)
9190{
9191 g_ptr_array_add(deregistered_data, data);
9192}
9193
9194void
9195proto_add_deregistered_slice (size_t block_size, void *mem_block)
9196{
9197 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)))
;
9198
9199 slice_data->block_size = block_size;
9200 slice_data->mem_block = mem_block;
9201
9202 g_ptr_array_add(deregistered_slice, slice_data);
9203}
9204
9205void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9206{
9207 if (field_strings == NULL((void*)0)) {
9208 return;
9209 }
9210
9211 switch (field_type) {
9212 case FT_FRAMENUM:
9213 /* This is just an integer represented as a pointer */
9214 break;
9215 case FT_PROTOCOL: {
9216 protocol_t *protocol = (protocol_t *)field_strings;
9217 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)
;
9218 break;
9219 }
9220 case FT_BOOLEAN: {
9221 true_false_string *tf = (true_false_string *)field_strings;
9222 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)
;
9223 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)
;
9224 break;
9225 }
9226 case FT_UINT40:
9227 case FT_INT40:
9228 case FT_UINT48:
9229 case FT_INT48:
9230 case FT_UINT56:
9231 case FT_INT56:
9232 case FT_UINT64:
9233 case FT_INT64: {
9234 if (field_display & BASE_UNIT_STRING0x00001000) {
9235 unit_name_string *unit = (unit_name_string *)field_strings;
9236 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)
;
9237 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)
;
9238 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9239 range_string *rs = (range_string *)field_strings;
9240 while (rs->strptr) {
9241 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
)
;
9242 rs++;
9243 }
9244 } else if (field_display & BASE_EXT_STRING0x00000200) {
9245 val64_string_ext *vse = (val64_string_ext *)field_strings;
9246 val64_string *vs = (val64_string *)vse->_vs_p;
9247 while (vs->strptr) {
9248 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
)
;
9249 vs++;
9250 }
9251 val64_string_ext_free(vse);
9252 field_strings = NULL((void*)0);
9253 } else if (field_display == BASE_CUSTOM) {
9254 /* this will be a pointer to a function, don't free that */
9255 field_strings = NULL((void*)0);
9256 } else {
9257 val64_string *vs64 = (val64_string *)field_strings;
9258 while (vs64->strptr) {
9259 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)
;
9260 vs64++;
9261 }
9262 }
9263 break;
9264 }
9265 case FT_CHAR:
9266 case FT_UINT8:
9267 case FT_INT8:
9268 case FT_UINT16:
9269 case FT_INT16:
9270 case FT_UINT24:
9271 case FT_INT24:
9272 case FT_UINT32:
9273 case FT_INT32:
9274 case FT_FLOAT:
9275 case FT_DOUBLE: {
9276 if (field_display & BASE_UNIT_STRING0x00001000) {
9277 unit_name_string *unit = (unit_name_string *)field_strings;
9278 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)
;
9279 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)
;
9280 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9281 range_string *rs = (range_string *)field_strings;
9282 while (rs->strptr) {
9283 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
)
;
9284 rs++;
9285 }
9286 } else if (field_display & BASE_EXT_STRING0x00000200) {
9287 value_string_ext *vse = (value_string_ext *)field_strings;
9288 value_string *vs = (value_string *)vse->_vs_p;
9289 while (vs->strptr) {
9290 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
)
;
9291 vs++;
9292 }
9293 value_string_ext_free(vse);
9294 field_strings = NULL((void*)0);
9295 } else if (field_display == BASE_CUSTOM) {
9296 /* this will be a pointer to a function, don't free that */
9297 field_strings = NULL((void*)0);
9298 } else {
9299 value_string *vs = (value_string *)field_strings;
9300 while (vs->strptr) {
9301 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
)
;
9302 vs++;
9303 }
9304 }
9305 break;
9306 default:
9307 break;
9308 }
9309 }
9310
9311 if (field_type != FT_FRAMENUM) {
9312 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
)
;
9313 }
9314}
9315
9316static void
9317free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9318{
9319 header_field_info *hfi = (header_field_info *) data;
9320 int hf_id = hfi->id;
9321
9322 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
)
;
9323 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
)
;
9324 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
)
;
9325
9326 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9327
9328 if (hfi->parent == -1)
9329 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)
;
9330
9331 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9332}
9333
9334static void
9335free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9336{
9337 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9338}
9339
9340static void
9341free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9342{
9343 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9344
9345 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9346 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)
;
9347}
9348
9349/* free deregistered fields and data */
9350void
9351proto_free_deregistered_fields (void)
9352{
9353 expert_free_deregistered_expertinfos();
9354
9355 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9356 g_ptr_array_free(deregistered_fields, true1);
9357 deregistered_fields = g_ptr_array_new();
9358
9359 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9360 g_ptr_array_free(deregistered_data, true1);
9361 deregistered_data = g_ptr_array_new();
9362
9363 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9364 g_ptr_array_free(deregistered_slice, true1);
9365 deregistered_slice = g_ptr_array_new();
9366}
9367
9368static const value_string hf_display[] = {
9369 { BASE_NONE, "BASE_NONE" },
9370 { BASE_DEC, "BASE_DEC" },
9371 { BASE_HEX, "BASE_HEX" },
9372 { BASE_OCT, "BASE_OCT" },
9373 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9374 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9375 { BASE_CUSTOM, "BASE_CUSTOM" },
9376 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9377 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9378 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9379 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9380 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9381 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9382 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9383 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9384 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9385 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9386 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9387 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9388 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9389 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9390 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9391 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9392 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9393 { BASE_PT_UDP, "BASE_PT_UDP" },
9394 { BASE_PT_TCP, "BASE_PT_TCP" },
9395 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9396 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9397 { BASE_OUI, "BASE_OUI" },
9398 { 0, NULL((void*)0) } };
9399
9400const char* proto_field_display_to_string(int field_display)
9401{
9402 return val_to_str_const(field_display, hf_display, "Unknown");
9403}
9404
9405static inline port_type
9406display_to_port_type(field_display_e e)
9407{
9408 switch (e) {
9409 case BASE_PT_UDP:
9410 return PT_UDP;
9411 case BASE_PT_TCP:
9412 return PT_TCP;
9413 case BASE_PT_DCCP:
9414 return PT_DCCP;
9415 case BASE_PT_SCTP:
9416 return PT_SCTP;
9417 default:
9418 break;
9419 }
9420 return PT_NONE;
9421}
9422
9423/* temporary function containing assert part for easier profiling */
9424static void
9425tmp_fld_check_assert(header_field_info *hfinfo)
9426{
9427 char* tmp_str;
9428
9429 /* The field must have a name (with length > 0) */
9430 if (!hfinfo->name || !hfinfo->name[0]) {
9431 if (hfinfo->abbrev)
9432 /* Try to identify the field */
9433 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)
9434 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9435 else
9436 /* Hum, no luck */
9437 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)"
)
;
9438 }
9439
9440 /* fields with an empty string for an abbreviation aren't filterable */
9441 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9442 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)
;
9443
9444 /* TODO: This check is a significant percentage of startup time (~10%),
9445 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9446 It might be nice to have a way to disable this check when, e.g.,
9447 running TShark many times with the same configuration. */
9448 /* Check that the filter name (abbreviation) is legal;
9449 * it must contain only alphanumerics, '-', "_", and ".". */
9450 unsigned char c;
9451 c = module_check_valid_name(hfinfo->abbrev, false0);
9452 if (c) {
9453 if (c == '.') {
9454 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)
;
9455 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9456 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)
;
9457 } else {
9458 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)
;
9459 }
9460 }
9461
9462 /* These types of fields are allowed to have value_strings,
9463 * true_false_strings or a protocol_t struct
9464 */
9465 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9466 switch (hfinfo->type) {
9467
9468 /*
9469 * These types are allowed to support display value_strings,
9470 * value64_strings, the extended versions of the previous
9471 * two, range strings, or unit strings.
9472 */
9473 case FT_CHAR:
9474 case FT_UINT8:
9475 case FT_UINT16:
9476 case FT_UINT24:
9477 case FT_UINT32:
9478 case FT_UINT40:
9479 case FT_UINT48:
9480 case FT_UINT56:
9481 case FT_UINT64:
9482 case FT_INT8:
9483 case FT_INT16:
9484 case FT_INT24:
9485 case FT_INT32:
9486 case FT_INT40:
9487 case FT_INT48:
9488 case FT_INT56:
9489 case FT_INT64:
9490 case FT_BOOLEAN:
9491 case FT_PROTOCOL:
9492 break;
9493
9494 /*
9495 * This is allowed to have a value of type
9496 * enum ft_framenum_type to indicate what relationship
9497 * the frame in question has to the frame in which
9498 * the field is put.
9499 */
9500 case FT_FRAMENUM:
9501 break;
9502
9503 /*
9504 * These types are allowed to support only unit strings.
9505 */
9506 case FT_FLOAT:
9507 case FT_DOUBLE:
9508 case FT_IEEE_11073_SFLOAT:
9509 case FT_IEEE_11073_FLOAT:
9510 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9511 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))
9512 " (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))
9513 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))
;
9514 }
9515 break;
9516
9517 /*
9518 * These types are allowed to support display
9519 * time_value_strings.
9520 */
9521 case FT_ABSOLUTE_TIME:
9522 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9523 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9524 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9525 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9526 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))
9527 " (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))
9528 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))
;
9529 }
9530 break;
9531
9532 /*
9533 * This type is only allowed to support a string if it's
9534 * a protocol (for pinos).
9535 */
9536 case FT_BYTES:
9537 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9538 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))
9539 " (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))
9540 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))
;
9541 }
9542 break;
9543
9544 default:
9545 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))
9546 " (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))
9547 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))
;
9548 }
9549 }
9550
9551 /* TODO: This check may slow down startup, and output quite a few warnings.
9552 It would be good to be able to enable this (and possibly other checks?)
9553 in non-release builds. */
9554#ifdef ENABLE_CHECK_FILTER
9555 /* Check for duplicate value_string values.
9556 There are lots that have the same value *and* string, so for now only
9557 report those that have same value but different string. */
9558 if ((hfinfo->strings != NULL((void*)0)) &&
9559 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9560 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9561 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9562 (
9563 (hfinfo->type == FT_CHAR) ||
9564 (hfinfo->type == FT_UINT8) ||
9565 (hfinfo->type == FT_UINT16) ||
9566 (hfinfo->type == FT_UINT24) ||
9567 (hfinfo->type == FT_UINT32) ||
9568 (hfinfo->type == FT_INT8) ||
9569 (hfinfo->type == FT_INT16) ||
9570 (hfinfo->type == FT_INT24) ||
9571 (hfinfo->type == FT_INT32) )) {
9572
9573 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9574 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9575 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9576 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9577 } else {
9578 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9579 CHECK_HF_VALUE(value_string, "u", start_values);
9580 }
9581 } else {
9582 const value_string *start_values = (const value_string*)hfinfo->strings;
9583 CHECK_HF_VALUE(value_string, "u", start_values);
9584 }
9585 }
9586
9587 if (hfinfo->type == FT_BOOLEAN) {
9588 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9589 if (tfs) {
9590 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9591 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9593
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9592 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9593
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9593 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9593
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9594 }
9595 }
9596 }
9597
9598 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9599 const range_string *rs = (const range_string*)(hfinfo->strings);
9600 if (rs) {
9601 const range_string *this_it = rs;
9602
9603 do {
9604 if (this_it->value_max < this_it->value_min) {
9605 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"
, 9609, __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)
9606 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9609, __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)
9607 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9609, __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)
9608 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9609, __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)
9609 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9609, __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)
;
9610 ++this_it;
9611 continue;
9612 }
9613
9614 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9615 /* Not OK if this one is completely hidden by an earlier one! */
9616 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9617 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"
, 9623, __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)
9618 "(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"
, 9623, __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)
9619 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9623, __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)
9620 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9623, __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)
9621 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9623, __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)
9622 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9623, __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)
9623 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9623, __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)
;
9624 }
9625 }
9626 ++this_it;
9627 } while (this_it->strptr);
9628 }
9629 }
9630#endif
9631
9632 switch (hfinfo->type) {
9633
9634 case FT_CHAR:
9635 /* Require the char type to have BASE_HEX, BASE_OCT,
9636 * BASE_CUSTOM, or BASE_NONE as its base.
9637 *
9638 * If the display value is BASE_NONE and there is a
9639 * strings conversion then the dissector writer is
9640 * telling us that the field's numerical value is
9641 * meaningless; we'll avoid showing the value to the
9642 * user.
9643 */
9644 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9645 case BASE_HEX:
9646 case BASE_OCT:
9647 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9648 break;
9649 case BASE_NONE:
9650 if (hfinfo->strings == NULL((void*)0))
9651 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
))
9652 " 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
))
9653 " 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
))
9654 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
))
9655 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
))
;
9656 break;
9657 default:
9658 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9659 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)
9660 " 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)
9661 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)
9662 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)
;
9663 //wmem_free(NULL, tmp_str);
9664 }
9665 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9666 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
))
9667 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
))
9668 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
))
;
9669 }
9670 break;
9671 case FT_INT8:
9672 case FT_INT16:
9673 case FT_INT24:
9674 case FT_INT32:
9675 case FT_INT40:
9676 case FT_INT48:
9677 case FT_INT56:
9678 case FT_INT64:
9679 /* Hexadecimal and octal are, in printf() and everywhere
9680 * else, unsigned so don't allow dissectors to register a
9681 * signed field to be displayed unsigned. (Else how would
9682 * we display negative values?)
9683 */
9684 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9685 case BASE_HEX:
9686 case BASE_OCT:
9687 case BASE_DEC_HEX:
9688 case BASE_HEX_DEC:
9689 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9690 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)
9691 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)
9692 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)
;
9693 //wmem_free(NULL, tmp_str);
9694 }
9695 /* FALL THROUGH */
9696 case FT_UINT8:
9697 case FT_UINT16:
9698 case FT_UINT24:
9699 case FT_UINT32:
9700 case FT_UINT40:
9701 case FT_UINT48:
9702 case FT_UINT56:
9703 case FT_UINT64:
9704 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
))
) {
9705 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9706 if (hfinfo->type != FT_UINT16) {
9707 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))
9708 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))
9709 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))
;
9710 }
9711 if (hfinfo->strings != NULL((void*)0)) {
9712 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)
9713 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)
9714 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)
;
9715 }
9716 if (hfinfo->bitmask != 0) {
9717 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)
9718 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)
9719 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)
;
9720 }
9721 wmem_free(NULL((void*)0), tmp_str);
9722 break;
9723 }
9724
9725 if (hfinfo->display == BASE_OUI) {
9726 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9727 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) {
9728 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))
9729 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))
9730 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))
;
9731 }
9732 if (hfinfo->strings != NULL((void*)0)) {
9733 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)
9734 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)
9735 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)
;
9736 }
9737 /* It can be a FT_UINT24 with a 0 bitmask, or
9738 * larger with a bitmask with 24 bits set. */
9739 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9740 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)
9741 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)
9742 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)
;
9743 }
9744 wmem_free(NULL((void*)0), tmp_str);
9745 break;
9746 }
9747
9748 /* Require integral types (other than frame number,
9749 * which is always displayed in decimal) to have a
9750 * number base.
9751 *
9752 * If the display value is BASE_NONE and there is a
9753 * strings conversion then the dissector writer is
9754 * telling us that the field's numerical value is
9755 * meaningless; we'll avoid showing the value to the
9756 * user.
9757 */
9758 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9759 case BASE_DEC:
9760 case BASE_HEX:
9761 case BASE_OCT:
9762 case BASE_DEC_HEX:
9763 case BASE_HEX_DEC:
9764 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9765 break;
9766 case BASE_NONE:
9767 if (hfinfo->strings == NULL((void*)0)) {
9768 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
))
9769 " 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
))
9770 " 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
))
9771 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
))
9772 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
))
;
9773 }
9774 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9775 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
))
9776 " 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
))
9777 " 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
))
9778 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
))
9779 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
))
;
9780 }
9781 break;
9782
9783 default:
9784 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9785 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)
9786 " 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)
9787 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)
9788 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)
;
9789 //wmem_free(NULL, tmp_str);
9790 }
9791 break;
9792 case FT_BYTES:
9793 case FT_UINT_BYTES:
9794 /* Require bytes to have a "display type" that could
9795 * add a character between displayed bytes.
9796 */
9797 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9798 case BASE_NONE:
9799 case SEP_DOT:
9800 case SEP_DASH:
9801 case SEP_COLON:
9802 case SEP_SPACE:
9803 break;
9804 default:
9805 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9806 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)
9807 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)
;
9808 //wmem_free(NULL, tmp_str);
9809 }
9810 if (hfinfo->bitmask != 0)
9811 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
))
9812 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
))
9813 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
))
;
9814 //allowed to support string if its a protocol (for pinos)
9815 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9816 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
))
9817 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
))
9818 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
))
;
9819 break;
9820
9821 case FT_PROTOCOL:
9822 case FT_FRAMENUM:
9823 if (hfinfo->display != BASE_NONE) {
9824 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9825 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)
9826 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)
9827 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)
;
9828 //wmem_free(NULL, tmp_str);
9829 }
9830 if (hfinfo->bitmask != 0)
9831 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
))
9832 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
))
9833 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
))
;
9834 break;
9835
9836 case FT_BOOLEAN:
9837 break;
9838
9839 case FT_ABSOLUTE_TIME:
9840 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9841 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9842 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)
9843 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)
;
9844 //wmem_free(NULL, tmp_str);
9845 }
9846 if (hfinfo->bitmask != 0)
9847 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
))
9848 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
))
9849 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
))
;
9850 break;
9851
9852 case FT_STRING:
9853 case FT_STRINGZ:
9854 case FT_UINT_STRING:
9855 case FT_STRINGZPAD:
9856 case FT_STRINGZTRUNC:
9857 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9858 case BASE_NONE:
9859 case BASE_STR_WSP:
9860 break;
9861
9862 default:
9863 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9864 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)
9865 " 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)
9866 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)
9867 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)
;
9868 //wmem_free(NULL, tmp_str);
9869 }
9870
9871 if (hfinfo->bitmask != 0)
9872 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
))
9873 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
))
9874 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
))
;
9875 if (hfinfo->strings != NULL((void*)0))
9876 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
))
9877 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
))
9878 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
))
;
9879 break;
9880
9881 case FT_IPv4:
9882 switch (hfinfo->display) {
9883 case BASE_NONE:
9884 case BASE_NETMASK:
9885 break;
9886
9887 default:
9888 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9889 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)
9890 " 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)
9891 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)
9892 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)
;
9893 //wmem_free(NULL, tmp_str);
9894 break;
9895 }
9896 break;
9897 case FT_FLOAT:
9898 case FT_DOUBLE:
9899 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9900 case BASE_NONE:
9901 case BASE_DEC:
9902 case BASE_HEX:
9903 case BASE_EXP:
9904 case BASE_CUSTOM:
9905 break;
9906 default:
9907 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9908 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)
9909 " 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)
9910 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)
9911 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)
;
9912 //wmem_free(NULL, tmp_str);
9913 }
9914 if (hfinfo->bitmask != 0)
9915 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
))
9916 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
))
9917 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
))
;
9918 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9919 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
))
9920 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
))
9921 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
))
;
9922 break;
9923 case FT_IEEE_11073_SFLOAT:
9924 case FT_IEEE_11073_FLOAT:
9925 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9926 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9927 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)
9928 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)
9929 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)
9930 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)
;
9931 //wmem_free(NULL, tmp_str);
9932 }
9933 if (hfinfo->bitmask != 0)
9934 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
))
9935 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
))
9936 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
))
;
9937 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9938 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
))
9939 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
))
9940 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
))
;
9941 break;
9942 default:
9943 if (hfinfo->display != BASE_NONE) {
9944 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9945 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)
9946 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)
9947 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)
9948 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)
;
9949 //wmem_free(NULL, tmp_str);
9950 }
9951 if (hfinfo->bitmask != 0)
9952 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
))
9953 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
))
9954 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
))
;
9955 if (hfinfo->strings != NULL((void*)0))
9956 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
))
9957 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
))
9958 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
))
;
9959 break;
9960 }
9961}
9962
9963static void
9964register_type_length_mismatch(void)
9965{
9966 static ei_register_info ei[] = {
9967 { &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)}}
}},
9968 { &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)}}
}},
9969 };
9970
9971 expert_module_t* expert_type_length_mismatch;
9972
9973 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9974
9975 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9976 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9977
9978 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9979 disabling them makes no sense. */
9980 proto_set_cant_toggle(proto_type_length_mismatch);
9981}
9982
9983static void
9984register_byte_array_string_decodinws_error(void)
9985{
9986 static ei_register_info ei[] = {
9987 { &ei_byte_array_string_decoding_failed_error,
9988 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9989 "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)}}
9990 }
9991 },
9992 };
9993
9994 expert_module_t* expert_byte_array_string_decoding_error;
9995
9996 proto_byte_array_string_decoding_error =
9997 proto_register_protocol("Byte Array-String Decoding Error",
9998 "Byte Array-string decoding error",
9999 "_ws.byte_array_string.decoding_error");
10000
10001 expert_byte_array_string_decoding_error =
10002 expert_register_protocol(proto_byte_array_string_decoding_error);
10003 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10004
10005 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10006 disabling them makes no sense. */
10007 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10008}
10009
10010static void
10011register_date_time_string_decodinws_error(void)
10012{
10013 static ei_register_info ei[] = {
10014 { &ei_date_time_string_decoding_failed_error,
10015 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10016 "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)}}
10017 }
10018 },
10019 };
10020
10021 expert_module_t* expert_date_time_string_decoding_error;
10022
10023 proto_date_time_string_decoding_error =
10024 proto_register_protocol("Date and Time-String Decoding Error",
10025 "Date and Time-string decoding error",
10026 "_ws.date_time_string.decoding_error");
10027
10028 expert_date_time_string_decoding_error =
10029 expert_register_protocol(proto_date_time_string_decoding_error);
10030 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10031
10032 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10033 disabling them makes no sense. */
10034 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10035}
10036
10037static void
10038register_string_errors(void)
10039{
10040 static ei_register_info ei[] = {
10041 { &ei_string_trailing_characters,
10042 { "_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)}}
}
10043 },
10044 };
10045
10046 expert_module_t* expert_string_errors;
10047
10048 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10049
10050 expert_string_errors = expert_register_protocol(proto_string_errors);
10051 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10052
10053 /* "String Errors" isn't really a protocol, it's an error indication;
10054 disabling them makes no sense. */
10055 proto_set_cant_toggle(proto_string_errors);
10056}
10057
10058static int
10059proto_register_field_init(header_field_info *hfinfo, const int parent)
10060{
10061
10062 tmp_fld_check_assert(hfinfo);
10063
10064 hfinfo->parent = parent;
10065 hfinfo->same_name_next = NULL((void*)0);
10066 hfinfo->same_name_prev_id = -1;
10067
10068 /* if we always add and never delete, then id == len - 1 is correct */
10069 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10070 if (!gpa_hfinfo.hfi) {
10071 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10072 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10073 /* The entry with index 0 is not used. */
10074 gpa_hfinfo.hfi[0] = NULL((void*)0);
10075 gpa_hfinfo.len = 1;
10076 } else {
10077 gpa_hfinfo.allocated_len += 1000;
10078 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10079 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10080 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10081 }
10082 }
10083 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10084 gpa_hfinfo.len++;
10085 hfinfo->id = gpa_hfinfo.len - 1;
10086
10087 /* if we have real names, enter this field in the name tree */
10088 /* Already checked in tmp_fld_check_assert */
10089 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10090 {
10091
10092 header_field_info *same_name_next_hfinfo;
10093
10094 /* We allow multiple hfinfo's to be registered under the same
10095 * abbreviation. This was done for X.25, as, depending
10096 * on whether it's modulo-8 or modulo-128 operation,
10097 * some bitfield fields may be in different bits of
10098 * a byte, and we want to be able to refer to that field
10099 * with one name regardless of whether the packets
10100 * are modulo-8 or modulo-128 packets. */
10101
10102 /* wmem_map_insert - if key is already present the previous
10103 * hfinfo with the same key/name is returned, otherwise NULL */
10104 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10105 if (same_name_hfinfo) {
10106 /* There's already a field with this name.
10107 * Put the current field *before* that field
10108 * in the list of fields with this name, Thus,
10109 * we end up with an effectively
10110 * doubly-linked-list of same-named hfinfo's,
10111 * with the head of the list (stored in the
10112 * hash) being the last seen hfinfo.
10113 */
10114 same_name_next_hfinfo =
10115 same_name_hfinfo->same_name_next;
10116
10117 hfinfo->same_name_next = same_name_next_hfinfo;
10118 if (same_name_next_hfinfo)
10119 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10120
10121 same_name_hfinfo->same_name_next = hfinfo;
10122 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10123#ifdef ENABLE_CHECK_FILTER
10124 while (same_name_hfinfo) {
10125 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10126 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", 10126
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10127 same_name_hfinfo = same_name_hfinfo->same_name_next;
10128 }
10129#endif
10130 }
10131 }
10132
10133 return hfinfo->id;
10134}
10135
10136void
10137proto_register_subtree_array(int * const *indices, const int num_indices)
10138{
10139 int i;
10140 int *const *ptr = indices;
10141
10142 /*
10143 * If we've already allocated the array of tree types, expand
10144 * it; this lets plugins such as mate add tree types after
10145 * the initial startup. (If we haven't already allocated it,
10146 * we don't allocate it; on the first pass, we just assign
10147 * ett values and keep track of how many we've assigned, and
10148 * when we're finished registering all dissectors we allocate
10149 * the array, so that we do only one allocation rather than
10150 * wasting CPU time and memory by growing the array for each
10151 * dissector that registers ett values.)
10152 */
10153 if (tree_is_expanded != NULL((void*)0)) {
10154 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10155
10156 /* set new items to 0 */
10157 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10158 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10159 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10160 }
10161
10162 /*
10163 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10164 * returning the indices through the pointers in the array whose
10165 * first element is pointed to by "indices", and update
10166 * "num_tree_types" appropriately.
10167 */
10168 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10169 if (**ptr != -1 && **ptr != 0) {
10170 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.")
10171 " 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.")
10172 " 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.")
10173 " 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.")
;
10174 }
10175 **ptr = num_tree_types;
10176 }
10177}
10178
10179static void
10180mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10181{
10182 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10183 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10184 char *last_char;
10185
10186 /* ..... field_name: dataaaaaaaaaaaaa
10187 * |
10188 * ^^^^^ name_pos
10189 *
10190 * ..... field_name […]: dataaaaaaaaaaaaa
10191 *
10192 * name_pos==0 means that we have only data or only a field_name
10193 */
10194
10195 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10195, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10196
10197 if (name_pos >= size - trunc_len) {
10198 /* No room for trunc_str after the field_name, put it first. */
10199 name_pos = 0;
10200 }
10201
10202 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10203 if (name_pos == 0) {
10204 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10205 memcpy(label_str, trunc_str + 1, trunc_len);
10206 } else {
10207 memcpy(label_str + name_pos, trunc_str, trunc_len);
10208 }
10209 /* in general, label_str is UTF-8
10210 we can truncate it only at the beginning of a new character
10211 we go backwards from the byte right after our buffer and
10212 find the next starting byte of a UTF-8 character, this is
10213 where we cut
10214 there's no need to use g_utf8_find_prev_char(), the search
10215 will always succeed since we copied trunc_str into the
10216 buffer */
10217 /* g_utf8_prev_char does not deference the memory address
10218 * passed in (until after decrementing it, so it is perfectly
10219 * legal to pass in a pointer one past the last element.
10220 */
10221 last_char = g_utf8_prev_char(label_str + size);
10222 *last_char = '\0';
10223 /* This is unnecessary (above always terminates), but try to
10224 * convince Coverity to avoid dozens of false positives. */
10225 label_str[size - 1] = '\0';
10226
10227 if (value_pos && *value_pos > 0) {
10228 if (name_pos == 0) {
10229 *value_pos += trunc_len;
10230 } else {
10231 /* Move one back to include trunc_str in the value. */
10232 *value_pos -= 1;
10233 }
10234 }
10235
10236 /* Check if value_pos is past label_str. */
10237 if (value_pos && *value_pos >= size) {
10238 *value_pos = size - 1;
10239 }
10240}
10241
10242static void
10243label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10244{
10245 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10246}
10247
10248static size_t
10249label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10250{
10251 size_t name_pos;
10252
10253 /* "%s: %s", hfinfo->name, text */
10254 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)
;
10255 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10256 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10257 if (value_pos) {
10258 *value_pos = pos;
10259 }
10260 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10261 }
10262
10263 if (pos >= ITEM_LABEL_LENGTH240) {
10264 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10265 label_mark_truncated(label_str, name_pos, value_pos);
10266 }
10267
10268 return pos;
10269}
10270
10271static size_t
10272label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10273{
10274 size_t name_pos;
10275
10276 /* "%s: %s (%s)", hfinfo->name, text, descr */
10277 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)
;
10278 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10279 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10280 if (value_pos) {
10281 *value_pos = pos;
10282 }
10283 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10284 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)
;
10285 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)
;
10286 } else {
10287 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)
;
10288 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10289 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)
;
10290 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10291 }
10292 }
10293
10294 if (pos >= ITEM_LABEL_LENGTH240) {
10295 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10296 label_mark_truncated(label_str, name_pos, value_pos);
10297 }
10298
10299 return pos;
10300}
10301
10302void
10303proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10304{
10305 const header_field_info *hfinfo;
10306 const char *str;
10307 const uint8_t *bytes;
10308 uint32_t integer;
10309 const ipv4_addr_and_mask *ipv4;
10310 const ipv6_addr_and_prefix *ipv6;
10311 const e_guid_t *guid;
10312 char *name;
10313 address addr;
10314 char *addr_str;
10315 char *tmp;
10316
10317 if (!label_str) {
10318 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10318, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10319 return;
10320 }
10321
10322 label_str[0]= '\0';
10323
10324 if (!fi) {
10325 return;
10326 }
10327
10328 hfinfo = fi->hfinfo;
10329
10330 switch (hfinfo->type) {
10331 case FT_NONE:
10332 case FT_PROTOCOL:
10333 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10334 if (value_pos) {
10335 *value_pos = strlen(hfinfo->name);
10336 }
10337 break;
10338
10339 case FT_BOOLEAN:
10340 fill_label_boolean(fi, label_str, value_pos);
10341 break;
10342
10343 case FT_BYTES:
10344 case FT_UINT_BYTES:
10345 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10346 fvalue_get_bytes_data(fi->value),
10347 (unsigned)fvalue_length2(fi->value));
10348 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10349 wmem_free(NULL((void*)0), tmp);
10350 break;
10351
10352 case FT_CHAR:
10353 if (hfinfo->bitmask) {
10354 fill_label_bitfield_char(fi, label_str, value_pos);
10355 } else {
10356 fill_label_char(fi, label_str, value_pos);
10357 }
10358 break;
10359
10360 /* Four types of integers to take care of:
10361 * Bitfield, with val_string
10362 * Bitfield, w/o val_string
10363 * Non-bitfield, with val_string
10364 * Non-bitfield, w/o val_string
10365 */
10366 case FT_UINT8:
10367 case FT_UINT16:
10368 case FT_UINT24:
10369 case FT_UINT32:
10370 if (hfinfo->bitmask) {
10371 fill_label_bitfield(fi, label_str, value_pos, false0);
10372 } else {
10373 fill_label_number(fi, label_str, value_pos, false0);
10374 }
10375 break;
10376
10377 case FT_FRAMENUM:
10378 fill_label_number(fi, label_str, value_pos, false0);
10379 break;
10380
10381 case FT_UINT40:
10382 case FT_UINT48:
10383 case FT_UINT56:
10384 case FT_UINT64:
10385 if (hfinfo->bitmask) {
10386 fill_label_bitfield64(fi, label_str, value_pos, false0);
10387 } else {
10388 fill_label_number64(fi, label_str, value_pos, false0);
10389 }
10390 break;
10391
10392 case FT_INT8:
10393 case FT_INT16:
10394 case FT_INT24:
10395 case FT_INT32:
10396 if (hfinfo->bitmask) {
10397 fill_label_bitfield(fi, label_str, value_pos, true1);
10398 } else {
10399 fill_label_number(fi, label_str, value_pos, true1);
10400 }
10401 break;
10402
10403 case FT_INT40:
10404 case FT_INT48:
10405 case FT_INT56:
10406 case FT_INT64:
10407 if (hfinfo->bitmask) {
10408 fill_label_bitfield64(fi, label_str, value_pos, true1);
10409 } else {
10410 fill_label_number64(fi, label_str, value_pos, true1);
10411 }
10412 break;
10413
10414 case FT_FLOAT:
10415 case FT_DOUBLE:
10416 fill_label_float(fi, label_str, value_pos);
10417 break;
10418
10419 case FT_ABSOLUTE_TIME:
10420 {
10421 const nstime_t *value = fvalue_get_time(fi->value);
10422 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10423 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10424 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10425 }
10426 if (hfinfo->strings) {
10427 /*
10428 * Table of time valus to be displayed
10429 * specially.
10430 */
10431 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10432 if (time_string != NULL((void*)0)) {
10433 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10434 break;
10435 }
10436 }
10437 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10438 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10439 wmem_free(NULL((void*)0), tmp);
10440 break;
10441 }
10442 case FT_RELATIVE_TIME:
10443 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10444 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10445 wmem_free(NULL((void*)0), tmp);
10446 break;
10447
10448 case FT_IPXNET:
10449 integer = fvalue_get_uinteger(fi->value);
10450 tmp = get_ipxnet_name(NULL((void*)0), integer);
10451 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10452 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10453 wmem_free(NULL((void*)0), tmp);
10454 wmem_free(NULL((void*)0), addr_str);
10455 break;
10456
10457 case FT_VINES:
10458 addr.type = AT_VINES;
10459 addr.len = VINES_ADDR_LEN6;
10460 addr.data = fvalue_get_bytes_data(fi->value);
10461
10462 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10463 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10464 wmem_free(NULL((void*)0), addr_str);
10465 break;
10466
10467 case FT_ETHER:
10468 bytes = fvalue_get_bytes_data(fi->value);
10469
10470 addr.type = AT_ETHER;
10471 addr.len = 6;
10472 addr.data = bytes;
10473
10474 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10475 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10476 wmem_free(NULL((void*)0), addr_str);
10477 break;
10478
10479 case FT_IPv4:
10480 ipv4 = fvalue_get_ipv4(fi->value);
10481 set_address_ipv4(&addr, ipv4);
10482
10483 if (hfinfo->display == BASE_NETMASK) {
10484 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10485 } else {
10486 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10487 }
10488 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10489 wmem_free(NULL((void*)0), addr_str);
10490 free_address(&addr);
10491 break;
10492
10493 case FT_IPv6:
10494 ipv6 = fvalue_get_ipv6(fi->value);
10495 set_address_ipv6(&addr, ipv6);
10496
10497 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10498 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10499 wmem_free(NULL((void*)0), addr_str);
10500 free_address(&addr);
10501 break;
10502
10503 case FT_FCWWN:
10504 bytes = fvalue_get_bytes_data(fi->value);
10505 addr.type = AT_FCWWN;
10506 addr.len = FCWWN_ADDR_LEN8;
10507 addr.data = bytes;
10508
10509 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10510 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10511 wmem_free(NULL((void*)0), addr_str);
10512 break;
10513
10514 case FT_GUID:
10515 guid = fvalue_get_guid(fi->value);
10516 tmp = guid_to_str(NULL((void*)0), guid);
10517 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10518 wmem_free(NULL((void*)0), tmp);
10519 break;
10520
10521 case FT_OID:
10522 bytes = fvalue_get_bytes_data(fi->value);
10523 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10524 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10525 if (name) {
10526 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10527 wmem_free(NULL((void*)0), name);
10528 } else {
10529 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10530 }
10531 wmem_free(NULL((void*)0), tmp);
10532 break;
10533
10534 case FT_REL_OID:
10535 bytes = fvalue_get_bytes_data(fi->value);
10536 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10537 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10538 if (name) {
10539 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10540 wmem_free(NULL((void*)0), name);
10541 } else {
10542 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10543 }
10544 wmem_free(NULL((void*)0), tmp);
10545 break;
10546
10547 case FT_SYSTEM_ID:
10548 bytes = fvalue_get_bytes_data(fi->value);
10549 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10550 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10551 wmem_free(NULL((void*)0), tmp);
10552 break;
10553
10554 case FT_EUI64:
10555 bytes = fvalue_get_bytes_data(fi->value);
10556 addr.type = AT_EUI64;
10557 addr.len = EUI64_ADDR_LEN8;
10558 addr.data = bytes;
10559
10560 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10561 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10562 wmem_free(NULL((void*)0), addr_str);
10563 break;
10564 case FT_STRING:
10565 case FT_STRINGZ:
10566 case FT_UINT_STRING:
10567 case FT_STRINGZPAD:
10568 case FT_STRINGZTRUNC:
10569 case FT_AX25:
10570 str = fvalue_get_string(fi->value);
10571 label_fill(label_str, 0, hfinfo, str, value_pos);
10572 break;
10573
10574 case FT_IEEE_11073_SFLOAT:
10575 case FT_IEEE_11073_FLOAT:
10576 fill_label_ieee_11073_float(fi, label_str, value_pos);
10577 break;
10578
10579 default:
10580 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
))
10581 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
))
10582 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
))
10583 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
))
;
10584 break;
10585 }
10586}
10587
10588static void
10589fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10590{
10591 char *p;
10592 unsigned bitfield_byte_length = 0;
10593 int bitwidth;
10594 uint64_t unshifted_value;
10595 uint64_t value;
10596
10597 const header_field_info *hfinfo = fi->hfinfo;
10598
10599 value = fvalue_get_uinteger64(fi->value);
10600 if (hfinfo->bitmask) {
10601 /* Figure out the bit width */
10602 bitwidth = hfinfo_container_bitwidth(hfinfo);
10603
10604 /* Un-shift bits */
10605 unshifted_value = value;
10606 unshifted_value <<= hfinfo_bitshift(hfinfo);
10607
10608 /* Create the bitfield first */
10609 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10610 bitfield_byte_length = (unsigned) (p - label_str);
10611 }
10612
10613 /* Fill in the textual info */
10614 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10615}
10616
10617static const char *
10618hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10619{
10620 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10621 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10622
10623 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10624 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10625 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10626 else
10627 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10628 }
10629
10630 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10631 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10632
10633 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10634 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10635
10636 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10637}
10638
10639static const char *
10640hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10641{
10642 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10643 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10644 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10645 else
10646 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10647 }
10648
10649 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10650 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10651
10652 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10653 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10654
10655 /* If this is reached somebody registered a 64-bit field with a 32-bit
10656 * value-string, which isn't right. */
10657 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)
10658 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10659
10660 /* This is necessary to squelch MSVC errors; is there
10661 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10662 never returns? */
10663 return NULL((void*)0);
10664}
10665
10666static const char *
10667hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10668{
10669 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10670 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10671
10672 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)
;
10673
10674 /* This is necessary to squelch MSVC errors; is there
10675 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10676 never returns? */
10677 return NULL((void*)0);
10678}
10679
10680static const char *
10681hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10682{
10683 const char *str = hf_try_val_to_str(value, hfinfo);
10684
10685 return (str) ? str : unknown_str;
10686}
10687
10688static const char *
10689hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10690{
10691 const char *str = hf_try_val64_to_str(value, hfinfo);
10692
10693 return (str) ? str : unknown_str;
10694}
10695
10696/* Fills data for bitfield chars with val_strings */
10697static void
10698fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10699{
10700 char *p;
10701 unsigned bitfield_byte_length;
10702 int bitwidth;
10703 uint32_t unshifted_value;
10704 uint32_t value;
10705
10706 char buf[32];
10707 const char *out;
10708
10709 const header_field_info *hfinfo = fi->hfinfo;
10710
10711 /* Figure out the bit width */
10712 bitwidth = hfinfo_container_bitwidth(hfinfo);
10713
10714 /* Un-shift bits */
10715 value = fvalue_get_uinteger(fi->value);
10716
10717 unshifted_value = value;
10718 if (hfinfo->bitmask) {
10719 unshifted_value <<= hfinfo_bitshift(hfinfo);
10720 }
10721
10722 /* Create the bitfield first */
10723 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10724 bitfield_byte_length = (unsigned) (p - label_str);
10725
10726 /* Fill in the textual info using stored (shifted) value */
10727 if (hfinfo->display == BASE_CUSTOM) {
10728 char tmp[ITEM_LABEL_LENGTH240];
10729 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10730
10731 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10731, "fmtfunc"))))
;
10732 fmtfunc(tmp, value);
10733 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10734 }
10735 else if (hfinfo->strings) {
10736 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10737
10738 out = hfinfo_char_vals_format(hfinfo, buf, value);
10739 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10740 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10741 else
10742 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10743 }
10744 else {
10745 out = hfinfo_char_value_format(hfinfo, buf, value);
10746
10747 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10748 }
10749}
10750
10751/* Fills data for bitfield ints with val_strings */
10752static void
10753fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10754{
10755 char *p;
10756 unsigned bitfield_byte_length;
10757 int bitwidth;
10758 uint32_t value, unshifted_value;
10759 char buf[NUMBER_LABEL_LENGTH80];
10760 const char *out;
10761
10762 const header_field_info *hfinfo = fi->hfinfo;
10763
10764 /* Figure out the bit width */
10765 if (fi->flags & FI_VARINT0x00040000)
10766 bitwidth = fi->length*8;
10767 else
10768 bitwidth = hfinfo_container_bitwidth(hfinfo);
10769
10770 /* Un-shift bits */
10771 if (is_signed)
10772 value = fvalue_get_sinteger(fi->value);
10773 else
10774 value = fvalue_get_uinteger(fi->value);
10775
10776 unshifted_value = value;
10777 if (hfinfo->bitmask) {
10778 unshifted_value <<= hfinfo_bitshift(hfinfo);
10779 }
10780
10781 /* Create the bitfield first */
10782 if (fi->flags & FI_VARINT0x00040000)
10783 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10784 else
10785 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10786 bitfield_byte_length = (unsigned) (p - label_str);
10787
10788 /* Fill in the textual info using stored (shifted) value */
10789 if (hfinfo->display == BASE_CUSTOM) {
10790 char tmp[ITEM_LABEL_LENGTH240];
10791 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10792
10793 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10793, "fmtfunc"))))
;
10794 fmtfunc(tmp, value);
10795 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10796 }
10797 else if (hfinfo->strings) {
10798 const char *val_str = hf_try_val_to_str(value, hfinfo);
10799
10800 out = hfinfo_number_vals_format(hfinfo, buf, value);
10801 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10802 /*
10803 * Unique values only display value_string string
10804 * if there is a match. Otherwise it's just a number
10805 */
10806 if (val_str) {
10807 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10808 } else {
10809 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10810 }
10811 } else {
10812 if (val_str == NULL((void*)0))
10813 val_str = "Unknown";
10814
10815 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10816 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10817 else
10818 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10819 }
10820 }
10821 else {
10822 out = hfinfo_number_value_format(hfinfo, buf, value);
10823
10824 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10825 }
10826}
10827
10828static void
10829fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10830{
10831 char *p;
10832 unsigned bitfield_byte_length;
10833 int bitwidth;
10834 uint64_t value, unshifted_value;
10835 char buf[NUMBER_LABEL_LENGTH80];
10836 const char *out;
10837
10838 const header_field_info *hfinfo = fi->hfinfo;
10839
10840 /* Figure out the bit width */
10841 if (fi->flags & FI_VARINT0x00040000)
10842 bitwidth = fi->length*8;
10843 else
10844 bitwidth = hfinfo_container_bitwidth(hfinfo);
10845
10846 /* Un-shift bits */
10847 if (is_signed)
10848 value = fvalue_get_sinteger64(fi->value);
10849 else
10850 value = fvalue_get_uinteger64(fi->value);
10851
10852 unshifted_value = value;
10853 if (hfinfo->bitmask) {
10854 unshifted_value <<= hfinfo_bitshift(hfinfo);
10855 }
10856
10857 /* Create the bitfield first */
10858 if (fi->flags & FI_VARINT0x00040000)
10859 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10860 else
10861 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10862 bitfield_byte_length = (unsigned) (p - label_str);
10863
10864 /* Fill in the textual info using stored (shifted) value */
10865 if (hfinfo->display == BASE_CUSTOM) {
10866 char tmp[ITEM_LABEL_LENGTH240];
10867 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10868
10869 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10869, "fmtfunc64"
))))
;
10870 fmtfunc64(tmp, value);
10871 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10872 }
10873 else if (hfinfo->strings) {
10874 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10875
10876 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10877 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10878 /*
10879 * Unique values only display value_string string
10880 * if there is a match. Otherwise it's just a number
10881 */
10882 if (val_str) {
10883 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10884 } else {
10885 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10886 }
10887 } else {
10888 if (val_str == NULL((void*)0))
10889 val_str = "Unknown";
10890
10891 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10892 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10893 else
10894 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10895 }
10896 }
10897 else {
10898 out = hfinfo_number_value_format64(hfinfo, buf, value);
10899
10900 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10901 }
10902}
10903
10904static void
10905fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10906{
10907 const header_field_info *hfinfo = fi->hfinfo;
10908 uint32_t value;
10909
10910 char buf[32];
10911 const char *out;
10912
10913 value = fvalue_get_uinteger(fi->value);
10914
10915 /* Fill in the textual info */
10916 if (hfinfo->display == BASE_CUSTOM) {
10917 char tmp[ITEM_LABEL_LENGTH240];
10918 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10919
10920 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10920, "fmtfunc"))))
;
10921 fmtfunc(tmp, value);
10922 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10923 }
10924 else if (hfinfo->strings) {
10925 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10926
10927 out = hfinfo_char_vals_format(hfinfo, buf, value);
10928 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10929 }
10930 else {
10931 out = hfinfo_char_value_format(hfinfo, buf, value);
10932
10933 label_fill(label_str, 0, hfinfo, out, value_pos);
10934 }
10935}
10936
10937static void
10938fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10939{
10940 const header_field_info *hfinfo = fi->hfinfo;
10941 uint32_t value;
10942
10943 char buf[NUMBER_LABEL_LENGTH80];
10944 const char *out;
10945
10946 if (is_signed)
10947 value = fvalue_get_sinteger(fi->value);
10948 else
10949 value = fvalue_get_uinteger(fi->value);
10950
10951 /* Fill in the textual info */
10952 if (hfinfo->display == BASE_CUSTOM) {
10953 char tmp[ITEM_LABEL_LENGTH240];
10954 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10955
10956 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10956, "fmtfunc"))))
;
10957 fmtfunc(tmp, value);
10958 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10959 }
10960 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10961 /*
10962 * It makes no sense to have a value-string table for a
10963 * frame-number field - they're just integers giving
10964 * the ordinal frame number.
10965 */
10966 const char *val_str = hf_try_val_to_str(value, hfinfo);
10967
10968 out = hfinfo_number_vals_format(hfinfo, buf, value);
10969 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10970 /*
10971 * Unique values only display value_string string
10972 * if there is a match. Otherwise it's just a number
10973 */
10974 if (val_str) {
10975 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10976 } else {
10977 label_fill(label_str, 0, hfinfo, out, value_pos);
10978 }
10979 } else {
10980 if (val_str == NULL((void*)0))
10981 val_str = "Unknown";
10982
10983 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10984 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10985 else
10986 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10987 }
10988 }
10989 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
))
) {
10990 char tmp[ITEM_LABEL_LENGTH240];
10991
10992 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10993 display_to_port_type((field_display_e)hfinfo->display), value);
10994 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10995 }
10996 else {
10997 out = hfinfo_number_value_format(hfinfo, buf, value);
10998
10999 label_fill(label_str, 0, hfinfo, out, value_pos);
11000 }
11001}
11002
11003static void
11004fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11005{
11006 const header_field_info *hfinfo = fi->hfinfo;
11007 uint64_t value;
11008
11009 char buf[NUMBER_LABEL_LENGTH80];
11010 const char *out;
11011
11012 if (is_signed)
11013 value = fvalue_get_sinteger64(fi->value);
11014 else
11015 value = fvalue_get_uinteger64(fi->value);
11016
11017 /* Fill in the textual info */
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, 0, 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, 0, hfinfo, val_str, out, value_pos);
11037 } else {
11038 label_fill(label_str, 0, 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, 0, hfinfo, val_str, value_pos);
11046 else
11047 label_fill_descr(label_str, 0, 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, 0, hfinfo, out, value_pos);
11054 }
11055}
11056
11057static size_t
11058fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11059{
11060 int display;
11061 int n;
11062 double value;
11063
11064 if (label_str_size < 12) {
11065 /* Not enough room to write an entire floating point value. */
11066 return 0;
11067 }
11068
11069 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11070 value = fvalue_get_floating(fi->value);
11071
11072 if (display == BASE_CUSTOM) {
11073 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11074 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11074, "fmtfunc"))))
;
11075 fmtfunc(label_str, value);
11076 return strlen(label_str);
11077 }
11078
11079 switch (display) {
11080 case BASE_NONE:
11081 if (fi->hfinfo->type == FT_FLOAT) {
11082 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11083 } else {
11084 n = (int)strlen(dtoa_g_fmt(label_str, value));
11085 }
11086 break;
11087 case BASE_DEC:
11088 n = snprintf(label_str, label_str_size, "%f", value);
11089 break;
11090 case BASE_HEX:
11091 n = snprintf(label_str, label_str_size, "%a", value);
11092 break;
11093 case BASE_EXP:
11094 n = snprintf(label_str, label_str_size, "%e", value);
11095 break;
11096 default:
11097 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11097
, __func__, "assertion \"not reached\" failed")
;
11098 }
11099 if (n < 0) {
11100 return 0; /* error */
11101 }
11102 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11103 const char *hf_str_val;
11104 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11105 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11106 }
11107 if (n > label_str_size) {
11108 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11108, __func__, "label length too small"); } } while (0)
;
11109 return strlen(label_str);
11110 }
11111
11112 return n;
11113}
11114
11115void
11116fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11117{
11118 char tmp[ITEM_LABEL_LENGTH240];
11119
11120 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11121 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11122}
11123
11124static size_t
11125fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11126{
11127 int display;
11128 size_t pos = 0;
11129 double value;
11130 char* tmp_str;
11131
11132 if (label_str_size < 12) {
11133 /* Not enough room to write an entire floating point value. */
11134 return 0;
11135 }
11136
11137 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11138 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11139 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11140 wmem_free(NULL((void*)0), tmp_str);
11141
11142 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11143 const char *hf_str_val;
11144 fvalue_to_double(fi->value, &value);
11145 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11146 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)
;
11147 }
11148 if ((int)pos > label_str_size) {
11149 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11149, __func__, "label length too small"); } } while (0)
;
11150 return strlen(label_str);
11151 }
11152
11153 return pos;
11154}
11155
11156void
11157fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11158{
11159 char tmp[ITEM_LABEL_LENGTH240];
11160
11161 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11162 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11163}
11164
11165int
11166hfinfo_bitshift(const header_field_info *hfinfo)
11167{
11168 return ws_ctz(hfinfo->bitmask);
11169}
11170
11171
11172static int
11173hfinfo_bitoffset(const header_field_info *hfinfo)
11174{
11175 if (!hfinfo->bitmask) {
11176 return 0;
11177 }
11178
11179 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11180 * as the first bit */
11181 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11182}
11183
11184static int
11185hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11186{
11187 if (!hfinfo->bitmask) {
11188 return 0;
11189 }
11190
11191 /* ilog2 = first set bit, ctz = last set bit */
11192 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11193}
11194
11195static int
11196hfinfo_type_bitwidth(enum ftenum type)
11197{
11198 int bitwidth = 0;
11199
11200 switch (type) {
11201 case FT_CHAR:
11202 case FT_UINT8:
11203 case FT_INT8:
11204 bitwidth = 8;
11205 break;
11206 case FT_UINT16:
11207 case FT_INT16:
11208 bitwidth = 16;
11209 break;
11210 case FT_UINT24:
11211 case FT_INT24:
11212 bitwidth = 24;
11213 break;
11214 case FT_UINT32:
11215 case FT_INT32:
11216 bitwidth = 32;
11217 break;
11218 case FT_UINT40:
11219 case FT_INT40:
11220 bitwidth = 40;
11221 break;
11222 case FT_UINT48:
11223 case FT_INT48:
11224 bitwidth = 48;
11225 break;
11226 case FT_UINT56:
11227 case FT_INT56:
11228 bitwidth = 56;
11229 break;
11230 case FT_UINT64:
11231 case FT_INT64:
11232 bitwidth = 64;
11233 break;
11234 default:
11235 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11235))
;
11236 ;
11237 }
11238 return bitwidth;
11239}
11240
11241
11242static int
11243hfinfo_container_bitwidth(const header_field_info *hfinfo)
11244{
11245 if (!hfinfo->bitmask) {
11246 return 0;
11247 }
11248
11249 if (hfinfo->type == FT_BOOLEAN) {
11250 return hfinfo->display; /* hacky? :) */
11251 }
11252
11253 return hfinfo_type_bitwidth(hfinfo->type);
11254}
11255
11256static int
11257hfinfo_hex_digits(const header_field_info *hfinfo)
11258{
11259 int bitwidth;
11260
11261 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11262 * appropriate to determine the number of hex digits for the field.
11263 * So instead, we compute it from the bitmask.
11264 */
11265 if (hfinfo->bitmask != 0) {
11266 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11267 } else {
11268 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11269 }
11270
11271 /* Divide by 4, rounding up, to get number of hex digits. */
11272 return (bitwidth + 3) / 4;
11273}
11274
11275const char *
11276hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11277{
11278 char *ptr = &buf[6];
11279 static const char hex_digits[16] =
11280 { '0', '1', '2', '3', '4', '5', '6', '7',
11281 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11282
11283 *ptr = '\0';
11284 *(--ptr) = '\'';
11285 /* Properly format value */
11286 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11287 /*
11288 * Printable, so just show the character, and, if it needs
11289 * to be escaped, escape it.
11290 */
11291 *(--ptr) = value;
11292 if (value == '\\' || value == '\'')
11293 *(--ptr) = '\\';
11294 } else {
11295 /*
11296 * Non-printable; show it as an escape sequence.
11297 */
11298 switch (value) {
11299
11300 case '\0':
11301 /*
11302 * Show a NUL with only one digit.
11303 */
11304 *(--ptr) = '0';
11305 break;
11306
11307 case '\a':
11308 case '\b':
11309 case '\f':
11310 case '\n':
11311 case '\r':
11312 case '\t':
11313 case '\v':
11314 *(--ptr) = value - '\a' + 'a';
11315 break;
11316
11317 default:
11318 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11319
11320 case BASE_OCT:
11321 *(--ptr) = (value & 0x7) + '0';
11322 value >>= 3;
11323 *(--ptr) = (value & 0x7) + '0';
11324 value >>= 3;
11325 *(--ptr) = (value & 0x7) + '0';
11326 break;
11327
11328 case BASE_HEX:
11329 *(--ptr) = hex_digits[value & 0x0F];
11330 value >>= 4;
11331 *(--ptr) = hex_digits[value & 0x0F];
11332 *(--ptr) = 'x';
11333 break;
11334
11335 default:
11336 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11337 }
11338 }
11339 *(--ptr) = '\\';
11340 }
11341 *(--ptr) = '\'';
11342 return ptr;
11343}
11344
11345static const char *
11346hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11347{
11348 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11349 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
))
;
11350
11351 *ptr = '\0';
11352 /* Properly format value */
11353 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11354 case BASE_DEC:
11355 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11356
11357 case BASE_DEC_HEX:
11358 *(--ptr) = ')';
11359 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11360 *(--ptr) = '(';
11361 *(--ptr) = ' ';
11362 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11363 return ptr;
11364
11365 case BASE_OCT:
11366 return oct_to_str_back(ptr, value);
11367
11368 case BASE_HEX:
11369 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11370
11371 case BASE_HEX_DEC:
11372 *(--ptr) = ')';
11373 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11374 *(--ptr) = '(';
11375 *(--ptr) = ' ';
11376 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11377 return ptr;
11378
11379 case BASE_PT_UDP:
11380 case BASE_PT_TCP:
11381 case BASE_PT_DCCP:
11382 case BASE_PT_SCTP:
11383 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11384 display_to_port_type((field_display_e)display), value);
11385 return buf;
11386 case BASE_OUI:
11387 {
11388 uint8_t p_oui[3];
11389 const char *manuf_name;
11390
11391 p_oui[0] = value >> 16 & 0xFF;
11392 p_oui[1] = value >> 8 & 0xFF;
11393 p_oui[2] = value & 0xFF;
11394
11395 /* Attempt an OUI lookup. */
11396 manuf_name = uint_get_manuf_name_if_known(value);
11397 if (manuf_name == NULL((void*)0)) {
11398 /* Could not find an OUI. */
11399 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11400 }
11401 else {
11402 /* Found an address string. */
11403 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11404 }
11405 return buf;
11406 }
11407
11408 default:
11409 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11410 }
11411 return ptr;
11412}
11413
11414static const char *
11415hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11416{
11417 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11418 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
))
;
11419
11420 *ptr = '\0';
11421 /* Properly format value */
11422 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11423 case BASE_DEC:
11424 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11425
11426 case BASE_DEC_HEX:
11427 *(--ptr) = ')';
11428 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11429 *(--ptr) = '(';
11430 *(--ptr) = ' ';
11431 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11432 return ptr;
11433
11434 case BASE_OCT:
11435 return oct64_to_str_back(ptr, value);
11436
11437 case BASE_HEX:
11438 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11439
11440 case BASE_HEX_DEC:
11441 *(--ptr) = ')';
11442 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11443 *(--ptr) = '(';
11444 *(--ptr) = ' ';
11445 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11446 return ptr;
11447
11448 default:
11449 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11450 }
11451
11452 return ptr;
11453}
11454
11455static const char *
11456hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11457{
11458 int display = hfinfo->display;
11459
11460 if (hfinfo->type == FT_FRAMENUM) {
11461 /*
11462 * Frame numbers are always displayed in decimal.
11463 */
11464 display = BASE_DEC;
11465 }
11466
11467 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11468}
11469
11470static const char *
11471hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11472{
11473 int display = hfinfo->display;
11474
11475 if (hfinfo->type == FT_FRAMENUM) {
11476 /*
11477 * Frame numbers are always displayed in decimal.
11478 */
11479 display = BASE_DEC;
11480 }
11481
11482 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11483}
11484
11485static const char *
11486hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11487{
11488 /* Get the underlying BASE_ value */
11489 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11490
11491 return hfinfo_char_value_format_display(display, buf, value);
11492}
11493
11494static const char *
11495hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11496{
11497 /* Get the underlying BASE_ value */
11498 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11499
11500 if (hfinfo->type == FT_FRAMENUM) {
11501 /*
11502 * Frame numbers are always displayed in decimal.
11503 */
11504 display = BASE_DEC;
11505 }
11506
11507 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11508 display = BASE_DEC;
11509 } else if (display == BASE_OUI) {
11510 display = BASE_HEX;
11511 }
11512
11513 switch (display) {
11514 case BASE_NONE:
11515 /* case BASE_DEC: */
11516 case BASE_DEC_HEX:
11517 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11518 case BASE_CUSTOM:
11519 display = BASE_DEC;
11520 break;
11521
11522 /* case BASE_HEX: */
11523 case BASE_HEX_DEC:
11524 display = BASE_HEX;
11525 break;
11526 }
11527
11528 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11529}
11530
11531static const char *
11532hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11533{
11534 /* Get the underlying BASE_ value */
11535 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11536
11537 if (hfinfo->type == FT_FRAMENUM) {
11538 /*
11539 * Frame numbers are always displayed in decimal.
11540 */
11541 display = BASE_DEC;
11542 }
11543
11544 switch (display) {
11545 case BASE_NONE:
11546 /* case BASE_DEC: */
11547 case BASE_DEC_HEX:
11548 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11549 case BASE_CUSTOM:
11550 display = BASE_DEC;
11551 break;
11552
11553 /* case BASE_HEX: */
11554 case BASE_HEX_DEC:
11555 display = BASE_HEX;
11556 break;
11557 }
11558
11559 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11560}
11561
11562static const char *
11563hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11564{
11565 /* Get the underlying BASE_ value */
11566 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11567
11568 return hfinfo_char_value_format_display(display, buf, value);
11569}
11570
11571static const char *
11572hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11573{
11574 /* Get the underlying BASE_ value */
11575 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11576
11577 if (display == BASE_NONE)
11578 return NULL((void*)0);
11579
11580 if (display == BASE_DEC_HEX)
11581 display = BASE_DEC;
11582 if (display == BASE_HEX_DEC)
11583 display = BASE_HEX;
11584
11585 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11586}
11587
11588static const char *
11589hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11590{
11591 /* Get the underlying BASE_ value */
11592 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11593
11594 if (display == BASE_NONE)
11595 return NULL((void*)0);
11596
11597 if (display == BASE_DEC_HEX)
11598 display = BASE_DEC;
11599 if (display == BASE_HEX_DEC)
11600 display = BASE_HEX;
11601
11602 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11603}
11604
11605const char *
11606proto_registrar_get_name(const int n)
11607{
11608 header_field_info *hfinfo;
11609
11610 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", 11610
, __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", 11610
, "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", 11610, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11611 return hfinfo->name;
11612}
11613
11614const char *
11615proto_registrar_get_abbrev(const int n)
11616{
11617 header_field_info *hfinfo;
11618
11619 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", 11619
, __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", 11619
, "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", 11619, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11620 return hfinfo->abbrev;
11621}
11622
11623enum ftenum
11624proto_registrar_get_ftype(const int n)
11625{
11626 header_field_info *hfinfo;
11627
11628 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", 11628
, __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", 11628
, "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", 11628, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11629 return hfinfo->type;
11630}
11631
11632int
11633proto_registrar_get_parent(const int n)
11634{
11635 header_field_info *hfinfo;
11636
11637 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", 11637
, __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", 11637
, "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", 11637, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11638 return hfinfo->parent;
11639}
11640
11641bool_Bool
11642proto_registrar_is_protocol(const int n)
11643{
11644 header_field_info *hfinfo;
11645
11646 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", 11646
, __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", 11646
, "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", 11646, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11647 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11648}
11649
11650/* Returns length of field in packet (not necessarily the length
11651 * in our internal representation, as in the case of IPv4).
11652 * 0 means undeterminable at time of registration
11653 * -1 means the field is not registered. */
11654int
11655proto_registrar_get_length(const int n)
11656{
11657 header_field_info *hfinfo;
11658
11659 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", 11659
, __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", 11659
, "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", 11659, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11660 return ftype_wire_size(hfinfo->type);
11661}
11662
11663size_t
11664proto_registrar_get_count(struct proto_registrar_stats *stats)
11665{
11666 header_field_info *hfinfo;
11667
11668 // Index zero is not used. We have to skip it.
11669 size_t total_count = gpa_hfinfo.len - 1;
11670 if (stats == NULL((void*)0)) {
11671 return total_count;
11672 }
11673 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11674 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11675 stats->deregistered_count++;
11676 continue; /* This is a deregistered protocol or header field */
11677 }
11678
11679 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", 11679
, __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", 11679, "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", 11679, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11680
11681 if (proto_registrar_is_protocol(id))
11682 stats->protocol_count++;
11683
11684 if (hfinfo->same_name_prev_id != -1)
11685 stats->same_name_count++;
11686 }
11687
11688 return total_count;
11689}
11690
11691/* Looks for a protocol or a field in a proto_tree. Returns true if
11692 * it exists anywhere, or false if it exists nowhere. */
11693bool_Bool
11694proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11695{
11696 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11697
11698 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11699 return true1;
11700 }
11701 else {
11702 return false0;
11703 }
11704}
11705
11706/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11707 * This only works if the hfindex was "primed" before the dissection
11708 * took place, as we just pass back the already-created GPtrArray*.
11709 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11710 * handles that. */
11711GPtrArray *
11712proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11713{
11714 if (!tree)
11715 return NULL((void*)0);
11716
11717 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11718 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11719 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11720 else
11721 return NULL((void*)0);
11722}
11723
11724bool_Bool
11725proto_tracking_interesting_fields(const proto_tree *tree)
11726{
11727 GHashTable *interesting_hfids;
11728
11729 if (!tree)
11730 return false0;
11731
11732 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11733
11734 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11735}
11736
11737/* Helper struct for proto_find_info() and proto_all_finfos() */
11738typedef struct {
11739 GPtrArray *array;
11740 int id;
11741} ffdata_t;
11742
11743/* Helper function for proto_find_info() */
11744static bool_Bool
11745find_finfo(proto_node *node, void * data)
11746{
11747 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11748 if (fi && fi->hfinfo) {
11749 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11750 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11751 }
11752 }
11753
11754 /* Don't stop traversing. */
11755 return false0;
11756}
11757
11758/* Helper function for proto_find_first_info() */
11759static bool_Bool
11760find_first_finfo(proto_node *node, void *data)
11761{
11762 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11763 if (fi && fi->hfinfo) {
11764 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11765 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11766
11767 /* Stop traversing. */
11768 return true1;
11769 }
11770 }
11771
11772 /* Continue traversing. */
11773 return false0;
11774}
11775
11776/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11777* This works on any proto_tree, primed or unprimed, but actually searches
11778* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11779* The caller does need to free the returned GPtrArray with
11780* g_ptr_array_free(<array>, true).
11781*/
11782GPtrArray *
11783proto_find_finfo(proto_tree *tree, const int id)
11784{
11785 ffdata_t ffdata;
11786
11787 ffdata.array = g_ptr_array_new();
11788 ffdata.id = id;
11789
11790 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11791
11792 return ffdata.array;
11793}
11794
11795/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11796* This works on any proto_tree, primed or unprimed, but actually searches
11797* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11798* The caller does need to free the returned GPtrArray with
11799* g_ptr_array_free(<array>, true).
11800*/
11801GPtrArray *
11802proto_find_first_finfo(proto_tree *tree, const int id)
11803{
11804 ffdata_t ffdata;
11805
11806 ffdata.array = g_ptr_array_new();
11807 ffdata.id = id;
11808
11809 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11810
11811 return ffdata.array;
11812}
11813
11814/* Helper function for proto_all_finfos() */
11815static bool_Bool
11816every_finfo(proto_node *node, void * data)
11817{
11818 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11819 if (fi && fi->hfinfo) {
11820 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11821 }
11822
11823 /* Don't stop traversing. */
11824 return false0;
11825}
11826
11827/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11828 * The caller does need to free the returned GPtrArray with
11829 * g_ptr_array_free(<array>, true).
11830 */
11831GPtrArray *
11832proto_all_finfos(proto_tree *tree)
11833{
11834 ffdata_t ffdata;
11835
11836 /* Pre allocate enough space to hold all fields in most cases */
11837 ffdata.array = g_ptr_array_sized_new(512);
11838 ffdata.id = 0;
11839
11840 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11841
11842 return ffdata.array;
11843}
11844
11845
11846typedef struct {
11847 unsigned offset;
11848 field_info *finfo;
11849 tvbuff_t *tvb;
11850} offset_search_t;
11851
11852static bool_Bool
11853check_for_offset(proto_node *node, void * data)
11854{
11855 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11856 offset_search_t *offsearch = (offset_search_t *)data;
11857
11858 /* !fi == the top most container node which holds nothing */
11859 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11860 if (offsearch->offset >= (unsigned) fi->start &&
11861 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11862
11863 offsearch->finfo = fi;
11864 return false0; /* keep traversing */
11865 }
11866 }
11867 return false0; /* keep traversing */
11868}
11869
11870/* Search a proto_tree backwards (from leaves to root) looking for the field
11871 * whose start/length occupies 'offset' */
11872/* XXX - I couldn't find an easy way to search backwards, so I search
11873 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11874 * the one I want to return to the user. This algorithm is inefficient
11875 * and could be re-done, but I'd have to handle all the children and
11876 * siblings of each node myself. When I have more time I'll do that.
11877 * (yeah right) */
11878field_info *
11879proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11880{
11881 offset_search_t offsearch;
11882
11883 offsearch.offset = offset;
11884 offsearch.finfo = NULL((void*)0);
11885 offsearch.tvb = tvb;
11886
11887 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11888
11889 return offsearch.finfo;
11890}
11891
11892typedef struct {
11893 unsigned length;
11894 char *buf;
11895} decoded_data_t;
11896
11897static bool_Bool
11898check_for_undecoded(proto_node *node, void * data)
11899{
11900 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11901 decoded_data_t* decoded = (decoded_data_t*)data;
11902 unsigned i;
11903 unsigned byte;
11904 unsigned bit;
11905
11906 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11907 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11908 byte = i / 8;
11909 bit = i % 8;
11910 decoded->buf[byte] |= (1 << bit);
11911 }
11912 }
11913
11914 return false0;
11915}
11916
11917char*
11918proto_find_undecoded_data(proto_tree *tree, unsigned length)
11919{
11920 decoded_data_t decoded;
11921 decoded.length = length;
11922 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11923
11924 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11925 return decoded.buf;
11926}
11927
11928/* Dumps the protocols in the registration database to stdout. An independent
11929 * program can take this output and format it into nice tables or HTML or
11930 * whatever.
11931 *
11932 * There is one record per line. The fields are tab-delimited.
11933 *
11934 * Field 1 = protocol name
11935 * Field 2 = protocol short name
11936 * Field 3 = protocol filter name
11937 * Field 4 = protocol enabled
11938 * Field 5 = protocol enabled by default
11939 * Field 6 = protocol can toggle
11940 */
11941void
11942proto_registrar_dump_protocols(void)
11943{
11944 protocol_t *protocol;
11945 int i;
11946 void *cookie = NULL((void*)0);
11947
11948
11949 i = proto_get_first_protocol(&cookie);
11950 while (i != -1) {
11951 protocol = find_protocol_by_id(i);
11952 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11953 protocol->name,
11954 protocol->short_name,
11955 protocol->filter_name,
11956 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11957 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11958 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11959 i = proto_get_next_protocol(&cookie);
11960 }
11961}
11962
11963/* Dumps the value_strings, extended value string headers, range_strings
11964 * or true/false strings for fields that have them.
11965 * There is one record per line. Fields are tab-delimited.
11966 * There are four types of records: Value String, Extended Value String Header,
11967 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11968 * the type of record.
11969 *
11970 * Note that a record will be generated only if the value_string,... is referenced
11971 * in a registered hfinfo entry.
11972 *
11973 *
11974 * Value Strings
11975 * -------------
11976 * Field 1 = 'V'
11977 * Field 2 = Field abbreviation to which this value string corresponds
11978 * Field 3 = Integer value
11979 * Field 4 = String
11980 *
11981 * Extended Value String Headers
11982 * -----------------------------
11983 * Field 1 = 'E'
11984 * Field 2 = Field abbreviation to which this extended value string header corresponds
11985 * Field 3 = Extended Value String "Name"
11986 * Field 4 = Number of entries in the associated value_string array
11987 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11988 *
11989 * Range Strings
11990 * -------------
11991 * Field 1 = 'R'
11992 * Field 2 = Field abbreviation to which this range string corresponds
11993 * Field 3 = Integer value: lower bound
11994 * Field 4 = Integer value: upper bound
11995 * Field 5 = String
11996 *
11997 * True/False Strings
11998 * ------------------
11999 * Field 1 = 'T'
12000 * Field 2 = Field abbreviation to which this true/false string corresponds
12001 * Field 3 = True String
12002 * Field 4 = False String
12003 */
12004void
12005proto_registrar_dump_values(void)
12006{
12007 header_field_info *hfinfo;
12008 int i, len, vi;
12009 const value_string *vals;
12010 const val64_string *vals64;
12011 const range_string *range;
12012 const true_false_string *tfs;
12013 const unit_name_string *units;
12014
12015 len = gpa_hfinfo.len;
12016 for (i = 1; i < len ; i++) {
12017 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12018 continue; /* This is a deregistered protocol or field */
12019
12020 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", 12020
, __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", 12020
, "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", 12020, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12021
12022 if (hfinfo->id == hf_text_only) {
12023 continue;
12024 }
12025
12026 /* ignore protocols */
12027 if (proto_registrar_is_protocol(i)) {
12028 continue;
12029 }
12030 /* process header fields */
12031#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12032 /*
12033 * If this field isn't at the head of the list of
12034 * fields with this name, skip this field - all
12035 * fields with the same name are really just versions
12036 * of the same field stored in different bits, and
12037 * should have the same type/radix/value list, and
12038 * just differ in their bit masks. (If a field isn't
12039 * a bitfield, but can be, say, 1 or 2 bytes long,
12040 * it can just be made FT_UINT16, meaning the
12041 * *maximum* length is 2 bytes, and be used
12042 * for all lengths.)
12043 */
12044 if (hfinfo->same_name_prev_id != -1)
12045 continue;
12046#endif
12047 vals = NULL((void*)0);
12048 vals64 = NULL((void*)0);
12049 range = NULL((void*)0);
12050 tfs = NULL((void*)0);
12051 units = NULL((void*)0);
12052
12053 if (hfinfo->strings != NULL((void*)0)) {
12054 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12055 (hfinfo->type == FT_CHAR ||
12056 hfinfo->type == FT_UINT8 ||
12057 hfinfo->type == FT_UINT16 ||
12058 hfinfo->type == FT_UINT24 ||
12059 hfinfo->type == FT_UINT32 ||
12060 hfinfo->type == FT_UINT40 ||
12061 hfinfo->type == FT_UINT48 ||
12062 hfinfo->type == FT_UINT56 ||
12063 hfinfo->type == FT_UINT64 ||
12064 hfinfo->type == FT_INT8 ||
12065 hfinfo->type == FT_INT16 ||
12066 hfinfo->type == FT_INT24 ||
12067 hfinfo->type == FT_INT32 ||
12068 hfinfo->type == FT_INT40 ||
12069 hfinfo->type == FT_INT48 ||
12070 hfinfo->type == FT_INT56 ||
12071 hfinfo->type == FT_INT64 ||
12072 hfinfo->type == FT_FLOAT ||
12073 hfinfo->type == FT_DOUBLE)) {
12074
12075 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12076 range = (const range_string *)hfinfo->strings;
12077 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12078 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12079 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12080 } else {
12081 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12082 }
12083 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12084 vals64 = (const val64_string *)hfinfo->strings;
12085 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12086 units = (const unit_name_string *)hfinfo->strings;
12087 } else {
12088 vals = (const value_string *)hfinfo->strings;
12089 }
12090 }
12091 else if (hfinfo->type == FT_BOOLEAN) {
12092 tfs = (const struct true_false_string *)hfinfo->strings;
12093 }
12094 }
12095
12096 /* Print value strings? */
12097 if (vals) {
12098 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12099 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12100 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12101 if (!val64_string_ext_validate(vse_p)) {
12102 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12102, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12103 continue;
12104 }
12105 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12106 printf("E\t%s\t%u\t%s\t%s\n",
12107 hfinfo->abbrev,
12108 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12109 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12110 val64_string_ext_match_type_str(vse_p));
12111 } else {
12112 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12113 if (!value_string_ext_validate(vse_p)) {
12114 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12114, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12115 continue;
12116 }
12117 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12118 printf("E\t%s\t%u\t%s\t%s\n",
12119 hfinfo->abbrev,
12120 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12121 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12122 value_string_ext_match_type_str(vse_p));
12123 }
12124 }
12125 vi = 0;
12126 while (vals[vi].strptr) {
12127 /* Print in the proper base */
12128 if (hfinfo->type == FT_CHAR) {
12129 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12130 printf("V\t%s\t'%c'\t%s\n",
12131 hfinfo->abbrev,
12132 vals[vi].value,
12133 vals[vi].strptr);
12134 } else {
12135 if (hfinfo->display == BASE_HEX) {
12136 printf("V\t%s\t'\\x%02x'\t%s\n",
12137 hfinfo->abbrev,
12138 vals[vi].value,
12139 vals[vi].strptr);
12140 }
12141 else {
12142 printf("V\t%s\t'\\%03o'\t%s\n",
12143 hfinfo->abbrev,
12144 vals[vi].value,
12145 vals[vi].strptr);
12146 }
12147 }
12148 } else {
12149 if (hfinfo->display == BASE_HEX) {
12150 printf("V\t%s\t0x%x\t%s\n",
12151 hfinfo->abbrev,
12152 vals[vi].value,
12153 vals[vi].strptr);
12154 }
12155 else {
12156 printf("V\t%s\t%u\t%s\n",
12157 hfinfo->abbrev,
12158 vals[vi].value,
12159 vals[vi].strptr);
12160 }
12161 }
12162 vi++;
12163 }
12164 }
12165 else if (vals64) {
12166 vi = 0;
12167 while (vals64[vi].strptr) {
12168 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12169 hfinfo->abbrev,
12170 vals64[vi].value,
12171 vals64[vi].strptr);
12172 vi++;
12173 }
12174 }
12175
12176 /* print range strings? */
12177 else if (range) {
12178 vi = 0;
12179 while (range[vi].strptr) {
12180 /* Print in the proper base */
12181 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12182 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12183 hfinfo->abbrev,
12184 range[vi].value_min,
12185 range[vi].value_max,
12186 range[vi].strptr);
12187 }
12188 else {
12189 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12190 hfinfo->abbrev,
12191 range[vi].value_min,
12192 range[vi].value_max,
12193 range[vi].strptr);
12194 }
12195 vi++;
12196 }
12197 }
12198
12199 /* Print true/false strings? */
12200 else if (tfs) {
12201 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12202 tfs->true_string, tfs->false_string);
12203 }
12204 /* Print unit strings? */
12205 else if (units) {
12206 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12207 units->singular, units->plural ? units->plural : "(no plural)");
12208 }
12209 }
12210}
12211
12212/* Prints the number of registered fields.
12213 * Useful for determining an appropriate value for
12214 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12215 *
12216 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12217 * the number of fields, true otherwise.
12218 */
12219bool_Bool
12220proto_registrar_dump_fieldcount(void)
12221{
12222 struct proto_registrar_stats stats = {0, 0, 0};
12223 size_t total_count = proto_registrar_get_count(&stats);
12224
12225 printf("There are %zu header fields registered, of which:\n"
12226 "\t%zu are deregistered\n"
12227 "\t%zu are protocols\n"
12228 "\t%zu have the same name as another field\n\n",
12229 total_count, stats.deregistered_count, stats.protocol_count,
12230 stats.same_name_count);
12231
12232 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12233 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12234 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12235 "\n");
12236
12237 printf("The header field table consumes %u KiB of memory.\n",
12238 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12239 printf("The fields themselves consume %u KiB of memory.\n",
12240 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12241
12242 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12243}
12244
12245static void
12246elastic_add_base_mapping(json_dumper *dumper)
12247{
12248 json_dumper_set_member_name(dumper, "index_patterns");
12249 json_dumper_begin_array(dumper);
12250 // The index names from write_json_index() in print.c
12251 json_dumper_value_string(dumper, "packets-*");
12252 json_dumper_end_array(dumper);
12253
12254 json_dumper_set_member_name(dumper, "settings");
12255 json_dumper_begin_object(dumper);
12256 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12257 json_dumper_value_anyf(dumper, "%d", 1000000);
12258 json_dumper_end_object(dumper);
12259}
12260
12261static char*
12262ws_type_to_elastic(unsigned type)
12263{
12264 switch(type) {
12265 case FT_INT8:
12266 return "byte";
12267 case FT_UINT8:
12268 case FT_INT16:
12269 return "short";
12270 case FT_UINT16:
12271 case FT_INT32:
12272 case FT_UINT24:
12273 case FT_INT24:
12274 return "integer";
12275 case FT_FRAMENUM:
12276 case FT_UINT32:
12277 case FT_UINT40:
12278 case FT_UINT48:
12279 case FT_UINT56:
12280 case FT_INT40:
12281 case FT_INT48:
12282 case FT_INT56:
12283 case FT_INT64:
12284 return "long";
12285 case FT_UINT64:
12286 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12287 case FT_FLOAT:
12288 return "float";
12289 case FT_DOUBLE:
12290 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12291 return "double";
12292 case FT_IPv6:
12293 case FT_IPv4:
12294 return "ip";
12295 case FT_ABSOLUTE_TIME:
12296 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12297 case FT_BOOLEAN:
12298 return "boolean";
12299 default:
12300 return NULL((void*)0);
12301 }
12302}
12303
12304static char*
12305dot_to_underscore(char* str)
12306{
12307 unsigned i;
12308 for (i = 0; i < strlen(str); i++) {
12309 if (str[i] == '.')
12310 str[i] = '_';
12311 }
12312 return str;
12313}
12314
12315/* Dumps a mapping file for ElasticSearch
12316 * This is the v1 (legacy) _template API.
12317 * At some point it may need to be updated with the composable templates
12318 * introduced in Elasticsearch 7.8 (_index_template)
12319 */
12320void
12321proto_registrar_dump_elastic(const char* filter)
12322{
12323 header_field_info *hfinfo;
12324 header_field_info *parent_hfinfo;
12325 unsigned i;
12326 bool_Bool open_object = true1;
12327 const char* prev_proto = NULL((void*)0);
12328 char* str;
12329 char** protos = NULL((void*)0);
12330 char* proto;
12331 bool_Bool found;
12332 unsigned j;
12333 char* type;
12334 char* prev_item = NULL((void*)0);
12335
12336 /* We have filtering protocols. Extract them. */
12337 if (filter) {
12338 protos = g_strsplit(filter, ",", -1);
12339 }
12340
12341 /*
12342 * To help tracking down the json tree, objects have been appended with a comment:
12343 * n.label -> where n is the indentation level and label the name of the object
12344 */
12345
12346 json_dumper dumper = {
12347 .output_file = stdoutstdout,
12348 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12349 };
12350 json_dumper_begin_object(&dumper); // 1.root
12351 elastic_add_base_mapping(&dumper);
12352
12353 json_dumper_set_member_name(&dumper, "mappings");
12354 json_dumper_begin_object(&dumper); // 2.mappings
12355
12356 json_dumper_set_member_name(&dumper, "properties");
12357 json_dumper_begin_object(&dumper); // 3.properties
12358 json_dumper_set_member_name(&dumper, "timestamp");
12359 json_dumper_begin_object(&dumper); // 4.timestamp
12360 json_dumper_set_member_name(&dumper, "type");
12361 json_dumper_value_string(&dumper, "date");
12362 json_dumper_end_object(&dumper); // 4.timestamp
12363
12364 json_dumper_set_member_name(&dumper, "layers");
12365 json_dumper_begin_object(&dumper); // 4.layers
12366 json_dumper_set_member_name(&dumper, "properties");
12367 json_dumper_begin_object(&dumper); // 5.properties
12368
12369 for (i = 1; i < gpa_hfinfo.len; i++) {
12370 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12371 continue; /* This is a deregistered protocol or header field */
12372
12373 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", 12373
, __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", 12373
, "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", 12373, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12374
12375 /*
12376 * Skip the pseudo-field for "proto_tree_add_text()" since
12377 * we don't want it in the list of filterable protocols.
12378 */
12379 if (hfinfo->id == hf_text_only)
12380 continue;
12381
12382 if (!proto_registrar_is_protocol(i)) {
12383 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", 12383
, __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", 12383
, "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", 12383
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12384
12385 /*
12386 * Skip the field if filter protocols have been set and this one's
12387 * parent is not listed.
12388 */
12389 if (protos) {
12390 found = false0;
12391 j = 0;
12392 proto = protos[0];
12393 while(proto) {
12394 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12395 found = true1;
12396 break;
12397 }
12398 j++;
12399 proto = protos[j];
12400 }
12401 if (!found)
12402 continue;
12403 }
12404
12405 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12406 json_dumper_end_object(&dumper); // 7.properties
12407 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12408 open_object = true1;
12409 }
12410
12411 prev_proto = parent_hfinfo->abbrev;
12412
12413 if (open_object) {
12414 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12415 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12416 json_dumper_set_member_name(&dumper, "properties");
12417 json_dumper_begin_object(&dumper); // 7.properties
12418 open_object = false0;
12419 }
12420 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12421 type = ws_type_to_elastic(hfinfo->type);
12422 /* when type is NULL, we have the default mapping: string */
12423 if (type) {
12424 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12425 dot_to_underscore(str);
12426 if (g_strcmp0(prev_item, str)) {
12427 json_dumper_set_member_name(&dumper, str);
12428 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12429 json_dumper_set_member_name(&dumper, "type");
12430 json_dumper_value_string(&dumper, type);
12431 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12432 }
12433 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)
;
12434 prev_item = str;
12435 }
12436 }
12437 }
12438 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)
;
12439
12440 if (prev_proto) {
12441 json_dumper_end_object(&dumper); // 7.properties
12442 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12443 }
12444
12445 json_dumper_end_object(&dumper); // 5.properties
12446 json_dumper_end_object(&dumper); // 4.layers
12447 json_dumper_end_object(&dumper); // 3.properties
12448 json_dumper_end_object(&dumper); // 2.mappings
12449 json_dumper_end_object(&dumper); // 1.root
12450 bool_Bool ret = json_dumper_finish(&dumper);
12451 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12451, "ret"))))
;
12452
12453 g_strfreev(protos);
12454}
12455
12456/* Dumps the contents of the registration database to stdout. An independent
12457 * program can take this output and format it into nice tables or HTML or
12458 * whatever.
12459 *
12460 * There is one record per line. Each record is either a protocol or a header
12461 * field, differentiated by the first field. The fields are tab-delimited.
12462 *
12463 * Protocols
12464 * ---------
12465 * Field 1 = 'P'
12466 * Field 2 = descriptive protocol name
12467 * Field 3 = protocol abbreviation
12468 *
12469 * Header Fields
12470 * -------------
12471 * Field 1 = 'F'
12472 * Field 2 = descriptive field name
12473 * Field 3 = field abbreviation
12474 * Field 4 = type ( textual representation of the ftenum type )
12475 * Field 5 = parent protocol abbreviation
12476 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12477 * Field 7 = bitmask: format: hex: 0x....
12478 * Field 8 = blurb describing field
12479 */
12480void
12481proto_registrar_dump_fields(void)
12482{
12483 header_field_info *hfinfo, *parent_hfinfo;
12484 int i, len;
12485 const char *enum_name;
12486 const char *base_name;
12487 const char *blurb;
12488 char width[5];
12489
12490 len = gpa_hfinfo.len;
12491 for (i = 1; i < len ; i++) {
12492 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12493 continue; /* This is a deregistered protocol or header field */
12494
12495 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", 12495
, __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", 12495
, "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", 12495, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12496
12497 /*
12498 * Skip the pseudo-field for "proto_tree_add_text()" since
12499 * we don't want it in the list of filterable fields.
12500 */
12501 if (hfinfo->id == hf_text_only)
12502 continue;
12503
12504 /* format for protocols */
12505 if (proto_registrar_is_protocol(i)) {
12506 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12507 }
12508 /* format for header fields */
12509 else {
12510 /*
12511 * If this field isn't at the head of the list of
12512 * fields with this name, skip this field - all
12513 * fields with the same name are really just versions
12514 * of the same field stored in different bits, and
12515 * should have the same type/radix/value list, and
12516 * just differ in their bit masks. (If a field isn't
12517 * a bitfield, but can be, say, 1 or 2 bytes long,
12518 * it can just be made FT_UINT16, meaning the
12519 * *maximum* length is 2 bytes, and be used
12520 * for all lengths.)
12521 */
12522 if (hfinfo->same_name_prev_id != -1)
12523 continue;
12524
12525 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", 12525
, __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", 12525
, "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", 12525
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12526
12527 enum_name = ftype_name(hfinfo->type);
12528 base_name = "";
12529
12530 if (hfinfo->type == FT_CHAR ||
12531 hfinfo->type == FT_UINT8 ||
12532 hfinfo->type == FT_UINT16 ||
12533 hfinfo->type == FT_UINT24 ||
12534 hfinfo->type == FT_UINT32 ||
12535 hfinfo->type == FT_UINT40 ||
12536 hfinfo->type == FT_UINT48 ||
12537 hfinfo->type == FT_UINT56 ||
12538 hfinfo->type == FT_UINT64 ||
12539 hfinfo->type == FT_INT8 ||
12540 hfinfo->type == FT_INT16 ||
12541 hfinfo->type == FT_INT24 ||
12542 hfinfo->type == FT_INT32 ||
12543 hfinfo->type == FT_INT40 ||
12544 hfinfo->type == FT_INT48 ||
12545 hfinfo->type == FT_INT56 ||
12546 hfinfo->type == FT_INT64) {
12547
12548 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12549 case BASE_NONE:
12550 case BASE_DEC:
12551 case BASE_HEX:
12552 case BASE_OCT:
12553 case BASE_DEC_HEX:
12554 case BASE_HEX_DEC:
12555 case BASE_CUSTOM:
12556 case BASE_PT_UDP:
12557 case BASE_PT_TCP:
12558 case BASE_PT_DCCP:
12559 case BASE_PT_SCTP:
12560 case BASE_OUI:
12561 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12562 break;
12563 default:
12564 base_name = "????";
12565 break;
12566 }
12567 } else if (hfinfo->type == FT_BOOLEAN) {
12568 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12569 snprintf(width, sizeof(width), "%d", hfinfo->display);
12570 base_name = width;
12571 }
12572
12573 blurb = hfinfo->blurb;
12574 if (blurb == NULL((void*)0))
12575 blurb = "";
12576 else if (strlen(blurb) == 0)
12577 blurb = "\"\"";
12578
12579 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12580 hfinfo->name, hfinfo->abbrev, enum_name,
12581 parent_hfinfo->abbrev, base_name,
12582 hfinfo->bitmask, blurb);
12583 }
12584 }
12585}
12586
12587/* Dumps all abbreviated field and protocol completions of the given string to
12588 * stdout. An independent program may use this for command-line tab completion
12589 * of fields.
12590 */
12591bool_Bool
12592proto_registrar_dump_field_completions(const char *prefix)
12593{
12594 header_field_info *hfinfo;
12595 int i, len;
12596 size_t prefix_len;
12597 bool_Bool matched = false0;
12598
12599 prefix_len = strlen(prefix);
12600 len = gpa_hfinfo.len;
12601 for (i = 1; i < len ; i++) {
12602 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12603 continue; /* This is a deregistered protocol or header field */
12604
12605 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", 12605
, __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", 12605
, "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", 12605, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12606
12607 /*
12608 * Skip the pseudo-field for "proto_tree_add_text()" since
12609 * we don't want it in the list of filterable fields.
12610 */
12611 if (hfinfo->id == hf_text_only)
12612 continue;
12613
12614 /* format for protocols */
12615 if (proto_registrar_is_protocol(i)) {
12616 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12617 matched = true1;
12618 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12619 }
12620 }
12621 /* format for header fields */
12622 else {
12623 /*
12624 * If this field isn't at the head of the list of
12625 * fields with this name, skip this field - all
12626 * fields with the same name are really just versions
12627 * of the same field stored in different bits, and
12628 * should have the same type/radix/value list, and
12629 * just differ in their bit masks. (If a field isn't
12630 * a bitfield, but can be, say, 1 or 2 bytes long,
12631 * it can just be made FT_UINT16, meaning the
12632 * *maximum* length is 2 bytes, and be used
12633 * for all lengths.)
12634 */
12635 if (hfinfo->same_name_prev_id != -1)
12636 continue;
12637
12638 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12639 matched = true1;
12640 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12641 }
12642 }
12643 }
12644 return matched;
12645}
12646
12647/* Dumps field types and descriptive names to stdout. An independent
12648 * program can take this output and format it into nice tables or HTML or
12649 * whatever.
12650 *
12651 * There is one record per line. The fields are tab-delimited.
12652 *
12653 * Field 1 = field type name, e.g. FT_UINT8
12654 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12655 */
12656void
12657proto_registrar_dump_ftypes(void)
12658{
12659 int fte;
12660
12661 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12662 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12663 }
12664}
12665
12666/* This function indicates whether it's possible to construct a
12667 * "match selected" display filter string for the specified field,
12668 * returns an indication of whether it's possible, and, if it's
12669 * possible and "filter" is non-null, constructs the filter and
12670 * sets "*filter" to point to it.
12671 * You do not need to [g_]free() this string since it will be automatically
12672 * freed once the next packet is dissected.
12673 */
12674static bool_Bool
12675construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12676 char **filter)
12677{
12678 const header_field_info *hfinfo;
12679 int start, length, length_remaining;
12680
12681 if (!finfo)
12682 return false0;
12683
12684 hfinfo = finfo->hfinfo;
12685 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12685, "hfinfo"))))
;
12686
12687 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12688 * then "the numeric value ... is not used when preparing
12689 * filters for the field in question." If it's any other
12690 * base, we'll generate the filter normally (which will
12691 * be numeric, even though the human-readable string does
12692 * work for filtering.)
12693 *
12694 * XXX - It might be nice to use fvalue_to_string_repr() in
12695 * "proto_item_fill_label()" as well, although, there, you'd
12696 * have to deal with the base *and* with resolved values for
12697 * addresses.
12698 *
12699 * Perhaps in addition to taking the repr type (DISPLAY
12700 * or DFILTER) and the display (base), fvalue_to_string_repr()
12701 * should have the the "strings" values in the header_field_info
12702 * structure for the field as a parameter, so it can have
12703 * if the field is Boolean or an enumerated integer type,
12704 * the tables used to generate human-readable values.
12705 */
12706 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12707 const char *str = NULL((void*)0);
12708
12709 switch (hfinfo->type) {
12710
12711 case FT_INT8:
12712 case FT_INT16:
12713 case FT_INT24:
12714 case FT_INT32:
12715 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12716 break;
12717
12718 case FT_CHAR:
12719 case FT_UINT8:
12720 case FT_UINT16:
12721 case FT_UINT24:
12722 case FT_UINT32:
12723 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12724 break;
12725
12726 default:
12727 break;
12728 }
12729
12730 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12731 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12732 return true1;
12733 }
12734 }
12735
12736 switch (hfinfo->type) {
12737
12738 case FT_PROTOCOL:
12739 if (filter != NULL((void*)0))
12740 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12741 break;
12742
12743 case FT_NONE:
12744 /*
12745 * If the length is 0, just match the name of the
12746 * field.
12747 *
12748 * (Also check for negative values, just in case,
12749 * as we'll cast it to an unsigned value later.)
12750 */
12751 length = finfo->length;
12752 if (length == 0) {
12753 if (filter != NULL((void*)0))
12754 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12755 break;
12756 }
12757 if (length < 0)
12758 return false0;
12759
12760 /*
12761 * This doesn't have a value, so we'd match
12762 * on the raw bytes at this address.
12763 *
12764 * Should we be allowed to access to the raw bytes?
12765 * If "edt" is NULL, the answer is "no".
12766 */
12767 if (edt == NULL((void*)0))
12768 return false0;
12769
12770 /*
12771 * Is this field part of the raw frame tvbuff?
12772 * If not, we can't use "frame[N:M]" to match
12773 * it.
12774 *
12775 * XXX - should this be frame-relative, or
12776 * protocol-relative?
12777 *
12778 * XXX - does this fallback for non-registered
12779 * fields even make sense?
12780 */
12781 if (finfo->ds_tvb != edt->tvb)
12782 return false0; /* you lose */
12783
12784 /*
12785 * Don't go past the end of that tvbuff.
12786 */
12787 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12788 if (length > length_remaining)
12789 length = length_remaining;
12790 if (length <= 0)
12791 return false0;
12792
12793 if (filter != NULL((void*)0)) {
12794 start = finfo->start;
12795 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12796 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12797 wmem_free(NULL((void*)0), str);
12798 }
12799 break;
12800
12801 /* By default, use the fvalue's "to_string_repr" method. */
12802 default:
12803 if (filter != NULL((void*)0)) {
12804 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12805 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12806 wmem_free(NULL((void*)0), str);
12807 }
12808 break;
12809 }
12810
12811 return true1;
12812}
12813
12814/*
12815 * Returns true if we can do a "match selected" on the field, false
12816 * otherwise.
12817 */
12818bool_Bool
12819proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12820{
12821 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12822}
12823
12824/* This function attempts to construct a "match selected" display filter
12825 * string for the specified field; if it can do so, it returns a pointer
12826 * to the string, otherwise it returns NULL.
12827 *
12828 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12829 */
12830char *
12831proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12832{
12833 char *filter = NULL((void*)0);
12834
12835 if (!construct_match_selected_string(finfo, edt, &filter))
12836 {
12837 wmem_free(NULL((void*)0), filter);
12838 return NULL((void*)0);
12839 }
12840 return filter;
12841}
12842
12843/* This function is common code for all proto_tree_add_bitmask... functions.
12844 */
12845
12846static bool_Bool
12847proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12848 const int len, const int ett, int * const *fields,
12849 const int flags, bool_Bool first,
12850 bool_Bool use_parent_tree,
12851 proto_tree* tree, uint64_t value)
12852{
12853 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12854 uint64_t bitmask = 0;
12855 uint64_t tmpval;
12856 header_field_info *hf;
12857 uint32_t integer32;
12858 int bit_offset;
12859 int no_of_bits;
12860
12861 if (!*fields)
12862 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"
)
;
12863
12864 if (len < 0 || len > 8)
12865 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12866 /**
12867 * packet-frame.c uses len=0 since the value is taken from the packet
12868 * metadata, not the packet bytes. In that case, assume that all bits
12869 * in the provided value are valid.
12870 */
12871 if (len > 0) {
12872 available_bits >>= (8 - (unsigned)len)*8;
12873 }
12874
12875 if (use_parent_tree == false0)
12876 tree = proto_item_add_subtree(item, ett);
12877
12878 while (*fields) {
12879 uint64_t present_bits;
12880 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", 12880, __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", 12880
, "**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", 12880, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12881 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", 12881
, "hf->bitmask != 0", hf->abbrev))))
;
12882
12883 bitmask |= hf->bitmask;
12884
12885 /* Skip fields that aren't fully present */
12886 present_bits = available_bits & hf->bitmask;
12887 if (present_bits != hf->bitmask) {
12888 fields++;
12889 continue;
12890 }
12891
12892 switch (hf->type) {
12893 case FT_CHAR:
12894 case FT_UINT8:
12895 case FT_UINT16:
12896 case FT_UINT24:
12897 case FT_UINT32:
12898 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12899 break;
12900
12901 case FT_INT8:
12902 case FT_INT16:
12903 case FT_INT24:
12904 case FT_INT32:
12905 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12906 break;
12907
12908 case FT_UINT40:
12909 case FT_UINT48:
12910 case FT_UINT56:
12911 case FT_UINT64:
12912 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12913 break;
12914
12915 case FT_INT40:
12916 case FT_INT48:
12917 case FT_INT56:
12918 case FT_INT64:
12919 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12920 break;
12921
12922 case FT_BOOLEAN:
12923 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12924 break;
12925
12926 default:
12927 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))
12928 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))
12929 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))
12930 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))
;
12931 break;
12932 }
12933 if (flags & BMT_NO_APPEND0x01) {
12934 fields++;
12935 continue;
12936 }
12937 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12938
12939 /* XXX: README.developer and the comments have always defined
12940 * BMT_NO_INT as "only boolean flags are added to the title /
12941 * don't add non-boolean (integral) fields", but the
12942 * implementation has always added BASE_CUSTOM and fields with
12943 * value_strings, though not fields with unit_strings.
12944 * Possibly this is because some dissectors use a FT_UINT8
12945 * with a value_string for fields that should be a FT_BOOLEAN.
12946 */
12947 switch (hf->type) {
12948 case FT_CHAR:
12949 if (hf->display == BASE_CUSTOM) {
12950 char lbl[ITEM_LABEL_LENGTH240];
12951 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12952
12953 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12953, "fmtfunc"))))
;
12954 fmtfunc(lbl, (uint32_t) tmpval);
12955 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12956 hf->name, lbl);
12957 first = false0;
12958 }
12959 else if (hf->strings) {
12960 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12961 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12962 first = false0;
12963 }
12964 else if (!(flags & BMT_NO_INT0x02)) {
12965 char buf[32];
12966 const char *out;
12967
12968 if (!first) {
12969 proto_item_append_text(item, ", ");
12970 }
12971
12972 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12973 proto_item_append_text(item, "%s: %s", hf->name, out);
12974 first = false0;
12975 }
12976
12977 break;
12978
12979 case FT_UINT8:
12980 case FT_UINT16:
12981 case FT_UINT24:
12982 case FT_UINT32:
12983 if (hf->display == BASE_CUSTOM) {
12984 char lbl[ITEM_LABEL_LENGTH240];
12985 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12986
12987 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12987, "fmtfunc"))))
;
12988 fmtfunc(lbl, (uint32_t) tmpval);
12989 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12990 hf->name, lbl);
12991 first = false0;
12992 }
12993 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12994 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12995 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12996 first = false0;
12997 }
12998 else if (!(flags & BMT_NO_INT0x02)) {
12999 char buf[NUMBER_LABEL_LENGTH80];
13000 const char *out = NULL((void*)0);
13001
13002 if (!first) {
13003 proto_item_append_text(item, ", ");
13004 }
13005
13006 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13007 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13008 }
13009 if (out == NULL((void*)0)) {
13010 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13011 }
13012 proto_item_append_text(item, "%s: %s", hf->name, out);
13013 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13014 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13015 }
13016 first = false0;
13017 }
13018
13019 break;
13020
13021 case FT_INT8:
13022 case FT_INT16:
13023 case FT_INT24:
13024 case FT_INT32:
13025 integer32 = (uint32_t) tmpval;
13026 if (hf->bitmask) {
13027 no_of_bits = ws_count_ones(hf->bitmask);
13028 integer32 = ws_sign_ext32(integer32, no_of_bits);
13029 }
13030 if (hf->display == BASE_CUSTOM) {
13031 char lbl[ITEM_LABEL_LENGTH240];
13032 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13033
13034 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13034, "fmtfunc"))))
;
13035 fmtfunc(lbl, (int32_t) integer32);
13036 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13037 hf->name, lbl);
13038 first = false0;
13039 }
13040 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13041 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13042 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13043 first = false0;
13044 }
13045 else if (!(flags & BMT_NO_INT0x02)) {
13046 char buf[NUMBER_LABEL_LENGTH80];
13047 const char *out = NULL((void*)0);
13048
13049 if (!first) {
13050 proto_item_append_text(item, ", ");
13051 }
13052
13053 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13054 out = hf_try_val_to_str((int32_t) integer32, hf);
13055 }
13056 if (out == NULL((void*)0)) {
13057 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13058 }
13059 proto_item_append_text(item, "%s: %s", hf->name, out);
13060 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13061 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13062 }
13063 first = false0;
13064 }
13065
13066 break;
13067
13068 case FT_UINT40:
13069 case FT_UINT48:
13070 case FT_UINT56:
13071 case FT_UINT64:
13072 if (hf->display == BASE_CUSTOM) {
13073 char lbl[ITEM_LABEL_LENGTH240];
13074 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13075
13076 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13076, "fmtfunc"))))
;
13077 fmtfunc(lbl, tmpval);
13078 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13079 hf->name, lbl);
13080 first = false0;
13081 }
13082 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13083 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13084 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13085 first = false0;
13086 }
13087 else if (!(flags & BMT_NO_INT0x02)) {
13088 char buf[NUMBER_LABEL_LENGTH80];
13089 const char *out = NULL((void*)0);
13090
13091 if (!first) {
13092 proto_item_append_text(item, ", ");
13093 }
13094
13095 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13096 out = hf_try_val64_to_str(tmpval, hf);
13097 }
13098 if (out == NULL((void*)0)) {
13099 out = hfinfo_number_value_format64(hf, buf, tmpval);
13100 }
13101 proto_item_append_text(item, "%s: %s", hf->name, out);
13102 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13103 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13104 }
13105 first = false0;
13106 }
13107
13108 break;
13109
13110 case FT_INT40:
13111 case FT_INT48:
13112 case FT_INT56:
13113 case FT_INT64:
13114 if (hf->bitmask) {
13115 no_of_bits = ws_count_ones(hf->bitmask);
13116 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13117 }
13118 if (hf->display == BASE_CUSTOM) {
13119 char lbl[ITEM_LABEL_LENGTH240];
13120 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13121
13122 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13122, "fmtfunc"))))
;
13123 fmtfunc(lbl, (int64_t) tmpval);
13124 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13125 hf->name, lbl);
13126 first = false0;
13127 }
13128 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13129 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13130 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13131 first = false0;
13132 }
13133 else if (!(flags & BMT_NO_INT0x02)) {
13134 char buf[NUMBER_LABEL_LENGTH80];
13135 const char *out = NULL((void*)0);
13136
13137 if (!first) {
13138 proto_item_append_text(item, ", ");
13139 }
13140
13141 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13142 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13143 }
13144 if (out == NULL((void*)0)) {
13145 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13146 }
13147 proto_item_append_text(item, "%s: %s", hf->name, out);
13148 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13149 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13150 }
13151 first = false0;
13152 }
13153
13154 break;
13155
13156 case FT_BOOLEAN:
13157 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13158 /* If we have true/false strings, emit full - otherwise messages
13159 might look weird */
13160 const struct true_false_string *tfs =
13161 (const struct true_false_string *)hf->strings;
13162
13163 if (tmpval) {
13164 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13165 hf->name, tfs->true_string);
13166 first = false0;
13167 } else if (!(flags & BMT_NO_FALSE0x04)) {
13168 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13169 hf->name, tfs->false_string);
13170 first = false0;
13171 }
13172 } else if (hf->bitmask & value) {
13173 /* If the flag is set, show the name */
13174 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13175 first = false0;
13176 }
13177 break;
13178 default:
13179 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))
13180 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))
13181 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))
13182 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))
;
13183 break;
13184 }
13185
13186 fields++;
13187 }
13188
13189 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13190 * but then again most dissectors don't set the bitmask field for
13191 * the higher level bitmask hfi, so calculate the bitmask from the
13192 * fields present. */
13193 if (item) {
13194 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13195 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13196 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)
;
13197 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)
;
13198 }
13199 return first;
13200}
13201
13202/* This function will dissect a sequence of bytes that describe a
13203 * bitmask and supply the value of that sequence through a pointer.
13204 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13205 * to be dissected.
13206 * This field will form an expansion under which the individual fields of the
13207 * bitmask is dissected and displayed.
13208 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13209 *
13210 * fields is an array of pointers to int that lists all the fields of the
13211 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13212 * or another integer of the same type/size as hf_hdr with a mask specified.
13213 * This array is terminated by a NULL entry.
13214 *
13215 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13216 * FT_integer fields that have a value_string attached will have the
13217 * matched string displayed on the expansion line.
13218 */
13219proto_item *
13220proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13221 const unsigned offset, const int hf_hdr,
13222 const int ett, int * const *fields,
13223 const unsigned encoding, uint64_t *retval)
13224{
13225 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);
13226}
13227
13228/* This function will dissect a sequence of bytes that describe a
13229 * bitmask.
13230 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13231 * to be dissected.
13232 * This field will form an expansion under which the individual fields of the
13233 * bitmask is dissected and displayed.
13234 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13235 *
13236 * fields is an array of pointers to int that lists all the fields of the
13237 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13238 * or another integer of the same type/size as hf_hdr with a mask specified.
13239 * This array is terminated by a NULL entry.
13240 *
13241 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13242 * FT_integer fields that have a value_string attached will have the
13243 * matched string displayed on the expansion line.
13244 */
13245proto_item *
13246proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13247 const unsigned offset, const int hf_hdr,
13248 const int ett, int * const *fields,
13249 const unsigned encoding)
13250{
13251 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13252}
13253
13254/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13255 * what data is appended to the header.
13256 */
13257proto_item *
13258proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13259 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13260 uint64_t *retval)
13261{
13262 proto_item *item = NULL((void*)0);
13263 header_field_info *hf;
13264 int len;
13265 uint64_t value;
13266
13267 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", 13267, __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", 13267
, "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", 13267, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13268 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", 13268, (hf)->abbrev)))
;
13269 len = ftype_wire_size(hf->type);
13270 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13271
13272 if (parent_tree) {
13273 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13274 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13275 flags, false0, false0, NULL((void*)0), value);
13276 }
13277
13278 *retval = value;
13279 if (hf->bitmask) {
13280 /* Mask out irrelevant portions */
13281 *retval &= hf->bitmask;
13282 /* Shift bits */
13283 *retval >>= hfinfo_bitshift(hf);
13284 }
13285
13286 return item;
13287}
13288
13289/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13290 * what data is appended to the header.
13291 */
13292proto_item *
13293proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13294 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13295{
13296 proto_item *item = NULL((void*)0);
13297 header_field_info *hf;
13298 int len;
13299 uint64_t value;
13300
13301 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", 13301, __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", 13301
, "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", 13301, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13302 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", 13302, (hf)->abbrev)))
;
13303
13304 if (parent_tree) {
13305 len = ftype_wire_size(hf->type);
13306 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13307 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13308 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13309 flags, false0, false0, NULL((void*)0), value);
13310 }
13311
13312 return item;
13313}
13314
13315/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13316 can't be retrieved directly from tvb) */
13317proto_item *
13318proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13319 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13320{
13321 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13322 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13323}
13324
13325/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13326WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13327proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13328 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13329{
13330 proto_item *item = NULL((void*)0);
13331 header_field_info *hf;
13332 int len;
13333
13334 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", 13334, __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", 13334
, "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", 13334, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13335 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", 13335, (hf)->abbrev)))
;
13336 /* the proto_tree_add_uint/_uint64() calls below
13337 will fail if tvb==NULL and len!=0 */
13338 len = tvb ? ftype_wire_size(hf->type) : 0;
13339
13340 if (parent_tree) {
13341 if (len <= 4)
13342 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13343 else
13344 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13345
13346 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13347 flags, false0, false0, NULL((void*)0), value);
13348 }
13349
13350 return item;
13351}
13352
13353/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13354void
13355proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13356 const int len, int * const *fields, const unsigned encoding)
13357{
13358 uint64_t value;
13359
13360 if (tree) {
13361 value = get_uint64_value(tree, tvb, offset, len, encoding);
13362 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13363 BMT_NO_APPEND0x01, false0, true1, tree, value);
13364 }
13365}
13366
13367WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13368proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13369 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13370{
13371 uint64_t value;
13372
13373 value = get_uint64_value(tree, tvb, offset, len, encoding);
13374 if (tree) {
13375 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13376 BMT_NO_APPEND0x01, false0, true1, tree, value);
13377 }
13378 if (retval) {
13379 *retval = value;
13380 }
13381}
13382
13383WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13384proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13385 const int len, int * const *fields, const uint64_t value)
13386{
13387 if (tree) {
13388 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13389 BMT_NO_APPEND0x01, false0, true1, tree, value);
13390 }
13391}
13392
13393
13394/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13395 * This is intended to support bitmask fields whose lengths can vary, perhaps
13396 * as the underlying standard evolves over time.
13397 * With this API there is the possibility of being called to display more or
13398 * less data than the dissector was coded to support.
13399 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13400 * Thus when presented with "too much" or "too little" data, MSbits will be
13401 * ignored or MSfields sacrificed.
13402 *
13403 * Only fields for which all defined bits are available are displayed.
13404 */
13405proto_item *
13406proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13407 const unsigned offset, const unsigned len, const int hf_hdr,
13408 const int ett, int * const *fields, struct expert_field* exp,
13409 const unsigned encoding)
13410{
13411 proto_item *item = NULL((void*)0);
13412 header_field_info *hf;
13413 unsigned decodable_len;
13414 unsigned decodable_offset;
13415 uint32_t decodable_value;
13416 uint64_t value;
13417
13418 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", 13418, __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", 13418
, "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", 13418, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13419 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", 13419, (hf)->abbrev)))
;
13420
13421 decodable_offset = offset;
13422 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13423
13424 /* If we are ftype_wire_size-limited,
13425 * make sure we decode as many LSBs as possible.
13426 */
13427 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13428 decodable_offset += (len - decodable_len);
13429 }
13430
13431 if (parent_tree) {
13432 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13433 decodable_len, encoding);
13434
13435 /* The root item covers all the bytes even if we can't decode them all */
13436 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13437 decodable_value);
13438 }
13439
13440 if (decodable_len < len) {
13441 /* Dissector likely requires updating for new protocol revision */
13442 expert_add_info_format(NULL((void*)0), item, exp,
13443 "Only least-significant %d of %d bytes decoded",
13444 decodable_len, len);
13445 }
13446
13447 if (item) {
13448 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13449 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13450 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13451 }
13452
13453 return item;
13454}
13455
13456/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13457proto_item *
13458proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13459 const unsigned offset, const unsigned len,
13460 const char *name, const char *fallback,
13461 const int ett, int * const *fields,
13462 const unsigned encoding, const int flags)
13463{
13464 proto_item *item = NULL((void*)0);
13465 uint64_t value;
13466
13467 if (parent_tree) {
13468 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13469 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13470 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13471 flags, true1, false0, NULL((void*)0), value) && fallback) {
13472 /* Still at first item - append 'fallback' text if any */
13473 proto_item_append_text(item, "%s", fallback);
13474 }
13475 }
13476
13477 return item;
13478}
13479
13480proto_item *
13481proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13482 const unsigned bit_offset, const int no_of_bits,
13483 const unsigned encoding)
13484{
13485 header_field_info *hfinfo;
13486 int octet_length;
13487 unsigned octet_offset;
13488
13489 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", 13489, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13489
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13489, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13490
13491 if (no_of_bits < 0) {
13492 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13493 }
13494 octet_length = (no_of_bits + 7) >> 3;
13495 octet_offset = bit_offset >> 3;
13496 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13497
13498 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13499 * but only after doing a bunch more work (which we can, in the common
13500 * case, shortcut here).
13501 */
13502 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13503 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", 13503
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13503, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13503, "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", 13503, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13504
13505 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13506}
13507
13508/*
13509 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13510 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13511 * Offset should be given in bits from the start of the tvb.
13512 */
13513
13514static proto_item *
13515_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13516 const unsigned bit_offset, const int no_of_bits,
13517 uint64_t *return_value, const unsigned encoding)
13518{
13519 unsigned offset;
13520 unsigned length;
13521 uint8_t tot_no_bits;
13522 char *bf_str;
13523 char lbl_str[ITEM_LABEL_LENGTH240];
13524 uint64_t value = 0;
13525 uint8_t *bytes = NULL((void*)0);
13526 size_t bytes_length = 0;
13527
13528 proto_item *pi;
13529 header_field_info *hf_field;
13530
13531 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13532 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", 13532, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13532
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13532, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13533
13534 if (hf_field->bitmask != 0) {
13535 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)
13536 " 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)
13537 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)
;
13538 }
13539
13540 if (no_of_bits < 0) {
13541 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13542 } else if (no_of_bits == 0) {
13543 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)
13544 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)
;
13545 }
13546
13547 /* Byte align offset */
13548 offset = bit_offset>>3;
13549
13550 /*
13551 * Calculate the number of octets used to hold the bits
13552 */
13553 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13554 length = (tot_no_bits + 7) >> 3;
13555
13556 if (no_of_bits < 65) {
13557 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13558 } else if (hf_field->type != FT_BYTES) {
13559 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)
13560 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)
;
13561 return NULL((void*)0);
13562 }
13563
13564 /* Sign extend for signed types */
13565 switch (hf_field->type) {
13566 case FT_INT8:
13567 case FT_INT16:
13568 case FT_INT24:
13569 case FT_INT32:
13570 case FT_INT40:
13571 case FT_INT48:
13572 case FT_INT56:
13573 case FT_INT64:
13574 value = ws_sign_ext64(value, no_of_bits);
13575 break;
13576
13577 default:
13578 break;
13579 }
13580
13581 if (return_value) {
13582 *return_value = value;
13583 }
13584
13585 /* Coast clear. Try and fake it */
13586 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13587 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", 13587
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13587, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13587, "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", 13587, __func__, "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); } } }
;
13588
13589 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13590
13591 switch (hf_field->type) {
13592 case FT_BOOLEAN:
13593 /* Boolean field */
13594 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13595 "%s = %s: %s",
13596 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13597 break;
13598
13599 case FT_CHAR:
13600 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13601 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13602 break;
13603
13604 case FT_UINT8:
13605 case FT_UINT16:
13606 case FT_UINT24:
13607 case FT_UINT32:
13608 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13609 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13610 break;
13611
13612 case FT_INT8:
13613 case FT_INT16:
13614 case FT_INT24:
13615 case FT_INT32:
13616 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13617 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13618 break;
13619
13620 case FT_UINT40:
13621 case FT_UINT48:
13622 case FT_UINT56:
13623 case FT_UINT64:
13624 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13625 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13626 break;
13627
13628 case FT_INT40:
13629 case FT_INT48:
13630 case FT_INT56:
13631 case FT_INT64:
13632 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13633 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13634 break;
13635
13636 case FT_BYTES:
13637 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13638 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13639 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13640 proto_item_set_text(pi, "%s", lbl_str);
13641 return pi;
13642
13643 /* TODO: should handle FT_UINT_BYTES ? */
13644
13645 default:
13646 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))
13647 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))
13648 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))
13649 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))
;
13650 return NULL((void*)0);
13651 }
13652
13653 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13654 return pi;
13655}
13656
13657proto_item *
13658proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13659 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13660 uint64_t *return_value)
13661{
13662 proto_item *pi;
13663 int no_of_bits;
13664 unsigned octet_offset;
13665 unsigned mask_initial_bit_offset;
13666 unsigned mask_greatest_bit_offset;
13667 unsigned octet_length;
13668 uint8_t i;
13669 char bf_str[256];
13670 char lbl_str[ITEM_LABEL_LENGTH240];
13671 uint64_t value;
13672 uint64_t composite_bitmask;
13673 uint64_t composite_bitmap;
13674
13675 header_field_info *hf_field;
13676
13677 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13678 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", 13678, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13678
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13678, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
1
Assuming 'hfindex' is not equal to 0
2
Assuming 'hfindex' is <= field 'len'
3
Assuming 'hfindex' is > 0
4
Assuming 'hfindex' is < field 'len'
5
'?' condition is true
6
Assuming the condition is true
7
'?' condition is true
13679
13680 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13681 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)
13682 " 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)
13683 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)
;
13684 }
13685
13686 mask_initial_bit_offset = bit_offset % 8;
13687
13688 no_of_bits = 0;
13689 value = 0;
13690 i = 0;
13691 mask_greatest_bit_offset = 0;
13692 composite_bitmask = 0;
13693 composite_bitmap = 0;
13694
13695 while (crumb_spec[i].crumb_bit_length != 0) {
10
Assuming field 'crumb_bit_length' is not equal to 0
11
Loop condition is true. Entering loop body
13696 uint64_t crumb_mask, crumb_value;
13697 uint8_t crumb_end_bit_offset;
13698
13699 crumb_value = tvb_get_bits64(tvb,
13700 bit_offset + crumb_spec[i].crumb_bit_offset,
13701 crumb_spec[i].crumb_bit_length,
13702 ENC_BIG_ENDIAN0x00000000);
13703 value += crumb_value;
13704 no_of_bits += crumb_spec[i].crumb_bit_length;
13705 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", 13705
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13706
13707 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13708 octet containing the initial offset.
13709 If the mask is beyond 32 bits, then give up on bit map display.
13710 This could be improved in future, probably showing a table
13711 of 32 or 64 bits per row */
13712 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13713 crumb_end_bit_offset = mask_initial_bit_offset
13714 + crumb_spec[i].crumb_bit_offset
13715 + crumb_spec[i].crumb_bit_length;
13716 crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
15
Assuming right operand of bit shift is less than 64
16
Value assigned to 'crumb_mask'
13717
13718 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13719 mask_greatest_bit_offset = crumb_end_bit_offset;
13720 }
13721 /* Currently the bitmap of the crumbs are only shown if
13722 * smaller than 32 bits. Do not bother calculating the
13723 * mask if it is larger than that. */
13724 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13725 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
20
The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'
13726 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13727 }
13728 }
13729 /* Shift left for the next segment */
13730 value <<= crumb_spec[++i].crumb_bit_length;
13731 }
13732
13733 /* Sign extend for signed types */
13734 switch (hf_field->type) {
13735 case FT_INT8:
13736 case FT_INT16:
13737 case FT_INT24:
13738 case FT_INT32:
13739 case FT_INT40:
13740 case FT_INT48:
13741 case FT_INT56:
13742 case FT_INT64:
13743 value = ws_sign_ext64(value, no_of_bits);
13744 break;
13745 default:
13746 break;
13747 }
13748
13749 if (return_value) {
13750 *return_value = value;
13751 }
13752
13753 /* Coast clear. Try and fake it */
13754 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13755 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", 13755
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13755, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13755, "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", 13755, __func__, "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); } } }
;
13756
13757 /* initialise the format string */
13758 bf_str[0] = '\0';
13759
13760 octet_offset = bit_offset >> 3;
13761
13762 /* Round up mask length to nearest octet */
13763 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13764 mask_greatest_bit_offset = octet_length << 3;
13765
13766 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13767 It would be a useful enhancement to eliminate this restriction. */
13768 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13769 other_decode_bitfield_value(bf_str,
13770 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13771 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13772 mask_greatest_bit_offset);
13773 } else {
13774 /* If the bitmask is too large, try to describe its contents. */
13775 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13776 }
13777
13778 switch (hf_field->type) {
13779 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13780 /* Boolean field */
13781 return proto_tree_add_boolean_format(tree, hfindex,
13782 tvb, octet_offset, octet_length, value,
13783 "%s = %s: %s",
13784 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13785 break;
13786
13787 case FT_CHAR:
13788 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13789 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13790 break;
13791
13792 case FT_UINT8:
13793 case FT_UINT16:
13794 case FT_UINT24:
13795 case FT_UINT32:
13796 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13797 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13798 break;
13799
13800 case FT_INT8:
13801 case FT_INT16:
13802 case FT_INT24:
13803 case FT_INT32:
13804 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13805 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13806 break;
13807
13808 case FT_UINT40:
13809 case FT_UINT48:
13810 case FT_UINT56:
13811 case FT_UINT64:
13812 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13813 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13814 break;
13815
13816 case FT_INT40:
13817 case FT_INT48:
13818 case FT_INT56:
13819 case FT_INT64:
13820 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13821 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13822 break;
13823
13824 default:
13825 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))
13826 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))
13827 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))
13828 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))
;
13829 return NULL((void*)0);
13830 }
13831 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13832 return pi;
13833}
13834
13835void
13836proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13837 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13838{
13839 header_field_info *hfinfo;
13840 unsigned start = bit_offset >> 3;
13841 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13842
13843 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13844 * so that we can use the tree's memory scope in calculating the string */
13845 if (length == -1) {
13846 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13847 } else {
13848 tvb_ensure_bytes_exist(tvb, start, length);
13849 }
13850 if (!tree) return;
13851
13852 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", 13852, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13852
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13852, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13853 proto_tree_add_text_internal(tree, tvb, start, length,
13854 "%s crumb %d of %s (decoded above)",
13855 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13856 tvb_get_bits32(tvb,
13857 bit_offset,
13858 crumb_spec[crumb_index].crumb_bit_length,
13859 ENC_BIG_ENDIAN0x00000000),
13860 ENC_BIG_ENDIAN0x00000000),
13861 crumb_index,
13862 hfinfo->name);
13863}
13864
13865proto_item *
13866proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13867 const unsigned bit_offset, const int no_of_bits,
13868 uint64_t *return_value, const unsigned encoding)
13869{
13870 proto_item *item;
13871
13872 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13873 bit_offset, no_of_bits,
13874 return_value, encoding))) {
13875 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)
;
13876 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)
;
13877 }
13878 return item;
13879}
13880
13881static proto_item *
13882_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13883 tvbuff_t *tvb, const unsigned bit_offset,
13884 const int no_of_bits, void *value_ptr,
13885 const unsigned encoding, char *value_str)
13886{
13887 unsigned offset;
13888 unsigned length;
13889 uint8_t tot_no_bits;
13890 char *str;
13891 uint64_t value = 0;
13892 header_field_info *hf_field;
13893
13894 /* We do not have to return a value, try to fake it as soon as possible */
13895 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13896 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", 13896
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13896, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13896, "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", 13896, __func__, "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); } } }
;
13897
13898 if (hf_field->bitmask != 0) {
13899 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)
13900 " 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)
13901 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)
;
13902 }
13903
13904 if (no_of_bits < 0) {
13905 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13906 } else if (no_of_bits == 0) {
13907 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)
13908 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)
;
13909 }
13910
13911 /* Byte align offset */
13912 offset = bit_offset>>3;
13913
13914 /*
13915 * Calculate the number of octets used to hold the bits
13916 */
13917 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13918 length = tot_no_bits>>3;
13919 /* If we are using part of the next octet, increase length by 1 */
13920 if (tot_no_bits & 0x07)
13921 length++;
13922
13923 if (no_of_bits < 65) {
13924 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13925 } else {
13926 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)
13927 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)
;
13928 return NULL((void*)0);
13929 }
13930
13931 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13932
13933 (void) g_strlcat(str, " = ", 256+64);
13934 (void) g_strlcat(str, hf_field->name, 256+64);
13935
13936 /*
13937 * This function does not receive an actual value but a dimensionless pointer to that value.
13938 * For this reason, the type of the header field is examined in order to determine
13939 * what kind of value we should read from this address.
13940 * The caller of this function must make sure that for the specific header field type the address of
13941 * a compatible value is provided.
13942 */
13943 switch (hf_field->type) {
13944 case FT_BOOLEAN:
13945 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13946 "%s: %s", str, value_str);
13947 break;
13948
13949 case FT_CHAR:
13950 case FT_UINT8:
13951 case FT_UINT16:
13952 case FT_UINT24:
13953 case FT_UINT32:
13954 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13955 "%s: %s", str, value_str);
13956 break;
13957
13958 case FT_UINT40:
13959 case FT_UINT48:
13960 case FT_UINT56:
13961 case FT_UINT64:
13962 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13963 "%s: %s", str, value_str);
13964 break;
13965
13966 case FT_INT8:
13967 case FT_INT16:
13968 case FT_INT24:
13969 case FT_INT32:
13970 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13971 "%s: %s", str, value_str);
13972 break;
13973
13974 case FT_INT40:
13975 case FT_INT48:
13976 case FT_INT56:
13977 case FT_INT64:
13978 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13979 "%s: %s", str, value_str);
13980 break;
13981
13982 case FT_FLOAT:
13983 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13984 "%s: %s", str, value_str);
13985 break;
13986
13987 default:
13988 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))
13989 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))
13990 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))
13991 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))
;
13992 return NULL((void*)0);
13993 }
13994}
13995
13996static proto_item *
13997proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13998 tvbuff_t *tvb, const unsigned bit_offset,
13999 const int no_of_bits, void *value_ptr,
14000 const unsigned encoding, char *value_str)
14001{
14002 proto_item *item;
14003
14004 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14005 tvb, bit_offset, no_of_bits,
14006 value_ptr, encoding, value_str))) {
14007 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)
;
14008 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)
;
14009 }
14010 return item;
14011}
14012
14013#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);
\
14014 va_start(ap, format)__builtin_va_start(ap, format); \
14015 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14016 va_end(ap)__builtin_va_end(ap);
14017
14018proto_item *
14019proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14020 tvbuff_t *tvb, const unsigned bit_offset,
14021 const int no_of_bits, uint32_t value,
14022 const unsigned encoding,
14023 const char *format, ...)
14024{
14025 va_list ap;
14026 char *dst;
14027 header_field_info *hf_field;
14028
14029 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14030
14031 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", 14031
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14031, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14031, "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", 14031, __func__, "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); } } }
;
14032
14033 switch (hf_field->type) {
14034 case FT_UINT8:
14035 case FT_UINT16:
14036 case FT_UINT24:
14037 case FT_UINT32:
14038 break;
14039
14040 default:
14041 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)
14042 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)
;
14043 return NULL((void*)0);
14044 }
14045
14046 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);
;
14047
14048 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14049}
14050
14051proto_item *
14052proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14053 tvbuff_t *tvb, const unsigned bit_offset,
14054 const int no_of_bits, uint64_t value,
14055 const unsigned encoding,
14056 const char *format, ...)
14057{
14058 va_list ap;
14059 char *dst;
14060 header_field_info *hf_field;
14061
14062 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14063
14064 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", 14064
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14064, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14064, "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", 14064, __func__, "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); } } }
;
14065
14066 switch (hf_field->type) {
14067 case FT_UINT40:
14068 case FT_UINT48:
14069 case FT_UINT56:
14070 case FT_UINT64:
14071 break;
14072
14073 default:
14074 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)
14075 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)
;
14076 return NULL((void*)0);
14077 }
14078
14079 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);
;
14080
14081 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14082}
14083
14084proto_item *
14085proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14086 tvbuff_t *tvb, const unsigned bit_offset,
14087 const int no_of_bits, float value,
14088 const unsigned encoding,
14089 const char *format, ...)
14090{
14091 va_list ap;
14092 char *dst;
14093 header_field_info *hf_field;
14094
14095 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14096
14097 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", 14097
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14097, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14097, "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", 14097, __func__, "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); } } }
;
14098
14099 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",
14099, ((hf_field))->abbrev))))
;
14100
14101 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);
;
14102
14103 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14104}
14105
14106proto_item *
14107proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14108 tvbuff_t *tvb, const unsigned bit_offset,
14109 const int no_of_bits, int32_t value,
14110 const unsigned encoding,
14111 const char *format, ...)
14112{
14113 va_list ap;
14114 char *dst;
14115 header_field_info *hf_field;
14116
14117 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14118
14119 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", 14119
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14119, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14119, "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", 14119, __func__, "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); } } }
;
14120
14121 switch (hf_field->type) {
14122 case FT_INT8:
14123 case FT_INT16:
14124 case FT_INT24:
14125 case FT_INT32:
14126 break;
14127
14128 default:
14129 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)
14130 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)
;
14131 return NULL((void*)0);
14132 }
14133
14134 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);
;
14135
14136 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14137}
14138
14139proto_item *
14140proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14141 tvbuff_t *tvb, const unsigned bit_offset,
14142 const int no_of_bits, int64_t value,
14143 const unsigned encoding,
14144 const char *format, ...)
14145{
14146 va_list ap;
14147 char *dst;
14148 header_field_info *hf_field;
14149
14150 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14151
14152 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", 14152
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14152, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14152, "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", 14152, __func__, "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); } } }
;
14153
14154 switch (hf_field->type) {
14155 case FT_INT40:
14156 case FT_INT48:
14157 case FT_INT56:
14158 case FT_INT64:
14159 break;
14160
14161 default:
14162 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)
14163 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)
;
14164 return NULL((void*)0);
14165 }
14166
14167 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);
;
14168
14169 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14170}
14171
14172proto_item *
14173proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14174 tvbuff_t *tvb, const unsigned bit_offset,
14175 const int no_of_bits, uint64_t value,
14176 const unsigned encoding,
14177 const char *format, ...)
14178{
14179 va_list ap;
14180 char *dst;
14181 header_field_info *hf_field;
14182
14183 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14184
14185 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", 14185
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14185, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14185, "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", 14185, __func__, "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); } } }
;
14186
14187 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"
, 14187, ((hf_field))->abbrev))))
;
14188
14189 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);
;
14190
14191 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14192}
14193
14194proto_item *
14195proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14196 const unsigned bit_offset, const int no_of_chars)
14197{
14198 proto_item *pi;
14199 header_field_info *hfinfo;
14200 int byte_length;
14201 unsigned byte_offset;
14202 char *string;
14203
14204 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14205
14206 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", 14206
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14206, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14206, "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", 14206, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14207
14208 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"
, 14208, ((hfinfo))->abbrev))))
;
14209
14210 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14211 byte_offset = bit_offset >> 3;
14212
14213 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14214
14215 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14216 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14216, "byte_length >= 0"
))))
;
14217 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14218
14219 return pi;
14220}
14221
14222proto_item *
14223proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14224 const unsigned bit_offset, const int no_of_chars)
14225{
14226 proto_item *pi;
14227 header_field_info *hfinfo;
14228 int byte_length;
14229 unsigned byte_offset;
14230 char *string;
14231
14232 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14233
14234 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", 14234
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14234, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14234, "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", 14234, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14235
14236 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"
, 14236, ((hfinfo))->abbrev))))
;
14237
14238 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14239 byte_offset = bit_offset >> 3;
14240
14241 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14242
14243 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14244 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14244, "byte_length >= 0"
))))
;
14245 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14246
14247 return pi;
14248}
14249
14250const value_string proto_checksum_vals[] = {
14251 { PROTO_CHECKSUM_E_BAD, "Bad" },
14252 { PROTO_CHECKSUM_E_GOOD, "Good" },
14253 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14254 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14255 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14256
14257 { 0, NULL((void*)0) }
14258};
14259
14260#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14261
14262proto_item *
14263proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14264 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14265 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14266{
14267 header_field_info *hfinfo;
14268 uint32_t checksum;
14269 uint32_t len;
14270 proto_item* ti = NULL((void*)0);
14271 proto_item* ti2;
14272 bool_Bool incorrect_checksum = true1;
14273
14274 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", 14274, __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", 14274
, "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", 14274, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14275
14276 switch (hfinfo->type) {
14277 case FT_UINT8:
14278 len = 1;
14279 break;
14280 case FT_UINT16:
14281 len = 2;
14282 break;
14283 case FT_UINT24:
14284 len = 3;
14285 break;
14286 case FT_UINT32:
14287 len = 4;
14288 break;
14289 default:
14290 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)
14291 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14292 }
14293
14294 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14295 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14296 proto_item_set_generated(ti);
14297 // Backward compatible with use of -1
14298 if (hf_checksum_status > 0) {
14299 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14300 proto_item_set_generated(ti2);
14301 }
14302 return ti;
14303 }
14304
14305 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14306 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14307 proto_item_set_generated(ti);
14308 } else {
14309 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14310 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14311 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14312 if (computed_checksum == 0) {
14313 proto_item_append_text(ti, " [correct]");
14314 // Backward compatible with use of -1
14315 if (hf_checksum_status > 0) {
14316 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14317 proto_item_set_generated(ti2);
14318 }
14319 incorrect_checksum = false0;
14320 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14321 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14322 /* XXX - This can't distinguish between "shouldbe"
14323 * 0x0000 and 0xFFFF unless we know whether there
14324 * were any nonzero bits (other than the checksum).
14325 * Protocols should not use this path if they might
14326 * have an all zero packet.
14327 * Some implementations put the wrong zero; maybe
14328 * we should have a special expert info for that?
14329 */
14330 }
14331 } else {
14332 if (checksum == computed_checksum) {
14333 proto_item_append_text(ti, " [correct]");
14334 // Backward compatible with use of -1
14335 if (hf_checksum_status > 0) {
14336 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14337 proto_item_set_generated(ti2);
14338 }
14339 incorrect_checksum = false0;
14340 }
14341 }
14342
14343 if (incorrect_checksum) {
14344 // Backward compatible with use of -1
14345 if (hf_checksum_status > 0) {
14346 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14347 proto_item_set_generated(ti2);
14348 }
14349 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14350 proto_item_append_text(ti, " [incorrect]");
14351 if (bad_checksum_expert != NULL((void*)0))
14352 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14353 } else {
14354 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14355 if (bad_checksum_expert != NULL((void*)0))
14356 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);
14357 }
14358 }
14359 } else {
14360 // Backward compatible with use of -1
14361 if (hf_checksum_status > 0) {
14362 proto_item_append_text(ti, " [unverified]");
14363 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14364 proto_item_set_generated(ti2);
14365 }
14366 }
14367 }
14368
14369 return ti;
14370}
14371
14372proto_item *
14373proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14374 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14375 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14376{
14377 header_field_info *hfinfo;
14378 uint8_t *checksum = NULL((void*)0);
14379 proto_item* ti = NULL((void*)0);
14380 proto_item* ti2;
14381 bool_Bool incorrect_checksum = true1;
14382
14383 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", 14383, __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", 14383
, "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", 14383, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14384
14385 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",
14385, ((hfinfo))->abbrev))))
;
14386
14387 /* Make sure a NULL computed_checksum isn't dereferenced.
14388 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14389 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14390 * cases the behavior is unexpected and still a programmer error;
14391 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14392 * _NOT_PRESENT nor _GENERATED is correct.
14393 */
14394 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", 14394, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14395
14396 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14397 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14398 proto_item_set_generated(ti);
14399 // Backward compatible with use of -1
14400 if (hf_checksum_status > 0) {
14401 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14402 proto_item_set_generated(ti2);
14403 }
14404 return ti;
14405 }
14406
14407 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14408 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14409 proto_item_set_generated(ti);
14410 return ti;
14411 }
14412
14413 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14414 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14415 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14416 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14417 bool_Bool non_zero_flag = false0;
14418 for (size_t index = 0; index < checksum_len; index++) {
14419 if (computed_checksum[index]) {
14420 non_zero_flag = true1;
14421 break;
14422 }
14423 }
14424 if (!non_zero_flag) {
14425 proto_item_append_text(ti, " [correct]");
14426 // Backward compatible with use of -1
14427 if (hf_checksum_status > 0) {
14428 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14429 proto_item_set_generated(ti2);
14430 }
14431 incorrect_checksum = false0;
14432 }
14433 } else {
14434 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14435 proto_item_append_text(ti, " [correct]");
14436 // Backward compatible with use of -1
14437 if (hf_checksum_status > 0) {
14438 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14439 proto_item_set_generated(ti2);
14440 }
14441 incorrect_checksum = false0;
14442 }
14443 }
14444
14445 if (incorrect_checksum) {
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, 0, PROTO_CHECKSUM_E_BAD);
14449 proto_item_set_generated(ti2);
14450 }
14451 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14452 proto_item_append_text(ti, " [incorrect]");
14453 if (bad_checksum_expert != NULL((void*)0))
14454 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14455 } else {
14456 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14457 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14458 if (bad_checksum_expert != NULL((void*)0))
14459 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14460 }
14461 }
14462 } else {
14463 // Backward compatible with use of -1
14464 if (hf_checksum_status > 0) {
14465 proto_item_append_text(ti, " [unverified]");
14466 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14467 proto_item_set_generated(ti2);
14468 }
14469 }
14470
14471 return ti;
14472}
14473
14474unsigned char
14475proto_check_field_name(const char *field_name)
14476{
14477 return module_check_valid_name(field_name, false0);
14478}
14479
14480unsigned char
14481proto_check_field_name_lower(const char *field_name)
14482{
14483 return module_check_valid_name(field_name, true1);
14484}
14485
14486bool_Bool
14487tree_expanded(int tree_type)
14488{
14489 if (tree_type <= 0) {
14490 return false0;
14491 }
14492 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", 14492, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14493 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14494}
14495
14496void
14497tree_expanded_set(int tree_type, bool_Bool value)
14498{
14499 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", 14499, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14500
14501 if (value)
14502 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14503 else
14504 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14505}
14506
14507/*
14508 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14509 *
14510 * Local variables:
14511 * c-basic-offset: 8
14512 * tab-width: 8
14513 * indent-tabs-mode: t
14514 * End:
14515 *
14516 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14517 * :indentSize=8:tabSize=8:noTabs=false:
14518 */