Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13736, 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-23-100357-3596-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 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2685 /* There are several other possible choices for what to do
2686 * with overflow; make sure to coordinate with whatever
2687 * packet-zbee-zcl.h does. */
2688 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2689 }
2690 time_stamp->nsecs = 0;
2691 } else if (length == 4) {
2692 tmpsecs = tvb_get_ntohl(tvb, start);
2693 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2694 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2695 }
2696 time_stamp->nsecs = 0;
2697 } else {
2698 time_stamp->secs = 0;
2699 time_stamp->nsecs = 0;
2700 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2701 }
2702 break;
2703
2704 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2705 /*
2706 * Zigbee ZCL time stamps, little-endian.
2707 * Only supported for absolute times.
2708 */
2709 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2709, "!is_relative"
))))
;
2710
2711 if (length == 8) {
2712 tmp64secs = tvb_get_letoh64(tvb, start);
2713 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2714 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2715 }
2716 time_stamp->nsecs = 0;
2717 } else if (length == 4) {
2718 tmpsecs = tvb_get_letohl(tvb, start);
2719 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2720 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2721 }
2722 time_stamp->nsecs = 0;
2723 } else {
2724 time_stamp->secs = 0;
2725 time_stamp->nsecs = 0;
2726 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2727 }
2728 break;
2729
2730 default:
2731 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2731))
;
2732 break;
2733 }
2734}
2735
2736static void
2737tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2738{
2739 const header_field_info *hfinfo = fi->hfinfo;
2740
2741 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2742 GPtrArray *ptrs = NULL((void*)0);
2743
2744 if (tree_data->interesting_hfids == NULL((void*)0)) {
2745 /* Initialize the hash because we now know that it is needed */
2746 tree_data->interesting_hfids =
2747 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2748 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2749 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2750 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2751 }
2752
2753 if (!ptrs) {
2754 /* First element triggers the creation of pointer array */
2755 ptrs = g_ptr_array_new();
2756 g_hash_table_insert(tree_data->interesting_hfids,
2757 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2758 }
2759
2760 g_ptr_array_add(ptrs, fi);
2761 }
2762}
2763
2764
2765/*
2766 * Validates that field length bytes are available starting from
2767 * start (pos/neg). Throws an exception if they aren't.
2768 */
2769static void
2770test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2771 unsigned start, int length, const unsigned encoding)
2772{
2773 int size = length;
2774
2775 if (!tvb)
2776 return;
2777
2778 if ((hfinfo->type == FT_STRINGZ) ||
2779 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2780 (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
))
))) {
2781 /* If we're fetching until the end of the TVB, only validate
2782 * that the offset is within range.
2783 */
2784 if (length == -1)
2785 size = 0;
2786 }
2787
2788 tvb_ensure_bytes_exist(tvb, start, size);
2789}
2790
2791static void
2792detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2793{
2794 bool_Bool found_stray_character = false0;
2795
2796 if (!string)
2797 return;
2798
2799 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2800 case ENC_ASCII0x00000000:
2801 case ENC_UTF_80x00000002:
2802 for (int i = (int)strlen(string); i < length; i++) {
2803 if (string[i] != '\0') {
2804 found_stray_character = true1;
2805 break;
2806 }
2807 }
2808 break;
2809
2810 default:
2811 break;
2812 }
2813
2814 if (found_stray_character) {
2815 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2816 }
2817}
2818
2819static void
2820free_fvalue_cb(void *data)
2821{
2822 fvalue_t *fv = (fvalue_t*)data;
2823 fvalue_free(fv);
2824}
2825
2826/* Add an item to a proto_tree, using the text label registered to that item;
2827 the item is extracted from the tvbuff handed to it. */
2828static proto_item *
2829proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2830 tvbuff_t *tvb, unsigned start, int length,
2831 unsigned encoding)
2832{
2833 proto_item *pi;
2834 uint32_t value, n;
2835 uint64_t value64;
2836 ws_in4_addr ipv4_value;
2837 float floatval;
2838 double doubleval;
2839 const char *stringval = NULL((void*)0);
2840 nstime_t time_stamp;
2841 bool_Bool length_error;
2842
2843 /* Ensure that the newly created fvalue_t is freed if we throw an
2844 * exception before adding it to the tree. (gcc creates clobbering
2845 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2846 * XXX: Move the new_field_info() call inside here?
2847 */
2848 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))
;
2849
2850 switch (new_fi->hfinfo->type) {
2851 case FT_NONE:
2852 /* no value to set for FT_NONE */
2853 break;
2854
2855 case FT_PROTOCOL:
2856 /* Set the protocol_tvb via the start offset, but include
2857 * rest of the ds_tvb so that if finfo_set_len is called
2858 * later it can be lengthened as much as possible. */
2859 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);
2860 break;
2861
2862 case FT_BYTES:
2863 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2864 break;
2865
2866 case FT_UINT_BYTES:
2867 n = get_uint_value(tree, tvb, start, length, encoding);
2868 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2869
2870 /* Instead of calling proto_item_set_len(), since we don't yet
2871 * have a proto_item, we set the field_info's length ourselves. */
2872 new_fi->length = n + length;
2873 break;
2874
2875 case FT_BOOLEAN:
2876 /*
2877 * Map all non-zero values to little-endian for
2878 * backwards compatibility.
2879 */
2880 if (encoding)
2881 encoding = ENC_LITTLE_ENDIAN0x80000000;
2882 proto_tree_set_boolean(new_fi,
2883 get_uint64_value(tree, tvb, start, length, encoding));
2884 break;
2885
2886 case FT_CHAR:
2887 /* XXX - make these just FT_UINT? */
2888 case FT_UINT8:
2889 case FT_UINT16:
2890 case FT_UINT24:
2891 case FT_UINT32:
2892 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2893 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2894 value = (uint32_t)value64;
2895 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2896 new_fi->flags |= FI_VARINT0x00040000;
2897 }
2898 }
2899 else {
2900 /*
2901 * Map all non-zero values to little-endian for
2902 * backwards compatibility.
2903 */
2904 if (encoding)
2905 encoding = ENC_LITTLE_ENDIAN0x80000000;
2906
2907 value = get_uint_value(tree, tvb, start, length, encoding);
2908 }
2909 proto_tree_set_uint(new_fi, value);
2910 break;
2911
2912 case FT_UINT40:
2913 case FT_UINT48:
2914 case FT_UINT56:
2915 case FT_UINT64:
2916 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2917 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2918 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2919 new_fi->flags |= FI_VARINT0x00040000;
2920 }
2921 }
2922 else {
2923 /*
2924 * Map all other non-zero values to little-endian for
2925 * backwards compatibility.
2926 */
2927 if (encoding)
2928 encoding = ENC_LITTLE_ENDIAN0x80000000;
2929
2930 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2931 }
2932 proto_tree_set_uint64(new_fi, value64);
2933 break;
2934
2935 /* XXX - make these just FT_INT? */
2936 case FT_INT8:
2937 case FT_INT16:
2938 case FT_INT24:
2939 case FT_INT32:
2940 /*
2941 * Map all non-zero values to little-endian for
2942 * backwards compatibility.
2943 */
2944 if (encoding)
2945 encoding = ENC_LITTLE_ENDIAN0x80000000;
2946 proto_tree_set_int(new_fi,
2947 get_int_value(tree, tvb, start, length, encoding));
2948 break;
2949
2950 case FT_INT40:
2951 case FT_INT48:
2952 case FT_INT56:
2953 case FT_INT64:
2954 /*
2955 * Map all non-zero values to little-endian for
2956 * backwards compatibility.
2957 */
2958 if (encoding)
2959 encoding = ENC_LITTLE_ENDIAN0x80000000;
2960 proto_tree_set_int64(new_fi,
2961 get_int64_value(tree, tvb, start, length, encoding));
2962 break;
2963
2964 case FT_IPv4:
2965 /*
2966 * Map all non-zero values to little-endian for
2967 * backwards compatibility.
2968 */
2969 if (encoding)
2970 encoding = ENC_LITTLE_ENDIAN0x80000000;
2971 if (length != FT_IPv4_LEN4) {
2972 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2973 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2974 }
2975 ipv4_value = tvb_get_ipv4(tvb, start);
2976 /*
2977 * NOTE: to support code written when
2978 * proto_tree_add_item() took a bool as its
2979 * last argument, with false meaning "big-endian"
2980 * and true meaning "little-endian", we treat any
2981 * non-zero value of "encoding" as meaning
2982 * "little-endian".
2983 */
2984 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);
2985 break;
2986
2987 case FT_IPXNET:
2988 if (length != FT_IPXNET_LEN4) {
2989 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2990 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2991 }
2992 proto_tree_set_ipxnet(new_fi,
2993 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2994 break;
2995
2996 case FT_IPv6:
2997 if (length != FT_IPv6_LEN16) {
2998 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2999 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3000 }
3001 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3002 break;
3003
3004 case FT_FCWWN:
3005 if (length != FT_FCWWN_LEN8) {
3006 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3007 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3008 }
3009 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3010 break;
3011
3012 case FT_AX25:
3013 if (length != 7) {
3014 length_error = length < 7 ? true1 : false0;
3015 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3016 }
3017 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3018 break;
3019
3020 case FT_VINES:
3021 if (length != VINES_ADDR_LEN6) {
3022 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3023 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3024 }
3025 proto_tree_set_vines_tvb(new_fi, tvb, start);
3026 break;
3027
3028 case FT_ETHER:
3029 if (length != FT_ETHER_LEN6) {
3030 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3031 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3032 }
3033 proto_tree_set_ether_tvb(new_fi, tvb, start);
3034 break;
3035
3036 case FT_EUI64:
3037 /*
3038 * Map all non-zero values to little-endian for
3039 * backwards compatibility.
3040 */
3041 if (encoding)
3042 encoding = ENC_LITTLE_ENDIAN0x80000000;
3043 if (length != FT_EUI64_LEN8) {
3044 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3045 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3046 }
3047 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3048 break;
3049 case FT_GUID:
3050 /*
3051 * Map all non-zero values to little-endian for
3052 * backwards compatibility.
3053 */
3054 if (encoding)
3055 encoding = ENC_LITTLE_ENDIAN0x80000000;
3056 if (length != FT_GUID_LEN16) {
3057 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3058 report_type_length_mismatch(tree, "a GUID", length, length_error);
3059 }
3060 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3061 break;
3062
3063 case FT_OID:
3064 case FT_REL_OID:
3065 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3066 break;
3067
3068 case FT_SYSTEM_ID:
3069 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3070 break;
3071
3072 case FT_FLOAT:
3073 /*
3074 * NOTE: to support code written when
3075 * proto_tree_add_item() took a bool as its
3076 * last argument, with false meaning "big-endian"
3077 * and true meaning "little-endian", we treat any
3078 * non-zero value of "encoding" as meaning
3079 * "little-endian".
3080 *
3081 * At some point in the future, we might
3082 * support non-IEEE-binary floating-point
3083 * formats in the encoding as well
3084 * (IEEE decimal, System/3x0, VAX).
3085 */
3086 if (encoding)
3087 encoding = ENC_LITTLE_ENDIAN0x80000000;
3088 if (length != 4) {
3089 length_error = length < 4 ? true1 : false0;
3090 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3091 }
3092 if (encoding)
3093 floatval = tvb_get_letohieee_float(tvb, start);
3094 else
3095 floatval = tvb_get_ntohieee_float(tvb, start);
3096 proto_tree_set_float(new_fi, floatval);
3097 break;
3098
3099 case FT_DOUBLE:
3100 /*
3101 * NOTE: to support code written when
3102 * proto_tree_add_item() took a bool as its
3103 * last argument, with false meaning "big-endian"
3104 * and true meaning "little-endian", we treat any
3105 * non-zero value of "encoding" as meaning
3106 * "little-endian".
3107 *
3108 * At some point in the future, we might
3109 * support non-IEEE-binary floating-point
3110 * formats in the encoding as well
3111 * (IEEE decimal, System/3x0, VAX).
3112 */
3113 if (encoding == true1)
3114 encoding = ENC_LITTLE_ENDIAN0x80000000;
3115 if (length != 8) {
3116 length_error = length < 8 ? true1 : false0;
3117 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3118 }
3119 if (encoding)
3120 doubleval = tvb_get_letohieee_double(tvb, start);
3121 else
3122 doubleval = tvb_get_ntohieee_double(tvb, start);
3123 proto_tree_set_double(new_fi, doubleval);
3124 break;
3125
3126 case FT_STRING:
3127 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3128 tvb, start, length, &length, encoding);
3129 proto_tree_set_string(new_fi, stringval);
3130
3131 /* Instead of calling proto_item_set_len(), since we
3132 * don't yet have a proto_item, we set the
3133 * field_info's length ourselves.
3134 *
3135 * XXX - our caller can't use that length to
3136 * advance an offset unless they arrange that
3137 * there always be a protocol tree into which
3138 * we're putting this item.
3139 */
3140 new_fi->length = length;
3141 break;
3142
3143 case FT_STRINGZ:
3144 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3145 tree, tvb, start, length, &length, encoding);
3146 proto_tree_set_string(new_fi, stringval);
3147
3148 /* Instead of calling proto_item_set_len(),
3149 * since we don't yet have a proto_item, we
3150 * set the field_info's length ourselves.
3151 *
3152 * XXX - our caller can't use that length to
3153 * advance an offset unless they arrange that
3154 * there always be a protocol tree into which
3155 * we're putting this item.
3156 */
3157 new_fi->length = length;
3158 break;
3159
3160 case FT_UINT_STRING:
3161 /*
3162 * NOTE: to support code written when
3163 * proto_tree_add_item() took a bool as its
3164 * last argument, with false meaning "big-endian"
3165 * and true meaning "little-endian", if the
3166 * encoding value is true, treat that as
3167 * ASCII with a little-endian length.
3168 *
3169 * This won't work for code that passes
3170 * arbitrary non-zero values; that code
3171 * will need to be fixed.
3172 */
3173 if (encoding == true1)
3174 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3175 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3176 tree, tvb, start, length, &length, encoding);
3177 proto_tree_set_string(new_fi, stringval);
3178
3179 /* Instead of calling proto_item_set_len(), since we
3180 * don't yet have a proto_item, we set the
3181 * field_info's length ourselves.
3182 *
3183 * XXX - our caller can't use that length to
3184 * advance an offset unless they arrange that
3185 * there always be a protocol tree into which
3186 * we're putting this item.
3187 */
3188 new_fi->length = length;
3189 break;
3190
3191 case FT_STRINGZPAD:
3192 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3193 tvb, start, length, &length, encoding);
3194 proto_tree_set_string(new_fi, stringval);
3195
3196 /* Instead of calling proto_item_set_len(), since we
3197 * don't yet have a proto_item, we set the
3198 * field_info's length ourselves.
3199 *
3200 * XXX - our caller can't use that length to
3201 * advance an offset unless they arrange that
3202 * there always be a protocol tree into which
3203 * we're putting this item.
3204 */
3205 new_fi->length = length;
3206 break;
3207
3208 case FT_STRINGZTRUNC:
3209 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3210 tvb, start, length, &length, encoding);
3211 proto_tree_set_string(new_fi, stringval);
3212
3213 /* Instead of calling proto_item_set_len(), since we
3214 * don't yet have a proto_item, we set the
3215 * field_info's length ourselves.
3216 *
3217 * XXX - our caller can't use that length to
3218 * advance an offset unless they arrange that
3219 * there always be a protocol tree into which
3220 * we're putting this item.
3221 */
3222 new_fi->length = length;
3223 break;
3224
3225 case FT_ABSOLUTE_TIME:
3226 /*
3227 * Absolute times can be in any of a number of
3228 * formats, and they can be big-endian or
3229 * little-endian.
3230 *
3231 * Historically FT_TIMEs were only timespecs;
3232 * the only question was whether they were stored
3233 * in big- or little-endian format.
3234 *
3235 * For backwards compatibility, we interpret an
3236 * encoding of 1 as meaning "little-endian timespec",
3237 * so that passing true is interpreted as that.
3238 */
3239 if (encoding == true1)
3240 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3241
3242 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3243
3244 proto_tree_set_time(new_fi, &time_stamp);
3245 break;
3246
3247 case FT_RELATIVE_TIME:
3248 /*
3249 * Relative times can be in any of a number of
3250 * formats, and they can be big-endian or
3251 * little-endian.
3252 *
3253 * Historically FT_TIMEs were only timespecs;
3254 * the only question was whether they were stored
3255 * in big- or little-endian format.
3256 *
3257 * For backwards compatibility, we interpret an
3258 * encoding of 1 as meaning "little-endian timespec",
3259 * so that passing true is interpreted as that.
3260 */
3261 if (encoding == true1)
3262 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3263
3264 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3265
3266 proto_tree_set_time(new_fi, &time_stamp);
3267 break;
3268 case FT_IEEE_11073_SFLOAT:
3269 if (encoding)
3270 encoding = ENC_LITTLE_ENDIAN0x80000000;
3271 if (length != 2) {
3272 length_error = length < 2 ? true1 : false0;
3273 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3274 }
3275
3276 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3277
3278 break;
3279 case FT_IEEE_11073_FLOAT:
3280 if (encoding)
3281 encoding = ENC_LITTLE_ENDIAN0x80000000;
3282 if (length != 4) {
3283 length_error = length < 4 ? true1 : false0;
3284 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3285 }
3286 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3287
3288 break;
3289 default:
3290 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))
3291 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))
3292 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))
3293 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))
;
3294 break;
3295 }
3296 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)
;
3297
3298 /* Don't add new node to proto_tree until now so that any exceptions
3299 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3300 /* XXX. wouldn't be better to add this item to tree, with some special
3301 * flag (FI_EXCEPTION?) to know which item caused exception? For
3302 * strings and bytes, we would have to set new_fi->value to something
3303 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3304 * could handle NULL values. */
3305 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3306 pi = proto_tree_add_node(tree, new_fi);
3307
3308 switch (new_fi->hfinfo->type) {
3309
3310 case FT_STRING:
3311 /* XXX: trailing stray character detection should be done
3312 * _before_ conversion to UTF-8, because conversion can change
3313 * the length, or else get_string_length should return a value
3314 * for the "length in bytes of the string after conversion
3315 * including internal nulls." (Noting that we do, for other
3316 * reasons, still need the "length in bytes in the field",
3317 * especially for FT_STRINGZ.)
3318 *
3319 * This is true even for ASCII and UTF-8, because
3320 * substituting REPLACEMENT CHARACTERS for illegal characters
3321 * can also do so (and for UTF-8 possibly even make the
3322 * string _shorter_).
3323 */
3324 detect_trailing_stray_characters(encoding, stringval, length, pi);
3325 break;
3326
3327 default:
3328 break;
3329 }
3330
3331 return pi;
3332}
3333
3334proto_item *
3335proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3336 const unsigned start, int length,
3337 const unsigned encoding, int32_t *retval)
3338{
3339 header_field_info *hfinfo;
3340 field_info *new_fi;
3341 int32_t value;
3342
3343 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", 3343, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3343,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3343, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3344
3345 switch (hfinfo->type) {
3346 case FT_INT8:
3347 case FT_INT16:
3348 case FT_INT24:
3349 case FT_INT32:
3350 break;
3351 case FT_INT64:
3352 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)
3353 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3354 default:
3355 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)
3356 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3357 }
3358
3359 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3360 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3361 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3362 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3363 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3364 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3365 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3366
3367 if (encoding & ENC_STRING0x07000000) {
3368 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3369 }
3370 /* I believe it's ok if this is called with a NULL tree */
3371 value = get_int_value(tree, tvb, start, length, encoding);
3372
3373 if (retval) {
3374 int no_of_bits;
3375 *retval = value;
3376 if (hfinfo->bitmask) {
3377 /* Mask out irrelevant portions */
3378 *retval &= (uint32_t)(hfinfo->bitmask);
3379 /* Shift bits */
3380 *retval >>= hfinfo_bitshift(hfinfo);
3381 }
3382 no_of_bits = ws_count_ones(hfinfo->bitmask);
3383 *retval = ws_sign_ext32(*retval, no_of_bits);
3384 }
3385
3386 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3387
3388 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", 3388
, __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", 3388, "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", 3388, "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", 3388, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3389
3390 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3391
3392 proto_tree_set_int(new_fi, value);
3393
3394 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3395
3396 return proto_tree_add_node(tree, new_fi);
3397}
3398
3399proto_item *
3400proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3401 const unsigned start, int length,
3402 const unsigned encoding, uint32_t *retval)
3403{
3404 header_field_info *hfinfo;
3405 field_info *new_fi;
3406 uint32_t value;
3407
3408 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", 3408, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3408,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3408, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3409
3410 switch (hfinfo->type) {
3411 case FT_CHAR:
3412 case FT_UINT8:
3413 case FT_UINT16:
3414 case FT_UINT24:
3415 case FT_UINT32:
3416 break;
3417 default:
3418 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)
3419 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)
;
3420 }
3421
3422 if (length == 0) {
3423 if (retval) {
3424 *retval = 0;
3425 }
3426 return NULL((void*)0);
3427 }
3428
3429 if (encoding & ENC_STRING0x07000000) {
3430 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3431 }
3432 /* I believe it's ok if this is called with a NULL tree */
3433 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3434 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3435 uint64_t temp64;
3436 tvb_get_varint(tvb, start, length, &temp64, encoding);
3437 value = (uint32_t)temp64;
3438 } else {
3439 value = get_uint_value(tree, tvb, start, length, encoding);
3440 }
3441
3442 if (retval) {
3443 *retval = value;
3444 if (hfinfo->bitmask) {
3445 /* Mask out irrelevant portions */
3446 *retval &= (uint32_t)(hfinfo->bitmask);
3447 /* Shift bits */
3448 *retval >>= hfinfo_bitshift(hfinfo);
3449 }
3450 }
3451
3452 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3453
3454 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", 3454
, __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", 3454, "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", 3454, "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", 3454, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3455
3456 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3457
3458 proto_tree_set_uint(new_fi, value);
3459
3460 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3461 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3462 new_fi->flags |= FI_VARINT0x00040000;
3463 }
3464 return proto_tree_add_node(tree, new_fi);
3465}
3466
3467proto_item *
3468proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3469 const unsigned start, int length,
3470 const unsigned encoding, uint32_t *retval)
3471{
3472 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3473}
3474
3475proto_item *
3476proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3477 const unsigned start, int length,
3478 const unsigned encoding, uint8_t *retval)
3479{
3480 /* TODO: further restrict by hfinfo->type ? */
3481 uint32_t val32;
3482 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3483 *retval = (uint8_t)val32;
3484 return item;
3485}
3486
3487proto_item *
3488proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3489 const unsigned start, int length,
3490 const unsigned encoding, uint16_t *retval)
3491{
3492 /* TODO: further restrict by hfinfo->type ? */
3493 uint32_t val32;
3494 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3495 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3496 return item;
3497}
3498
3499
3500/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3501 * and returns proto_item* and uint value retrieved*/
3502proto_item *
3503ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3504 const unsigned encoding, uint32_t *retval)
3505{
3506 field_info *new_fi;
3507 header_field_info *hfinfo;
3508 unsigned item_length;
3509 unsigned offset;
3510 uint32_t value;
3511
3512 offset = ptvc->offset;
3513 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", 3513, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3513,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3513, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3514
3515 switch (hfinfo->type) {
3516 case FT_CHAR:
3517 case FT_UINT8:
3518 case FT_UINT16:
3519 case FT_UINT24:
3520 case FT_UINT32:
3521 break;
3522 default:
3523 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)
3524 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)
;
3525 }
3526
3527 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3528 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3529
3530 /* I believe it's ok if this is called with a NULL tree */
3531 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3532 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3533
3534 if (retval) {
3535 *retval = value;
3536 if (hfinfo->bitmask) {
3537 /* Mask out irrelevant portions */
3538 *retval &= (uint32_t)(hfinfo->bitmask);
3539 /* Shift bits */
3540 *retval >>= hfinfo_bitshift(hfinfo);
3541 }
3542 }
3543
3544 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3545
3546 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3547
3548 /* Coast clear. Try and fake it */
3549 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", 3549
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3549, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3549, "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", 3549, __func__, "Adding %s would put more than %d 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); } } }
;
3550
3551 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3552
3553 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3554 offset, length, encoding);
3555}
3556
3557/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3558 * and returns proto_item* and int value retrieved*/
3559proto_item *
3560ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3561 const unsigned encoding, int32_t *retval)
3562{
3563 field_info *new_fi;
3564 header_field_info *hfinfo;
3565 unsigned item_length;
3566 unsigned offset;
3567 uint32_t value;
3568
3569 offset = ptvc->offset;
3570 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", 3570, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3570,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3570, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3571
3572 switch (hfinfo->type) {
3573 case FT_INT8:
3574 case FT_INT16:
3575 case FT_INT24:
3576 case FT_INT32:
3577 break;
3578 default:
3579 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)
3580 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3581 }
3582
3583 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3584 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3585
3586 /* I believe it's ok if this is called with a NULL tree */
3587 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3588 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3589
3590 if (retval) {
3591 int no_of_bits;
3592 *retval = value;
3593 if (hfinfo->bitmask) {
3594 /* Mask out irrelevant portions */
3595 *retval &= (uint32_t)(hfinfo->bitmask);
3596 /* Shift bits */
3597 *retval >>= hfinfo_bitshift(hfinfo);
3598 }
3599 no_of_bits = ws_count_ones(hfinfo->bitmask);
3600 *retval = ws_sign_ext32(*retval, no_of_bits);
3601 }
3602
3603 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3604
3605 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3606
3607 /* Coast clear. Try and fake it */
3608 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", 3608
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3608, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3608, "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", 3608, __func__, "Adding %s would put more than %d 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); } } }
;
3609
3610 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3611
3612 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3613 offset, length, encoding);
3614}
3615
3616/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3617 * and returns proto_item* and string value retrieved */
3618proto_item*
3619ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3620{
3621 header_field_info *hfinfo;
3622 field_info *new_fi;
3623 const uint8_t *value;
3624 unsigned item_length;
3625 unsigned offset;
3626
3627 offset = ptvc->offset;
3628
3629 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", 3629
, __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", 3629, "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", 3629, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3630
3631 switch (hfinfo->type) {
3632 case FT_STRING:
3633 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3634 break;
3635 case FT_STRINGZ:
3636 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3637 break;
3638 case FT_UINT_STRING:
3639 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3640 break;
3641 case FT_STRINGZPAD:
3642 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3643 break;
3644 case FT_STRINGZTRUNC:
3645 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3646 break;
3647 default:
3648 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)
3649 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)
;
3650 }
3651
3652 if (retval)
3653 *retval = value;
3654
3655 ptvcursor_advance(ptvc, item_length);
3656
3657 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3658
3659 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", 3659, __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", 3659,
"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", 3659, "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", 3659
, __func__, "Adding %s would put more than %d 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); } } }
;
3660
3661 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3662
3663 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3664 offset, length, encoding);
3665}
3666
3667/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3668 * and returns proto_item* and boolean value retrieved */
3669proto_item*
3670ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3671{
3672 header_field_info *hfinfo;
3673 field_info *new_fi;
3674 unsigned item_length;
3675 unsigned offset;
3676 uint64_t value, bitval;
3677
3678 offset = ptvc->offset;
3679 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", 3679, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3679,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3679, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3680
3681 if (hfinfo->type != FT_BOOLEAN) {
3682 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)
3683 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3684 }
3685
3686 if (length == 0) {
3687 if (retval) {
3688 *retval = 0;
3689 }
3690 return NULL((void*)0);
3691 }
3692 if (encoding & ENC_STRING0x07000000) {
3693 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3694 }
3695
3696 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3697 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3698
3699 /* I believe it's ok if this is called with a NULL tree */
3700 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3701
3702 if (retval) {
3703 bitval = value;
3704 if (hfinfo->bitmask) {
3705 /* Mask out irrelevant portions */
3706 bitval &= hfinfo->bitmask;
3707 }
3708 *retval = (bitval != 0);
3709 }
3710
3711 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3712
3713 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3714
3715 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", 3715, __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", 3715,
"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", 3715, "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", 3715
, __func__, "Adding %s would put more than %d 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); } } }
;
3716
3717 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3718
3719 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3720 offset, length, encoding);
3721}
3722
3723proto_item *
3724proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3725 const unsigned start, int length, const unsigned encoding, uint64_t *retval)
3726{
3727 header_field_info *hfinfo;
3728 field_info *new_fi;
3729 uint64_t value;
3730
3731 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3731, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3731,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3731, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3732
3733 switch (hfinfo->type) {
3734 case FT_UINT40:
3735 case FT_UINT48:
3736 case FT_UINT56:
3737 case FT_UINT64:
3738 break;
3739 default:
3740 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)
3741 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3742 }
3743
3744 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3745 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3746 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3747 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3748 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3749 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3750 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3751
3752 if (encoding & ENC_STRING0x07000000) {
3753 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3754 }
3755 /* I believe it's ok if this is called with a NULL tree */
3756 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3757 tvb_get_varint(tvb, start, length, &value, encoding);
3758 } else {
3759 value = get_uint64_value(tree, tvb, start, length, encoding);
3760 }
3761
3762 if (retval) {
3763 *retval = value;
3764 if (hfinfo->bitmask) {
3765 /* Mask out irrelevant portions */
3766 *retval &= hfinfo->bitmask;
3767 /* Shift bits */
3768 *retval >>= hfinfo_bitshift(hfinfo);
3769 }
3770 }
3771
3772 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3773
3774 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", 3774
, __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", 3774, "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", 3774, "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", 3774, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3775
3776 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3777
3778 proto_tree_set_uint64(new_fi, value);
3779
3780 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3781 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3782 new_fi->flags |= FI_VARINT0x00040000;
3783 }
3784
3785 return proto_tree_add_node(tree, new_fi);
3786}
3787
3788proto_item *
3789proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3790 const unsigned start, int length, const unsigned encoding, int64_t *retval)
3791{
3792 header_field_info *hfinfo;
3793 field_info *new_fi;
3794 int64_t value;
3795
3796 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", 3796, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3796,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3796, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3797
3798 switch (hfinfo->type) {
3799 case FT_INT40:
3800 case FT_INT48:
3801 case FT_INT56:
3802 case FT_INT64:
3803 break;
3804 default:
3805 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)
3806 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3807 }
3808
3809 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3810 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3811 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3812 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3813 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3814 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3815 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3816
3817 if (encoding & ENC_STRING0x07000000) {
3818 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3819 }
3820 /* I believe it's ok if this is called with a NULL tree */
3821 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3822 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3823 }
3824 else {
3825 value = get_int64_value(tree, tvb, start, length, encoding);
3826 }
3827
3828 if (retval) {
3829 *retval = value;
3830 }
3831
3832 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3833
3834 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", 3834
, __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", 3834, "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", 3834, "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", 3834, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3835
3836 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3837
3838 proto_tree_set_int64(new_fi, value);
3839
3840 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3841 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3842 new_fi->flags |= FI_VARINT0x00040000;
3843 }
3844
3845 return proto_tree_add_node(tree, new_fi);
3846}
3847
3848proto_item *
3849proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3850 const unsigned start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3851{
3852 header_field_info *hfinfo;
3853 field_info *new_fi;
3854 uint64_t value;
3855
3856 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", 3856, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3856,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3856, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3857
3858 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
))
)) {
3859 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)
3860 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3861 }
3862
3863 /* length validation for native number encoding caught by get_uint64_value() */
3864 /* length has to be -1 or > 0 regardless of encoding */
3865 if (length == 0)
3866 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)
3867 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3868
3869 if (encoding & ENC_STRING0x07000000) {
3870 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3871 }
3872
3873 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3874
3875 if (retval) {
3876 *retval = value;
3877 if (hfinfo->bitmask) {
3878 /* Mask out irrelevant portions */
3879 *retval &= hfinfo->bitmask;
3880 /* Shift bits */
3881 *retval >>= hfinfo_bitshift(hfinfo);
3882 }
3883 }
3884
3885 if (lenretval) {
3886 *lenretval = length;
3887 }
3888
3889 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3890
3891 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", 3891
, __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", 3891, "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", 3891, "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", 3891, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3892
3893 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3894
3895 proto_tree_set_uint64(new_fi, value);
3896
3897 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3898 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3899 new_fi->flags |= FI_VARINT0x00040000;
3900 }
3901
3902 return proto_tree_add_node(tree, new_fi);
3903
3904}
3905
3906proto_item *
3907proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3908 const unsigned start, int length,
3909 const unsigned encoding, bool_Bool *retval)
3910{
3911 header_field_info *hfinfo;
3912 field_info *new_fi;
3913 uint64_t value, bitval;
3914
3915 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", 3915, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3915,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3915, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3916
3917 if (hfinfo->type != FT_BOOLEAN) {
3918 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)
3919 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3920 }
3921
3922 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3923 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3924 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3925 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3926 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3927 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3928 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3929
3930 if (encoding & ENC_STRING0x07000000) {
3931 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3932 }
3933 /* I believe it's ok if this is called with a NULL tree */
3934 value = get_uint64_value(tree, tvb, start, length, encoding);
3935
3936 if (retval) {
3937 bitval = value;
3938 if (hfinfo->bitmask) {
3939 /* Mask out irrelevant portions */
3940 bitval &= hfinfo->bitmask;
3941 }
3942 *retval = (bitval != 0);
3943 }
3944
3945 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3946
3947 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", 3947
, __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", 3947, "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", 3947, "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", 3947, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3948
3949 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3950
3951 proto_tree_set_boolean(new_fi, value);
3952
3953 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3954
3955 return proto_tree_add_node(tree, new_fi);
3956}
3957
3958proto_item *
3959proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3960 const unsigned start, int length,
3961 const unsigned encoding, float *retval)
3962{
3963 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3964 field_info *new_fi;
3965 float value;
3966
3967 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", 3967,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3968
3969 if (hfinfo->type != FT_FLOAT) {
3970 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)
;
3971 }
3972
3973 if (length != 4) {
3974 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3975 }
3976
3977 /* treat any nonzero encoding as little endian for backwards compatibility */
3978 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3979 if (retval) {
3980 *retval = value;
3981 }
3982
3983 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3984
3985 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", 3985
, __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", 3985, "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", 3985, "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", 3985, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3986
3987 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3988 if (encoding) {
3989 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3990 }
3991
3992 proto_tree_set_float(new_fi, value);
3993
3994 return proto_tree_add_node(tree, new_fi);
3995}
3996
3997proto_item *
3998proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3999 const unsigned start, int length,
4000 const unsigned encoding, double *retval)
4001{
4002 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4003 field_info *new_fi;
4004 double value;
4005
4006 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", 4006,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4007
4008 if (hfinfo->type != FT_DOUBLE) {
4009 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)
;
4010 }
4011
4012 if (length != 8) {
4013 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4014 }
4015
4016 /* treat any nonzero encoding as little endian for backwards compatibility */
4017 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4018 if (retval) {
4019 *retval = value;
4020 }
4021
4022 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4023
4024 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", 4024
, __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", 4024, "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", 4024, "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", 4024, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4025
4026 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4027 if (encoding) {
4028 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4029 }
4030
4031 proto_tree_set_double(new_fi, value);
4032
4033 return proto_tree_add_node(tree, new_fi);
4034}
4035
4036proto_item *
4037proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4038 const unsigned start, int length,
4039 const unsigned encoding, ws_in4_addr *retval)
4040{
4041 header_field_info *hfinfo;
4042 field_info *new_fi;
4043 ws_in4_addr value;
4044
4045 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", 4045, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4045,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4045, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4046
4047 switch (hfinfo->type) {
4048 case FT_IPv4:
4049 break;
4050 default:
4051 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)
4052 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4053 }
4054
4055 if (length != FT_IPv4_LEN4)
4056 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)
4057 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4058
4059 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4060 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4061 }
4062
4063 /*
4064 * NOTE: to support code written when proto_tree_add_item() took
4065 * a bool as its last argument, with false meaning "big-endian"
4066 * and true meaning "little-endian", we treat any non-zero value
4067 * of "encoding" as meaning "little-endian".
4068 */
4069 value = tvb_get_ipv4(tvb, start);
4070 if (encoding)
4071 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))))
;
4072
4073 if (retval) {
4074 *retval = value;
4075 }
4076
4077 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4078
4079 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", 4079
, __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", 4079, "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", 4079, "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", 4079, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4080
4081 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4082
4083 proto_tree_set_ipv4(new_fi, value);
4084
4085 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4086 return proto_tree_add_node(tree, new_fi);
4087}
4088
4089proto_item *
4090proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4091 const unsigned start, int length,
4092 const unsigned encoding, ws_in6_addr *addr)
4093{
4094 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4095 field_info *new_fi;
4096
4097 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", 4097,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4098
4099 switch (hfinfo->type) {
4100 case FT_IPv6:
4101 break;
4102 default:
4103 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)
4104 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4105 }
4106
4107 if (length != FT_IPv6_LEN16)
4108 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)
4109 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4110
4111 if (encoding) {
4112 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"
)
;
4113 }
4114
4115 tvb_get_ipv6(tvb, start, addr);
4116
4117 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4118
4119 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", 4119
, __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", 4119, "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", 4119, "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", 4119, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4120
4121 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4122
4123 proto_tree_set_ipv6(new_fi, addr);
4124
4125 return proto_tree_add_node(tree, new_fi);
4126}
4127
4128proto_item *
4129proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4130 const unsigned start, int length, const unsigned encoding, uint8_t *retval) {
4131
4132 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4133 field_info *new_fi;
4134
4135 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", 4135,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4136
4137 switch (hfinfo->type) {
4138 case FT_ETHER:
4139 break;
4140 default:
4141 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)
4142 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4143 }
4144
4145 if (length != FT_ETHER_LEN6)
4146 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)
4147 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4148
4149 if (encoding) {
4150 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"
)
;
4151 }
4152
4153 tvb_memcpy(tvb, retval, start, length);
4154
4155 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4156
4157 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", 4157
, __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", 4157, "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", 4157, "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", 4157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4158
4159 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4160
4161 proto_tree_set_ether(new_fi, retval);
4162
4163 return proto_tree_add_node(tree, new_fi);
4164}
4165
4166
4167proto_item *
4168proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4169 tvbuff_t *tvb,
4170 const unsigned start, int length,
4171 const unsigned encoding,
4172 wmem_allocator_t *scope,
4173 const uint8_t **retval,
4174 int *lenretval)
4175{
4176 proto_item *pi;
4177 header_field_info *hfinfo;
4178 field_info *new_fi;
4179 const uint8_t *value;
4180
4181 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", 4181, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4181,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4181, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4182
4183 switch (hfinfo->type) {
4184 case FT_STRING:
4185 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4186 break;
4187 case FT_STRINGZ:
4188 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4189 break;
4190 case FT_UINT_STRING:
4191 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4192 break;
4193 case FT_STRINGZPAD:
4194 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4195 break;
4196 case FT_STRINGZTRUNC:
4197 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4198 break;
4199 default:
4200 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)
4201 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)
;
4202 }
4203
4204 if (retval)
4205 *retval = value;
4206
4207 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4208
4209 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", 4209
, __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", 4209, "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", 4209, "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", 4209, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4210
4211 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4212
4213 proto_tree_set_string(new_fi, (const char*)value);
4214
4215 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4216
4217 pi = proto_tree_add_node(tree, new_fi);
4218
4219 switch (hfinfo->type) {
4220
4221 case FT_STRINGZ:
4222 case FT_STRINGZPAD:
4223 case FT_STRINGZTRUNC:
4224 case FT_UINT_STRING:
4225 break;
4226
4227 case FT_STRING:
4228 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4229 break;
4230
4231 default:
4232 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4232
, __func__, "assertion \"not reached\" failed")
;
4233 }
4234
4235 return pi;
4236}
4237
4238proto_item *
4239proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4240 const unsigned start, int length,
4241 const unsigned encoding, wmem_allocator_t *scope,
4242 const uint8_t **retval)
4243{
4244 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4245 tvb, start, length, encoding, scope, retval, &length);
4246}
4247
4248proto_item *
4249proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4250 tvbuff_t *tvb,
4251 const unsigned start, int length,
4252 const unsigned encoding,
4253 wmem_allocator_t *scope,
4254 char **retval,
4255 int *lenretval)
4256{
4257 proto_item *pi;
4258 header_field_info *hfinfo;
4259 field_info *new_fi;
4260 const uint8_t *value;
4261 uint32_t n = 0;
4262
4263 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", 4263, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4263,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4263, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4264
4265 switch (hfinfo->type) {
4266 case FT_STRING:
4267 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4268 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4269 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4270 break;
4271 case FT_STRINGZ:
4272 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4273 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4274 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4275 break;
4276 case FT_UINT_STRING:
4277 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4278 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4279 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4280 break;
4281 case FT_STRINGZPAD:
4282 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4283 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4284 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4285 break;
4286 case FT_STRINGZTRUNC:
4287 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4288 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4289 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4290 break;
4291 case FT_BYTES:
4292 tvb_ensure_bytes_exist(tvb, start, length);
4293 value = tvb_get_ptr(tvb, start, length);
4294 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4295 *lenretval = length;
4296 break;
4297 case FT_UINT_BYTES:
4298 n = get_uint_value(tree, tvb, start, length, encoding);
4299 tvb_ensure_bytes_exist(tvb, start + length, n);
4300 value = tvb_get_ptr(tvb, start + length, n);
4301 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4302 *lenretval = length + n;
4303 break;
4304 default:
4305 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)
4306 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)
;
4307 }
4308
4309 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4310
4311 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", 4311
, __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", 4311, "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", 4311, "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", 4311, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4312
4313 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4314
4315 switch (hfinfo->type) {
4316
4317 case FT_STRING:
4318 case FT_STRINGZ:
4319 case FT_UINT_STRING:
4320 case FT_STRINGZPAD:
4321 case FT_STRINGZTRUNC:
4322 proto_tree_set_string(new_fi, (const char*)value);
4323 break;
4324
4325 case FT_BYTES:
4326 proto_tree_set_bytes(new_fi, value, length);
4327 break;
4328
4329 case FT_UINT_BYTES:
4330 proto_tree_set_bytes(new_fi, value, n);
4331 break;
4332
4333 default:
4334 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4334
, __func__, "assertion \"not reached\" failed")
;
4335 }
4336
4337 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4338
4339 pi = proto_tree_add_node(tree, new_fi);
4340
4341 switch (hfinfo->type) {
4342
4343 case FT_STRINGZ:
4344 case FT_STRINGZPAD:
4345 case FT_STRINGZTRUNC:
4346 case FT_UINT_STRING:
4347 break;
4348
4349 case FT_STRING:
4350 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4351 break;
4352
4353 case FT_BYTES:
4354 case FT_UINT_BYTES:
4355 break;
4356
4357 default:
4358 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4358
, __func__, "assertion \"not reached\" failed")
;
4359 }
4360
4361 return pi;
4362}
4363
4364proto_item *
4365proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4366 tvbuff_t *tvb,
4367 const unsigned start, int length,
4368 const unsigned encoding,
4369 wmem_allocator_t *scope,
4370 char **retval)
4371{
4372 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4373 tvb, start, length, encoding, scope, retval, &length);
4374}
4375
4376proto_item *
4377proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4378 tvbuff_t *tvb,
4379 const unsigned start, int length, const unsigned encoding,
4380 wmem_allocator_t *scope, char **retval)
4381{
4382 header_field_info *hfinfo;
4383 field_info *new_fi;
4384 nstime_t time_stamp;
4385 int flags;
4386
4387 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", 4387, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4387,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4387, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4388
4389 switch (hfinfo->type) {
4390 case FT_ABSOLUTE_TIME:
4391 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4392 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4393 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4394 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4395 }
4396 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4397 break;
4398 case FT_RELATIVE_TIME:
4399 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4400 *retval = rel_time_to_secs_str(scope, &time_stamp);
4401 break;
4402 default:
4403 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)
4404 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4405 }
4406
4407 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4408
4409 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", 4409
, __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", 4409, "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", 4409, "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", 4409, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4410
4411 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4412
4413 switch (hfinfo->type) {
4414
4415 case FT_ABSOLUTE_TIME:
4416 case FT_RELATIVE_TIME:
4417 proto_tree_set_time(new_fi, &time_stamp);
4418 break;
4419 default:
4420 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4420
, __func__, "assertion \"not reached\" failed")
;
4421 }
4422
4423 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4424
4425 return proto_tree_add_node(tree, new_fi);
4426}
4427
4428/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4429 and returns proto_item* */
4430proto_item *
4431ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4432 const unsigned encoding)
4433{
4434 field_info *new_fi;
4435 header_field_info *hfinfo;
4436 int item_length;
4437 unsigned offset;
4438
4439 offset = ptvc->offset;
4440 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", 4440, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4440,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4440, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4441 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4442 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4443
4444 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4445
4446 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4447
4448 /* Coast clear. Try and fake it */
4449 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", 4449
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4449, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4449, "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", 4449, __func__, "Adding %s would put more than %d 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); } } }
;
4450
4451 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4452
4453 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4454 offset, length, encoding);
4455}
4456
4457/* Add an item to a proto_tree, using the text label registered to that item;
4458 the item is extracted from the tvbuff handed to it. */
4459proto_item *
4460proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4461 const unsigned start, int length, const unsigned encoding)
4462{
4463 field_info *new_fi;
4464 int item_length;
4465
4466 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", 4466,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4467
4468 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4469 test_length(hfinfo, tvb, start, item_length, encoding);
4470
4471 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4472
4473 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", 4473
, __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", 4473, "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", 4473, "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", 4473, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4474
4475 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4476
4477 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4478}
4479
4480proto_item *
4481proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4482 const unsigned start, int length, const unsigned encoding)
4483{
4484 register header_field_info *hfinfo;
4485
4486 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", 4486, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4486,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4486, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4487 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4488}
4489
4490/* Add an item to a proto_tree, using the text label registered to that item;
4491 the item is extracted from the tvbuff handed to it.
4492
4493 Return the length of the item through the pointer. */
4494proto_item *
4495proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4496 tvbuff_t *tvb, const unsigned start,
4497 int length, const unsigned encoding,
4498 int *lenretval)
4499{
4500 field_info *new_fi;
4501 int item_length;
4502 proto_item *item;
4503
4504 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", 4504,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4505
4506 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4507 test_length(hfinfo, tvb, start, item_length, encoding);
4508
4509 if (!tree) {
4510 /*
4511 * We need to get the correct item length here.
4512 * That's normally done by proto_tree_new_item(),
4513 * but we won't be calling it.
4514 */
4515 *lenretval = get_full_length(hfinfo, tvb, start, length,
4516 item_length, encoding);
4517 return NULL((void*)0);
4518 }
4519
4520 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", 4527
, __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", 4527, "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", 4527, "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", 4527
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4521 /*((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", 4527
, __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", 4527, "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", 4527, "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", 4527
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4522 * 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", 4527
, __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", 4527, "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", 4527, "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", 4527
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4523 * 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", 4527
, __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", 4527, "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", 4527, "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", 4527
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4524 */((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", 4527
, __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", 4527, "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", 4527, "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", 4527
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4525 *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", 4527
, __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", 4527, "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", 4527, "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", 4527
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4526 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", 4527
, __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", 4527, "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", 4527, "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", 4527
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4527 })((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", 4527
, __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", 4527, "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", 4527, "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", 4527
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4528
4529 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4530
4531 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4532 *lenretval = new_fi->length;
4533 return item;
4534}
4535
4536proto_item *
4537proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4538 const unsigned start, int length,
4539 const unsigned encoding, int *lenretval)
4540{
4541 register header_field_info *hfinfo;
4542
4543 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", 4543, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4543,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4543, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4544 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4545}
4546
4547/* which FT_ types can use proto_tree_add_bytes_item() */
4548static inline bool_Bool
4549validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4550{
4551 return (type == FT_BYTES ||
4552 type == FT_UINT_BYTES ||
4553 type == FT_OID ||
4554 type == FT_REL_OID ||
4555 type == FT_SYSTEM_ID );
4556}
4557
4558/* Note: this does no validation that the byte array of an FT_OID or
4559 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4560 so I think it's ok to continue not validating it?
4561 */
4562proto_item *
4563proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4564 const unsigned start, unsigned length,
4565 const unsigned encoding,
4566 GByteArray *retval, unsigned *endoff, int *err)
4567{
4568 field_info *new_fi;
4569 GByteArray *bytes = retval;
4570 GByteArray *created_bytes = NULL((void*)0);
4571 bool_Bool failed = false0;
4572 uint32_t n = 0;
4573 header_field_info *hfinfo;
4574 bool_Bool generate = (bytes || tree) ? true1 : false0;
4575
4576 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", 4576, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4576,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4576, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4577
4578 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", 4578,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4579
4580 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", 4581, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4581 "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", 4581, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4582
4583 if (length == 0) {
4584 return NULL((void*)0);
4585 }
4586
4587 if (encoding & ENC_STR_NUM0x01000000) {
4588 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"
)
;
4589 }
4590
4591 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4592 if (hfinfo->type == FT_UINT_BYTES) {
4593 /* can't decode FT_UINT_BYTES from strings */
4594 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")
4595 "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")
;
4596 }
4597
4598 unsigned hex_encoding = encoding;
4599 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4600 /* If none of the separator values are used,
4601 * assume no separator (the common case). */
4602 hex_encoding |= ENC_SEP_NONE0x00010000;
4603#if 0
4604 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")
4605 "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")
;
4606#endif
4607 }
4608
4609 if (!bytes) {
4610 /* caller doesn't care about return value, but we need it to
4611 call tvb_get_string_bytes() and set the tree later */
4612 bytes = created_bytes = g_byte_array_new();
4613 }
4614
4615 /*
4616 * bytes might be NULL after this, but can't add expert
4617 * error until later; if it's NULL, just note that
4618 * it failed.
4619 */
4620 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4621 if (bytes == NULL((void*)0))
4622 failed = true1;
4623 }
4624 else if (generate) {
4625 tvb_ensure_bytes_exist(tvb, start, length);
4626
4627 if (hfinfo->type == FT_UINT_BYTES) {
4628 n = length; /* n is now the "header" length */
4629 length = get_uint_value(tree, tvb, start, n, encoding);
4630 /* length is now the value's length; only store the value in the array */
4631 tvb_ensure_bytes_exist(tvb, start + n, length);
4632 if (!bytes) {
4633 /* caller doesn't care about return value, but
4634 * we may need it to set the tree later */
4635 bytes = created_bytes = g_byte_array_new();
4636 }
4637 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4638 }
4639 else if (length > 0) {
4640 if (!bytes) {
4641 /* caller doesn't care about return value, but
4642 * we may need it to set the tree later */
4643 bytes = created_bytes = g_byte_array_new();
4644 }
4645 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4646 }
4647
4648 if (endoff)
4649 *endoff = start + n + length;
4650 }
4651
4652 if (err)
4653 *err = failed ? EINVAL22 : 0;
4654
4655 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); }
4656 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4657 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); }
4658 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); }
4659 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); }
4660 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4661 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4662
4663 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", 4669
, __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", 4669, "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", 4669, "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", 4669
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4664 {((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", 4669
, __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", 4669, "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", 4669, "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", 4669
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4665 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", 4669
, __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", 4669, "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", 4669, "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", 4669
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4666 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", 4669
, __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", 4669, "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", 4669, "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", 4669
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4667 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", 4669
, __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", 4669, "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", 4669, "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", 4669
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4668 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", 4669
, __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", 4669, "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", 4669, "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", 4669
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4669 } )((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", 4669
, __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", 4669, "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", 4669, "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", 4669
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4670
4671 /* n will be zero except when it's a FT_UINT_BYTES */
4672 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4673
4674 if (encoding & ENC_STRING0x07000000) {
4675 if (failed)
4676 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4677
4678 if (bytes)
4679 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4680 else
4681 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4682
4683 if (created_bytes)
4684 g_byte_array_free(created_bytes, true1);
4685 }
4686 else {
4687 /* n will be zero except when it's a FT_UINT_BYTES */
4688 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4689
4690 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4691 * use the byte array created above in this case.
4692 */
4693 if (created_bytes)
4694 g_byte_array_free(created_bytes, true1);
4695
4696 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4697 (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)
;
4698 }
4699
4700 return proto_tree_add_node(tree, new_fi);
4701}
4702
4703
4704proto_item *
4705proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4706 const unsigned start, const unsigned length,
4707 const unsigned encoding,
4708 nstime_t *retval, unsigned *endoff, int *err)
4709{
4710 field_info *new_fi;
4711 nstime_t time_stamp;
4712 int saved_err = 0;
4713 header_field_info *hfinfo;
4714
4715 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", 4715, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4715,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4715, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4716
4717 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", 4717,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4718
4719 if (length == 0) {
4720 if(retval) {
4721 nstime_set_zero(retval);
4722 }
4723 return NULL((void*)0);
4724 }
4725
4726 nstime_set_zero(&time_stamp);
4727
4728 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4729 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", 4729, ((hfinfo))->abbrev))))
;
4730 /* The only string format that could be a relative time is
4731 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4732 * relative to "now" currently.
4733 */
4734 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4735 saved_err = EINVAL22;
4736 }
4737 else {
4738 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", 4738, ((hfinfo))->abbrev))))
;
4739 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4740
4741 tvb_ensure_bytes_exist(tvb, start, length);
4742 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4743 if (endoff) *endoff = start + length;
4744 }
4745
4746 if (err) *err = saved_err;
4747
4748 if (retval) {
4749 retval->secs = time_stamp.secs;
4750 retval->nsecs = time_stamp.nsecs;
4751 }
4752
4753 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4754
4755 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", 4755
, __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", 4755, "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", 4755, "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", 4755, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4756
4757 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4758
4759 proto_tree_set_time(new_fi, &time_stamp);
4760
4761 if (encoding & ENC_STRING0x07000000) {
4762 if (saved_err)
4763 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4764 }
4765 else {
4766 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4767 (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)
;
4768 }
4769
4770 return proto_tree_add_node(tree, new_fi);
4771}
4772
4773/* Add a FT_NONE to a proto_tree */
4774proto_item *
4775proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4776 const unsigned start, int length, const char *format,
4777 ...)
4778{
4779 proto_item *pi;
4780 va_list ap;
4781 header_field_info *hfinfo;
4782
4783 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4784
4785 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", 4785
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4785, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4785, "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", 4785, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4786
4787 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", 4787
, ((hfinfo))->abbrev))))
;
4788
4789 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4790
4791 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4791, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4792
4793 va_start(ap, format)__builtin_va_start(ap, format);
4794 proto_tree_set_representation(pi, format, ap);
4795 va_end(ap)__builtin_va_end(ap);
4796
4797 /* no value to set for FT_NONE */
4798 return pi;
4799}
4800
4801/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4802 * offset, and returns proto_item* */
4803proto_item *
4804ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4805 const unsigned encoding)
4806{
4807 proto_item *item;
4808
4809 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4810 length, encoding);
4811
4812 return item;
4813}
4814
4815/* Advance the ptvcursor's offset within its tvbuff without
4816 * adding anything to the proto_tree. */
4817void
4818ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4819{
4820 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4821 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4822 }
4823}
4824
4825
4826static void
4827proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4828{
4829 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4829, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4830 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4831}
4832
4833/* Add a FT_PROTOCOL to a proto_tree */
4834proto_item *
4835proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4836 unsigned start, int length, const char *format, ...)
4837{
4838 proto_item *pi;
4839 field_info *new_fi;
4840 tvbuff_t *protocol_tvb;
4841 va_list ap;
4842 header_field_info *hfinfo;
4843 char* protocol_rep;
4844
4845 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4846
4847 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", 4847
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4847, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4847, "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", 4847, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4848
4849 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"
, 4849, ((hfinfo))->abbrev))))
;
4850
4851 /*
4852 * This can throw an exception when it calls get_hfi_length before
4853 * it allocates anything, if length is nonzero and start is past
4854 * the end of the tvb. Afterwards it can't throw an exception,
4855 * as length is clamped to the captured length remaining.
4856 */
4857 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4858 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4859 /* Start the protocol_tvb at the correct start offset, but allow it
4860 * to be lengthened later via finfo_set_len. */
4861 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4862
4863 va_start(ap, format)__builtin_va_start(ap, format);
4864 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4865 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4866 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)
;
4867 va_end(ap)__builtin_va_end(ap);
4868
4869 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4869, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4870
4871 va_start(ap, format)__builtin_va_start(ap, format);
4872 proto_tree_set_representation(pi, format, ap);
4873 va_end(ap)__builtin_va_end(ap);
4874
4875 return pi;
4876}
4877
4878/* Add a FT_BYTES to a proto_tree */
4879proto_item *
4880proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4881 int length, const uint8_t *start_ptr)
4882{
4883 proto_item *pi;
4884 header_field_info *hfinfo;
4885 int item_length;
4886
4887 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", 4887, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4887,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4887, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4888 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4889 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4890
4891 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4892
4893 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", 4893
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4893, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4893, "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", 4893, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4894
4895 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",
4895, ((hfinfo))->abbrev))))
;
4896
4897 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4898 start_ptr = tvb_get_ptr(tvb, start, length);
4899
4900 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4901 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4902
4903 return pi;
4904}
4905
4906/* Add a FT_BYTES to a proto_tree */
4907proto_item *
4908proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4909 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4910{
4911 proto_item *pi;
4912 header_field_info *hfinfo;
4913 int item_length;
4914
4915 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", 4915, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4915,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4915, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4916 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4917 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4918
4919 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4920
4921 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", 4921
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4921, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4921, "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", 4921, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4922
4923 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",
4923, ((hfinfo))->abbrev))))
;
4924
4925 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4926 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4927
4928 return pi;
4929}
4930
4931proto_item *
4932proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4933 unsigned start, int length,
4934 const uint8_t *start_ptr,
4935 const char *format, ...)
4936{
4937 proto_item *pi;
4938 va_list ap;
4939
4940 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4941
4942 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; }
;
4943
4944 va_start(ap, format)__builtin_va_start(ap, format);
4945 proto_tree_set_representation_value(pi, format, ap);
4946 va_end(ap)__builtin_va_end(ap);
4947
4948 return pi;
4949}
4950
4951proto_item *
4952proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4953 unsigned start, int length, const uint8_t *start_ptr,
4954 const char *format, ...)
4955{
4956 proto_item *pi;
4957 va_list ap;
4958
4959 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4960
4961 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; }
;
4962
4963 va_start(ap, format)__builtin_va_start(ap, format);
4964 proto_tree_set_representation(pi, format, ap);
4965 va_end(ap)__builtin_va_end(ap);
4966
4967 return pi;
4968}
4969
4970static void
4971proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4972{
4973 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4973, "length >= 0"
))))
;
4974 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", 4974, "start_ptr != ((void*)0) || length == 0"
))))
;
4975
4976 fvalue_set_bytes_data(fi->value, start_ptr, length);
4977}
4978
4979
4980static void
4981proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
4982{
4983 tvb_ensure_bytes_exist(tvb, offset, length);
4984 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4985}
4986
4987static void
4988proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4989{
4990 GByteArray *bytes;
4991
4992 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4992, "value != ((void*)0)"
))))
;
4993
4994 bytes = byte_array_dup(value);
4995
4996 fvalue_set_byte_array(fi->value, bytes);
4997}
4998
4999/* Add a FT_*TIME to a proto_tree */
5000proto_item *
5001proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5002 unsigned length, const nstime_t *value_ptr)
5003{
5004 proto_item *pi;
5005 header_field_info *hfinfo;
5006
5007 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5008
5009 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", 5009
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5009, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5009, "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", 5009, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5010
5011 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", 5011, ((hfinfo))->abbrev))))
;
5012
5013 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5014 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5015
5016 return pi;
5017}
5018
5019proto_item *
5020proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5021 unsigned start, unsigned length, nstime_t *value_ptr,
5022 const char *format, ...)
5023{
5024 proto_item *pi;
5025 va_list ap;
5026
5027 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5028 if (pi != tree) {
5029 va_start(ap, format)__builtin_va_start(ap, format);
5030 proto_tree_set_representation_value(pi, format, ap);
5031 va_end(ap)__builtin_va_end(ap);
5032 }
5033
5034 return pi;
5035}
5036
5037proto_item *
5038proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5039 unsigned start, unsigned length, nstime_t *value_ptr,
5040 const char *format, ...)
5041{
5042 proto_item *pi;
5043 va_list ap;
5044
5045 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5046 if (pi != tree) {
5047 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5047, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5048
5049 va_start(ap, format)__builtin_va_start(ap, format);
5050 proto_tree_set_representation(pi, format, ap);
5051 va_end(ap)__builtin_va_end(ap);
5052 }
5053
5054 return pi;
5055}
5056
5057/* Set the FT_*TIME value */
5058static void
5059proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5060{
5061 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5061, "value_ptr != ((void*)0)"
))))
;
5062
5063 fvalue_set_time(fi->value, value_ptr);
5064}
5065
5066/* Add a FT_IPXNET to a proto_tree */
5067proto_item *
5068proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5069 unsigned length, uint32_t value)
5070{
5071 proto_item *pi;
5072 header_field_info *hfinfo;
5073
5074 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5075
5076 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", 5076
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5076, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5076, "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", 5076, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5077
5078 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"
, 5078, ((hfinfo))->abbrev))))
;
5079
5080 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5081 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5082
5083 return pi;
5084}
5085
5086proto_item *
5087proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5088 unsigned start, unsigned length, uint32_t value,
5089 const char *format, ...)
5090{
5091 proto_item *pi;
5092 va_list ap;
5093
5094 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5095 if (pi != tree) {
5096 va_start(ap, format)__builtin_va_start(ap, format);
5097 proto_tree_set_representation_value(pi, format, ap);
5098 va_end(ap)__builtin_va_end(ap);
5099 }
5100
5101 return pi;
5102}
5103
5104proto_item *
5105proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5106 unsigned start, unsigned length, uint32_t value,
5107 const char *format, ...)
5108{
5109 proto_item *pi;
5110 va_list ap;
5111
5112 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5113 if (pi != tree) {
5114 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5114, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5115
5116 va_start(ap, format)__builtin_va_start(ap, format);
5117 proto_tree_set_representation(pi, format, ap);
5118 va_end(ap)__builtin_va_end(ap);
5119 }
5120
5121 return pi;
5122}
5123
5124/* Set the FT_IPXNET value */
5125static void
5126proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5127{
5128 fvalue_set_uinteger(fi->value, value);
5129}
5130
5131/* Add a FT_IPv4 to a proto_tree */
5132proto_item *
5133proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5134 unsigned length, ws_in4_addr value)
5135{
5136 proto_item *pi;
5137 header_field_info *hfinfo;
5138
5139 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5140
5141 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", 5141
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5141, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5141, "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", 5141, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5142
5143 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", 5143
, ((hfinfo))->abbrev))))
;
5144
5145 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5146 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5147
5148 return pi;
5149}
5150
5151proto_item *
5152proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5153 unsigned start, unsigned length, ws_in4_addr value,
5154 const char *format, ...)
5155{
5156 proto_item *pi;
5157 va_list ap;
5158
5159 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5160 if (pi != tree) {
5161 va_start(ap, format)__builtin_va_start(ap, format);
5162 proto_tree_set_representation_value(pi, format, ap);
5163 va_end(ap)__builtin_va_end(ap);
5164 }
5165
5166 return pi;
5167}
5168
5169proto_item *
5170proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5171 unsigned start, unsigned length, ws_in4_addr value,
5172 const char *format, ...)
5173{
5174 proto_item *pi;
5175 va_list ap;
5176
5177 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5178 if (pi != tree) {
5179 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5179, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5180
5181 va_start(ap, format)__builtin_va_start(ap, format);
5182 proto_tree_set_representation(pi, format, ap);
5183 va_end(ap)__builtin_va_end(ap);
5184 }
5185
5186 return pi;
5187}
5188
5189/* Set the FT_IPv4 value */
5190static void
5191proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5192{
5193 ipv4_addr_and_mask ipv4;
5194 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5195 fvalue_set_ipv4(fi->value, &ipv4);
5196}
5197
5198/* Add a FT_IPv6 to a proto_tree */
5199proto_item *
5200proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5201 unsigned length, const ws_in6_addr *value)
5202{
5203 proto_item *pi;
5204 header_field_info *hfinfo;
5205
5206 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5207
5208 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", 5208
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5208, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5208, "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", 5208, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5209
5210 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", 5210
, ((hfinfo))->abbrev))))
;
5211
5212 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5213 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5214
5215 return pi;
5216}
5217
5218proto_item *
5219proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5220 unsigned start, unsigned length,
5221 const ws_in6_addr *value_ptr,
5222 const char *format, ...)
5223{
5224 proto_item *pi;
5225 va_list ap;
5226
5227 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5228 if (pi != tree) {
5229 va_start(ap, format)__builtin_va_start(ap, format);
5230 proto_tree_set_representation_value(pi, format, ap);
5231 va_end(ap)__builtin_va_end(ap);
5232 }
5233
5234 return pi;
5235}
5236
5237proto_item *
5238proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5239 unsigned start, unsigned length,
5240 const ws_in6_addr *value_ptr,
5241 const char *format, ...)
5242{
5243 proto_item *pi;
5244 va_list ap;
5245
5246 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5247 if (pi != tree) {
5248 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5248, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5249
5250 va_start(ap, format)__builtin_va_start(ap, format);
5251 proto_tree_set_representation(pi, format, ap);
5252 va_end(ap)__builtin_va_end(ap);
5253 }
5254
5255 return pi;
5256}
5257
5258/* Set the FT_IPv6 value */
5259static void
5260proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5261{
5262 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5262, "value != ((void*)0)"
))))
;
5263 ipv6_addr_and_prefix ipv6;
5264 ipv6.addr = *value;
5265 ipv6.prefix = 128;
5266 fvalue_set_ipv6(fi->value, &ipv6);
5267}
5268
5269static void
5270proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5271{
5272 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5273}
5274
5275/* Set the FT_FCWWN value */
5276static void
5277proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5278{
5279 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5279, "value_ptr != ((void*)0)"
))))
;
5280 fvalue_set_fcwwn(fi->value, value_ptr);
5281}
5282
5283static void
5284proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5285{
5286 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5287}
5288
5289/* Add a FT_GUID to a proto_tree */
5290proto_item *
5291proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5292 unsigned length, const e_guid_t *value_ptr)
5293{
5294 proto_item *pi;
5295 header_field_info *hfinfo;
5296
5297 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5298
5299 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", 5299
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5299, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5299, "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", 5299, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5300
5301 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", 5301
, ((hfinfo))->abbrev))))
;
5302
5303 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5304 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5305
5306 return pi;
5307}
5308
5309proto_item *
5310proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5311 unsigned start, unsigned length,
5312 const e_guid_t *value_ptr,
5313 const char *format, ...)
5314{
5315 proto_item *pi;
5316 va_list ap;
5317
5318 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5319 if (pi != tree) {
5320 va_start(ap, format)__builtin_va_start(ap, format);
5321 proto_tree_set_representation_value(pi, format, ap);
5322 va_end(ap)__builtin_va_end(ap);
5323 }
5324
5325 return pi;
5326}
5327
5328proto_item *
5329proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5330 unsigned start, unsigned length, const e_guid_t *value_ptr,
5331 const char *format, ...)
5332{
5333 proto_item *pi;
5334 va_list ap;
5335
5336 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5337 if (pi != tree) {
5338 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5338, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5339
5340 va_start(ap, format)__builtin_va_start(ap, format);
5341 proto_tree_set_representation(pi, format, ap);
5342 va_end(ap)__builtin_va_end(ap);
5343 }
5344
5345 return pi;
5346}
5347
5348/* Set the FT_GUID value */
5349static void
5350proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5351{
5352 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5352, "value_ptr != ((void*)0)"
))))
;
5353 fvalue_set_guid(fi->value, value_ptr);
5354}
5355
5356static void
5357proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5358 const unsigned encoding)
5359{
5360 e_guid_t guid;
5361
5362 tvb_get_guid(tvb, start, &guid, encoding);
5363 proto_tree_set_guid(fi, &guid);
5364}
5365
5366/* Add a FT_OID to a proto_tree */
5367proto_item *
5368proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5369 unsigned length, const uint8_t* value_ptr)
5370{
5371 proto_item *pi;
5372 header_field_info *hfinfo;
5373
5374 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5375
5376 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", 5376
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5376, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5376, "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", 5376, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5377
5378 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", 5378
, ((hfinfo))->abbrev))))
;
5379
5380 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5381 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5382
5383 return pi;
5384}
5385
5386proto_item *
5387proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5388 unsigned start, unsigned length,
5389 const uint8_t* value_ptr,
5390 const char *format, ...)
5391{
5392 proto_item *pi;
5393 va_list ap;
5394
5395 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5396 if (pi != tree) {
5397 va_start(ap, format)__builtin_va_start(ap, format);
5398 proto_tree_set_representation_value(pi, format, ap);
5399 va_end(ap)__builtin_va_end(ap);
5400 }
5401
5402 return pi;
5403}
5404
5405proto_item *
5406proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5407 unsigned start, unsigned length, const uint8_t* value_ptr,
5408 const char *format, ...)
5409{
5410 proto_item *pi;
5411 va_list ap;
5412
5413 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5414 if (pi != tree) {
5415 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5415, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5416
5417 va_start(ap, format)__builtin_va_start(ap, format);
5418 proto_tree_set_representation(pi, format, ap);
5419 va_end(ap)__builtin_va_end(ap);
5420 }
5421
5422 return pi;
5423}
5424
5425/* Set the FT_OID value */
5426static void
5427proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5428{
5429 GByteArray *bytes;
5430
5431 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", 5431, "value_ptr != ((void*)0) || length == 0"
))))
;
5432
5433 bytes = g_byte_array_new();
5434 if (length > 0) {
5435 g_byte_array_append(bytes, value_ptr, length);
5436 }
5437 fvalue_set_byte_array(fi->value, bytes);
5438}
5439
5440static void
5441proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5442{
5443 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5444}
5445
5446/* Set the FT_SYSTEM_ID value */
5447static void
5448proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5449{
5450 GByteArray *bytes;
5451
5452 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", 5452, "value_ptr != ((void*)0) || length == 0"
))))
;
5453
5454 bytes = g_byte_array_new();
5455 if (length > 0) {
5456 g_byte_array_append(bytes, value_ptr, length);
5457 }
5458 fvalue_set_byte_array(fi->value, bytes);
5459}
5460
5461static void
5462proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5463{
5464 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5465}
5466
5467/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5468 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5469 * is destroyed. */
5470proto_item *
5471proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5472 int length, const char* value)
5473{
5474 proto_item *pi;
5475 header_field_info *hfinfo;
5476 int item_length;
5477
5478 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", 5478, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5478,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5478, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5479 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5480 /*
5481 * Special case - if the length is 0, skip the test, so that
5482 * we can have an empty string right after the end of the
5483 * packet. (This handles URL-encoded forms where the last field
5484 * has no value so the form ends right after the =.)
5485 *
5486 * XXX - length zero makes sense for FT_STRING, and more or less
5487 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5488 * for FT_STRINGZ (except that a number of fields that should be
5489 * one of the others are actually registered as FT_STRINGZ.)
5490 */
5491 if (item_length != 0)
5492 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5493
5494 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5495
5496 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", 5496
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5496, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5496, "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", 5496, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5497
5498 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", 5498, ((hfinfo))->abbrev))))
;
5499
5500 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5501 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5501, "length >= 0"
))))
;
5502
5503 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", 5503, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5504 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5505
5506 return pi;
5507}
5508
5509proto_item *
5510proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5511 unsigned start, int length, const char* value,
5512 const char *format,
5513 ...)
5514{
5515 proto_item *pi;
5516 va_list ap;
5517
5518 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5519 if (pi != tree) {
5520 va_start(ap, format)__builtin_va_start(ap, format);
5521 proto_tree_set_representation_value(pi, format, ap);
5522 va_end(ap)__builtin_va_end(ap);
5523 }
5524
5525 return pi;
5526}
5527
5528proto_item *
5529proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5530 unsigned start, int length, const char* value,
5531 const char *format, ...)
5532{
5533 proto_item *pi;
5534 va_list ap;
5535
5536 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5537 if (pi != tree) {
5538 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5538, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5539
5540 va_start(ap, format)__builtin_va_start(ap, format);
5541 proto_tree_set_representation(pi, format, ap);
5542 va_end(ap)__builtin_va_end(ap);
5543 }
5544
5545 return pi;
5546}
5547
5548/* Set the FT_STRING value */
5549static void
5550proto_tree_set_string(field_info *fi, const char* value)
5551{
5552 if (value) {
5553 fvalue_set_string(fi->value, value);
5554 } else {
5555 /*
5556 * XXX - why is a null value for a string field
5557 * considered valid?
5558 */
5559 fvalue_set_string(fi->value, "[ Null ]");
5560 }
5561}
5562
5563/* Set the FT_AX25 value */
5564static void
5565proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5566{
5567 fvalue_set_ax25(fi->value, value);
5568}
5569
5570static void
5571proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5572{
5573 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5574}
5575
5576/* Set the FT_VINES value */
5577static void
5578proto_tree_set_vines(field_info *fi, const uint8_t* value)
5579{
5580 fvalue_set_vines(fi->value, value);
5581}
5582
5583static void
5584proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5585{
5586 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5587}
5588
5589/* Add a FT_ETHER to a proto_tree */
5590proto_item *
5591proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5592 unsigned length, const uint8_t* value)
5593{
5594 proto_item *pi;
5595 header_field_info *hfinfo;
5596
5597 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5598
5599 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", 5599
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5599, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5599, "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", 5599, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5600
5601 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",
5601, ((hfinfo))->abbrev))))
;
5602
5603 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5604 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5605
5606 return pi;
5607}
5608
5609proto_item *
5610proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5611 unsigned start, unsigned length, const uint8_t* value,
5612 const char *format, ...)
5613{
5614 proto_item *pi;
5615 va_list ap;
5616
5617 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5618 if (pi != tree) {
5619 va_start(ap, format)__builtin_va_start(ap, format);
5620 proto_tree_set_representation_value(pi, format, ap);
5621 va_end(ap)__builtin_va_end(ap);
5622 }
5623
5624 return pi;
5625}
5626
5627proto_item *
5628proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5629 unsigned start, unsigned length, const uint8_t* value,
5630 const char *format, ...)
5631{
5632 proto_item *pi;
5633 va_list ap;
5634
5635 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5636 if (pi != tree) {
5637 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5637, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5638
5639 va_start(ap, format)__builtin_va_start(ap, format);
5640 proto_tree_set_representation(pi, format, ap);
5641 va_end(ap)__builtin_va_end(ap);
5642 }
5643
5644 return pi;
5645}
5646
5647/* Set the FT_ETHER value */
5648static void
5649proto_tree_set_ether(field_info *fi, const uint8_t* value)
5650{
5651 fvalue_set_ether(fi->value, value);
5652}
5653
5654static void
5655proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5656{
5657 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5658}
5659
5660/* Add a FT_BOOLEAN to a proto_tree */
5661proto_item *
5662proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5663 unsigned length, uint64_t value)
5664{
5665 proto_item *pi;
5666 header_field_info *hfinfo;
5667
5668 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5669
5670 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", 5670
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5670, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5670, "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", 5670, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5671
5672 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"
, 5672, ((hfinfo))->abbrev))))
;
5673
5674 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5675 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5676
5677 return pi;
5678}
5679
5680proto_item *
5681proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5682 tvbuff_t *tvb, unsigned start, unsigned length,
5683 uint64_t value, const char *format, ...)
5684{
5685 proto_item *pi;
5686 va_list ap;
5687
5688 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5689 if (pi != tree) {
5690 va_start(ap, format)__builtin_va_start(ap, format);
5691 proto_tree_set_representation_value(pi, format, ap);
5692 va_end(ap)__builtin_va_end(ap);
5693 }
5694
5695 return pi;
5696}
5697
5698proto_item *
5699proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5700 unsigned start, unsigned length, uint64_t value,
5701 const char *format, ...)
5702{
5703 proto_item *pi;
5704 va_list ap;
5705
5706 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5707 if (pi != tree) {
5708 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5708, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5709
5710 va_start(ap, format)__builtin_va_start(ap, format);
5711 proto_tree_set_representation(pi, format, ap);
5712 va_end(ap)__builtin_va_end(ap);
5713 }
5714
5715 return pi;
5716}
5717
5718/* Set the FT_BOOLEAN value */
5719static void
5720proto_tree_set_boolean(field_info *fi, uint64_t value)
5721{
5722 proto_tree_set_uint64(fi, value);
5723}
5724
5725/* Generate, into "buf", a string showing the bits of a bitfield.
5726 Return a pointer to the character after that string. */
5727static char *
5728other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5729{
5730 int i = 0;
5731 uint64_t bit;
5732 char *p;
5733
5734 p = buf;
5735
5736 /* This is a devel error. It is safer to stop here. */
5737 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5737, "width >= 1"
))))
;
5738
5739 bit = UINT64_C(1)1UL << (width - 1);
5740 for (;;) {
5741 if (mask & bit) {
5742 /* This bit is part of the field. Show its value. */
5743 if (val & bit)
5744 *p++ = '1';
5745 else
5746 *p++ = '0';
5747 } else {
5748 /* This bit is not part of the field. */
5749 *p++ = '.';
5750 }
5751 bit >>= 1;
5752 i++;
5753 if (i >= width)
5754 break;
5755 if (i % 4 == 0)
5756 *p++ = ' ';
5757 }
5758 *p = '\0';
5759 return p;
5760}
5761
5762static char *
5763decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5764{
5765 char *p;
5766
5767 p = other_decode_bitfield_value(buf, val, mask, width);
5768 p = g_stpcpy(p, " = ");
5769
5770 return p;
5771}
5772
5773static char *
5774other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5775{
5776 int i = 0;
5777 uint64_t bit;
5778 char *p;
5779
5780 p = buf;
5781
5782 /* This is a devel error. It is safer to stop here. */
5783 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5783, "width >= 1"
))))
;
5784
5785 bit = UINT64_C(1)1UL << (width - 1);
5786 for (;;) {
5787 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5788 (mask & bit)) {
5789 /* This bit is part of the field. Show its value. */
5790 if (val & bit)
5791 *p++ = '1';
5792 else
5793 *p++ = '0';
5794 } else {
5795 /* This bit is not part of the field. */
5796 *p++ = '.';
5797 }
5798 bit >>= 1;
5799 i++;
5800 if (i >= width)
5801 break;
5802 if (i % 4 == 0)
5803 *p++ = ' ';
5804 }
5805
5806 *p = '\0';
5807 return p;
5808}
5809
5810static char *
5811decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5812{
5813 char *p;
5814
5815 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5816 p = g_stpcpy(p, " = ");
5817
5818 return p;
5819}
5820
5821/* Add a FT_FLOAT to a proto_tree */
5822proto_item *
5823proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5824 unsigned length, float value)
5825{
5826 proto_item *pi;
5827 header_field_info *hfinfo;
5828
5829 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5830
5831 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", 5831
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5831, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5831, "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", 5831, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5832
5833 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",
5833, ((hfinfo))->abbrev))))
;
5834
5835 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5836 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5837
5838 return pi;
5839}
5840
5841proto_item *
5842proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5843 unsigned start, unsigned length, float value,
5844 const char *format, ...)
5845{
5846 proto_item *pi;
5847 va_list ap;
5848
5849 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5850 if (pi != tree) {
5851 va_start(ap, format)__builtin_va_start(ap, format);
5852 proto_tree_set_representation_value(pi, format, ap);
5853 va_end(ap)__builtin_va_end(ap);
5854 }
5855
5856 return pi;
5857}
5858
5859proto_item *
5860proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5861 unsigned start, unsigned length, float value,
5862 const char *format, ...)
5863{
5864 proto_item *pi;
5865 va_list ap;
5866
5867 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5868 if (pi != tree) {
5869 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5869, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5870
5871 va_start(ap, format)__builtin_va_start(ap, format);
5872 proto_tree_set_representation(pi, format, ap);
5873 va_end(ap)__builtin_va_end(ap);
5874 }
5875
5876 return pi;
5877}
5878
5879/* Set the FT_FLOAT value */
5880static void
5881proto_tree_set_float(field_info *fi, float value)
5882{
5883 fvalue_set_floating(fi->value, value);
5884}
5885
5886/* Add a FT_DOUBLE to a proto_tree */
5887proto_item *
5888proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5889 unsigned length, double value)
5890{
5891 proto_item *pi;
5892 header_field_info *hfinfo;
5893
5894 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5895
5896 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", 5896
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5896, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5896, "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", 5896, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5897
5898 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"
, 5898, ((hfinfo))->abbrev))))
;
5899
5900 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5901 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5902
5903 return pi;
5904}
5905
5906proto_item *
5907proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5908 unsigned start, unsigned length, double value,
5909 const char *format, ...)
5910{
5911 proto_item *pi;
5912 va_list ap;
5913
5914 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5915 if (pi != tree) {
5916 va_start(ap, format)__builtin_va_start(ap, format);
5917 proto_tree_set_representation_value(pi, format, ap);
5918 va_end(ap)__builtin_va_end(ap);
5919 }
5920
5921 return pi;
5922}
5923
5924proto_item *
5925proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5926 unsigned start, unsigned length, double value,
5927 const char *format, ...)
5928{
5929 proto_item *pi;
5930 va_list ap;
5931
5932 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5933 if (pi != tree) {
5934 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5934, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5935
5936 va_start(ap, format)__builtin_va_start(ap, format);
5937 proto_tree_set_representation(pi, format, ap);
5938 va_end(ap)__builtin_va_end(ap);
5939 }
5940
5941 return pi;
5942}
5943
5944/* Set the FT_DOUBLE value */
5945static void
5946proto_tree_set_double(field_info *fi, double value)
5947{
5948 fvalue_set_floating(fi->value, value);
5949}
5950
5951/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5952proto_item *
5953proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5954 unsigned length, uint32_t value)
5955{
5956 proto_item *pi = NULL((void*)0);
5957 header_field_info *hfinfo;
5958
5959 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5960
5961 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", 5961
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5961, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5961, "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", 5961, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5962
5963 switch (hfinfo->type) {
5964 case FT_CHAR:
5965 case FT_UINT8:
5966 case FT_UINT16:
5967 case FT_UINT24:
5968 case FT_UINT32:
5969 case FT_FRAMENUM:
5970 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5971 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5972 break;
5973
5974 default:
5975 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)
5976 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)
;
5977 }
5978
5979 return pi;
5980}
5981
5982proto_item *
5983proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5984 unsigned start, unsigned length, uint32_t value,
5985 const char *format, ...)
5986{
5987 proto_item *pi;
5988 va_list ap;
5989
5990 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5991 if (pi != tree) {
5992 va_start(ap, format)__builtin_va_start(ap, format);
5993 proto_tree_set_representation_value(pi, format, ap);
5994 va_end(ap)__builtin_va_end(ap);
5995 }
5996
5997 return pi;
5998}
5999
6000proto_item *
6001proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6002 unsigned start, unsigned length, uint32_t value,
6003 const char *format, ...)
6004{
6005 proto_item *pi;
6006 va_list ap;
6007
6008 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6009 if (pi != tree) {
6010 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6010, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6011
6012 va_start(ap, format)__builtin_va_start(ap, format);
6013 proto_tree_set_representation(pi, format, ap);
6014 va_end(ap)__builtin_va_end(ap);
6015 }
6016
6017 return pi;
6018}
6019
6020/* Set the FT_UINT{8,16,24,32} value */
6021static void
6022proto_tree_set_uint(field_info *fi, uint32_t value)
6023{
6024 const header_field_info *hfinfo;
6025 uint32_t integer;
6026
6027 hfinfo = fi->hfinfo;
6028 integer = value;
6029
6030 if (hfinfo->bitmask) {
6031 /* Mask out irrelevant portions */
6032 integer &= (uint32_t)(hfinfo->bitmask);
6033
6034 /* Shift bits */
6035 integer >>= hfinfo_bitshift(hfinfo);
6036
6037 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6038 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)
;
6039 }
6040
6041 fvalue_set_uinteger(fi->value, integer);
6042}
6043
6044/* Add FT_UINT{40,48,56,64} to a proto_tree */
6045proto_item *
6046proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6047 unsigned length, uint64_t value)
6048{
6049 proto_item *pi = NULL((void*)0);
6050 header_field_info *hfinfo;
6051
6052 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6053
6054 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", 6054
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6054, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6054, "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", 6054, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6055
6056 switch (hfinfo->type) {
6057 case FT_UINT40:
6058 case FT_UINT48:
6059 case FT_UINT56:
6060 case FT_UINT64:
6061 case FT_FRAMENUM:
6062 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6063 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6064 break;
6065
6066 default:
6067 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)
6068 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)
;
6069 }
6070
6071 return pi;
6072}
6073
6074proto_item *
6075proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6076 unsigned start, unsigned length, uint64_t value,
6077 const char *format, ...)
6078{
6079 proto_item *pi;
6080 va_list ap;
6081
6082 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6083 if (pi != tree) {
6084 va_start(ap, format)__builtin_va_start(ap, format);
6085 proto_tree_set_representation_value(pi, format, ap);
6086 va_end(ap)__builtin_va_end(ap);
6087 }
6088
6089 return pi;
6090}
6091
6092proto_item *
6093proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6094 unsigned start, unsigned length, uint64_t value,
6095 const char *format, ...)
6096{
6097 proto_item *pi;
6098 va_list ap;
6099
6100 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6101 if (pi != tree) {
6102 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6102, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6103
6104 va_start(ap, format)__builtin_va_start(ap, format);
6105 proto_tree_set_representation(pi, format, ap);
6106 va_end(ap)__builtin_va_end(ap);
6107 }
6108
6109 return pi;
6110}
6111
6112/* Set the FT_UINT{40,48,56,64} value */
6113static void
6114proto_tree_set_uint64(field_info *fi, uint64_t value)
6115{
6116 const header_field_info *hfinfo;
6117 uint64_t integer;
6118
6119 hfinfo = fi->hfinfo;
6120 integer = value;
6121
6122 if (hfinfo->bitmask) {
6123 /* Mask out irrelevant portions */
6124 integer &= hfinfo->bitmask;
6125
6126 /* Shift bits */
6127 integer >>= hfinfo_bitshift(hfinfo);
6128
6129 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6130 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)
;
6131 }
6132
6133 fvalue_set_uinteger64(fi->value, integer);
6134}
6135
6136/* Add FT_INT{8,16,24,32} to a proto_tree */
6137proto_item *
6138proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6139 unsigned length, int32_t value)
6140{
6141 proto_item *pi = NULL((void*)0);
6142 header_field_info *hfinfo;
6143
6144 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6145
6146 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", 6146
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6146, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6146, "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", 6146, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6147
6148 switch (hfinfo->type) {
6149 case FT_INT8:
6150 case FT_INT16:
6151 case FT_INT24:
6152 case FT_INT32:
6153 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6154 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6155 break;
6156
6157 default:
6158 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)
6159 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6160 }
6161
6162 return pi;
6163}
6164
6165proto_item *
6166proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6167 unsigned start, unsigned length, int32_t value,
6168 const char *format, ...)
6169{
6170 proto_item *pi;
6171 va_list ap;
6172
6173 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6174 if (pi != tree) {
6175 va_start(ap, format)__builtin_va_start(ap, format);
6176 proto_tree_set_representation_value(pi, format, ap);
6177 va_end(ap)__builtin_va_end(ap);
6178 }
6179
6180 return pi;
6181}
6182
6183proto_item *
6184proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6185 unsigned start, unsigned length, int32_t value,
6186 const char *format, ...)
6187{
6188 proto_item *pi;
6189 va_list ap;
6190
6191 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6192 if (pi != tree) {
6193 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6193, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6194
6195 va_start(ap, format)__builtin_va_start(ap, format);
6196 proto_tree_set_representation(pi, format, ap);
6197 va_end(ap)__builtin_va_end(ap);
6198 }
6199
6200 return pi;
6201}
6202
6203/* Set the FT_INT{8,16,24,32} value */
6204static void
6205proto_tree_set_int(field_info *fi, int32_t value)
6206{
6207 const header_field_info *hfinfo;
6208 uint32_t integer;
6209 int no_of_bits;
6210
6211 hfinfo = fi->hfinfo;
6212 integer = (uint32_t) value;
6213
6214 if (hfinfo->bitmask) {
6215 /* Mask out irrelevant portions */
6216 integer &= (uint32_t)(hfinfo->bitmask);
6217
6218 /* Shift bits */
6219 integer >>= hfinfo_bitshift(hfinfo);
6220
6221 no_of_bits = ws_count_ones(hfinfo->bitmask);
6222 integer = ws_sign_ext32(integer, no_of_bits);
6223
6224 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6225 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6226 }
6227
6228 fvalue_set_sinteger(fi->value, integer);
6229}
6230
6231/* Add FT_INT{40,48,56,64} to a proto_tree */
6232proto_item *
6233proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6234 unsigned length, int64_t value)
6235{
6236 proto_item *pi = NULL((void*)0);
6237 header_field_info *hfinfo;
6238
6239 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6240
6241 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", 6241
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6241, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6241, "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", 6241, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6242
6243 switch (hfinfo->type) {
6244 case FT_INT40:
6245 case FT_INT48:
6246 case FT_INT56:
6247 case FT_INT64:
6248 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6249 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6250 break;
6251
6252 default:
6253 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)
6254 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6255 }
6256
6257 return pi;
6258}
6259
6260proto_item *
6261proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6262 unsigned start, unsigned length, int64_t value,
6263 const char *format, ...)
6264{
6265 proto_item *pi;
6266 va_list ap;
6267
6268 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6269 if (pi != tree) {
6270 va_start(ap, format)__builtin_va_start(ap, format);
6271 proto_tree_set_representation_value(pi, format, ap);
6272 va_end(ap)__builtin_va_end(ap);
6273 }
6274
6275 return pi;
6276}
6277
6278/* Set the FT_INT{40,48,56,64} value */
6279static void
6280proto_tree_set_int64(field_info *fi, int64_t value)
6281{
6282 const header_field_info *hfinfo;
6283 uint64_t integer;
6284 int no_of_bits;
6285
6286 hfinfo = fi->hfinfo;
6287 integer = value;
6288
6289 if (hfinfo->bitmask) {
6290 /* Mask out irrelevant portions */
6291 integer &= hfinfo->bitmask;
6292
6293 /* Shift bits */
6294 integer >>= hfinfo_bitshift(hfinfo);
6295
6296 no_of_bits = ws_count_ones(hfinfo->bitmask);
6297 integer = ws_sign_ext64(integer, no_of_bits);
6298
6299 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6300 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)
;
6301 }
6302
6303 fvalue_set_sinteger64(fi->value, integer);
6304}
6305
6306proto_item *
6307proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6308 unsigned start, unsigned length, int64_t value,
6309 const char *format, ...)
6310{
6311 proto_item *pi;
6312 va_list ap;
6313
6314 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6315 if (pi != tree) {
6316 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6316, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6317
6318 va_start(ap, format)__builtin_va_start(ap, format);
6319 proto_tree_set_representation(pi, format, ap);
6320 va_end(ap)__builtin_va_end(ap);
6321 }
6322
6323 return pi;
6324}
6325
6326/* Add a FT_EUI64 to a proto_tree */
6327proto_item *
6328proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6329 unsigned length, const uint64_t value)
6330{
6331 proto_item *pi;
6332 header_field_info *hfinfo;
6333
6334 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6335
6336 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", 6336
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6336, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6336, "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", 6336, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6337
6338 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",
6338, ((hfinfo))->abbrev))))
;
6339
6340 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6341 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6342
6343 return pi;
6344}
6345
6346proto_item *
6347proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6348 unsigned start, unsigned length, const uint64_t value,
6349 const char *format, ...)
6350{
6351 proto_item *pi;
6352 va_list ap;
6353
6354 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6355 if (pi != tree) {
6356 va_start(ap, format)__builtin_va_start(ap, format);
6357 proto_tree_set_representation_value(pi, format, ap);
6358 va_end(ap)__builtin_va_end(ap);
6359 }
6360
6361 return pi;
6362}
6363
6364proto_item *
6365proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6366 unsigned start, unsigned length, const uint64_t value,
6367 const char *format, ...)
6368{
6369 proto_item *pi;
6370 va_list ap;
6371
6372 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6373 if (pi != tree) {
6374 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6374, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6375
6376 va_start(ap, format)__builtin_va_start(ap, format);
6377 proto_tree_set_representation(pi, format, ap);
6378 va_end(ap)__builtin_va_end(ap);
6379 }
6380
6381 return pi;
6382}
6383
6384/* Set the FT_EUI64 value */
6385static void
6386proto_tree_set_eui64(field_info *fi, const uint64_t value)
6387{
6388 uint8_t v[FT_EUI64_LEN8];
6389 phtonu64(v, value);
6390 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6391}
6392
6393static void
6394proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6395{
6396 if (encoding)
6397 {
6398 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6399 } else {
6400 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6401 }
6402}
6403
6404proto_item *
6405proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6406 const mac_hf_list_t *list_generic,
6407 int idx, tvbuff_t *tvb,
6408 proto_tree *tree, unsigned offset)
6409{
6410 uint8_t addr[6];
6411 const char *addr_name = NULL((void*)0);
6412 const char *oui_name = NULL((void*)0);
6413 proto_item *addr_item = NULL((void*)0);
6414 proto_tree *addr_tree = NULL((void*)0);
6415 proto_item *ret_val = NULL((void*)0);
6416
6417 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6418 return NULL((void*)0);
6419 }
6420
6421 /* Resolve what we can of the address */
6422 tvb_memcpy(tvb, addr, offset, sizeof addr);
6423 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6424 addr_name = get_ether_name(addr);
6425 }
6426 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6427 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6428 }
6429
6430 /* Add the item for the specific address type */
6431 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6432 if (idx >= 0) {
6433 addr_tree = proto_item_add_subtree(ret_val, idx);
6434 }
6435 else {
6436 addr_tree = tree;
6437 }
6438
6439 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6440 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6441 tvb, offset, 6, addr_name);
6442 proto_item_set_generated(addr_item);
6443 proto_item_set_hidden(addr_item);
6444 }
6445
6446 if (list_specific->hf_oui != NULL((void*)0)) {
6447 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6448 proto_item_set_generated(addr_item);
6449 proto_item_set_hidden(addr_item);
6450
6451 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6452 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6453 proto_item_set_generated(addr_item);
6454 proto_item_set_hidden(addr_item);
6455 }
6456 }
6457
6458 if (list_specific->hf_lg != NULL((void*)0)) {
6459 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6460 }
6461 if (list_specific->hf_ig != NULL((void*)0)) {
6462 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6463 }
6464
6465 /* Were we given a list for generic address fields? If not, stop here */
6466 if (list_generic == NULL((void*)0)) {
6467 return ret_val;
6468 }
6469
6470 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6471 proto_item_set_hidden(addr_item);
6472
6473 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6474 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6475 tvb, offset, 6, addr_name);
6476 proto_item_set_generated(addr_item);
6477 proto_item_set_hidden(addr_item);
6478 }
6479
6480 if (list_generic->hf_oui != NULL((void*)0)) {
6481 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6482 proto_item_set_generated(addr_item);
6483 proto_item_set_hidden(addr_item);
6484
6485 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6486 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6487 proto_item_set_generated(addr_item);
6488 proto_item_set_hidden(addr_item);
6489 }
6490 }
6491
6492 if (list_generic->hf_lg != NULL((void*)0)) {
6493 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6494 proto_item_set_hidden(addr_item);
6495 }
6496 if (list_generic->hf_ig != NULL((void*)0)) {
6497 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6498 proto_item_set_hidden(addr_item);
6499 }
6500 return ret_val;
6501}
6502
6503static proto_item *
6504proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6505{
6506 proto_node *pnode, *tnode, *sibling;
6507 field_info *tfi;
6508 unsigned depth = 1;
6509
6510 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6510, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6511
6512 /*
6513 * Restrict our depth. proto_tree_traverse_pre_order and
6514 * proto_tree_traverse_post_order (and possibly others) are recursive
6515 * so we need to be mindful of our stack size.
6516 */
6517 if (tree->first_child == NULL((void*)0)) {
6518 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6519 depth++;
6520 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6521 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__)), 6524)))
6522 "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__)), 6524)))
6523 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__)), 6524)))
6524 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__)), 6524)))
;
6525 }
6526 }
6527 }
6528
6529 /*
6530 * Make sure "tree" is ready to have subtrees under it, by
6531 * checking whether it's been given an ett_ value.
6532 *
6533 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6534 * node of the protocol tree. That node is not displayed,
6535 * so it doesn't need an ett_ value to remember whether it
6536 * was expanded.
6537 */
6538 tnode = tree;
6539 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6540 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6541 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"
, 6542)
6542 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"
, 6542)
;
6543 /* XXX - is it safe to continue here? */
6544 }
6545
6546 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6547 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6548 pnode->parent = tnode;
6549 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6550 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6551 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6552
6553 if (tnode->last_child != NULL((void*)0)) {
6554 sibling = tnode->last_child;
6555 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6555, "sibling->next == ((void*)0)"
))))
;
6556 sibling->next = pnode;
6557 } else
6558 tnode->first_child = pnode;
6559 tnode->last_child = pnode;
6560
6561 /* We should not be adding a fake node for an interesting field */
6562 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", 6562, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6563
6564 /* XXX - Should the proto_item have a header_field_info member, at least
6565 * for faked items, to know what hfi was faked? (Some dissectors look at
6566 * the tree items directly.)
6567 */
6568 return (proto_item *)pnode;
6569}
6570
6571/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6572static proto_item *
6573proto_tree_add_node(proto_tree *tree, field_info *fi)
6574{
6575 proto_node *pnode, *tnode, *sibling;
6576 field_info *tfi;
6577 unsigned depth = 1;
6578
6579 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6579, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6580
6581 /*
6582 * Restrict our depth. proto_tree_traverse_pre_order and
6583 * proto_tree_traverse_post_order (and possibly others) are recursive
6584 * so we need to be mindful of our stack size.
6585 */
6586 if (tree->first_child == NULL((void*)0)) {
6587 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6588 depth++;
6589 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6590 fvalue_free(fi->value);
6591 fi->value = NULL((void*)0);
6592 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__)), 6595)))
6593 "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__)), 6595)))
6594 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__)), 6595)))
6595 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__)), 6595)))
;
6596 }
6597 }
6598 }
6599
6600 /*
6601 * Make sure "tree" is ready to have subtrees under it, by
6602 * checking whether it's been given an ett_ value.
6603 *
6604 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6605 * node of the protocol tree. That node is not displayed,
6606 * so it doesn't need an ett_ value to remember whether it
6607 * was expanded.
6608 */
6609 tnode = tree;
6610 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6611 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6612 /* Since we are not adding fi to a node, its fvalue won't get
6613 * freed by proto_tree_free_node(), so free it now.
6614 */
6615 fvalue_free(fi->value);
6616 fi->value = NULL((void*)0);
6617 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", 6618)
6618 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", 6618)
;
6619 /* XXX - is it safe to continue here? */
6620 }
6621
6622 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6623 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6624 pnode->parent = tnode;
6625 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6626 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6627 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6628
6629 if (tnode->last_child != NULL((void*)0)) {
6630 sibling = tnode->last_child;
6631 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6631, "sibling->next == ((void*)0)"
))))
;
6632 sibling->next = pnode;
6633 } else
6634 tnode->first_child = pnode;
6635 tnode->last_child = pnode;
6636
6637 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6638
6639 return (proto_item *)pnode;
6640}
6641
6642
6643/* Generic way to allocate field_info and add to proto_tree.
6644 * Sets *pfi to address of newly-allocated field_info struct */
6645static proto_item *
6646proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6647 int *length)
6648{
6649 proto_item *pi;
6650 field_info *fi;
6651 int item_length;
6652
6653 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6654 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6655 pi = proto_tree_add_node(tree, fi);
6656
6657 return pi;
6658}
6659
6660/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6661 * Eventually this should replace the other function.
6662 * Sets *pfi to address of newly-allocated field_info struct */
6663static proto_item *
6664proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6665 unsigned *length)
6666{
6667 proto_item *pi;
6668 field_info *fi;
6669 unsigned item_length;
6670
6671 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6672 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6673 pi = proto_tree_add_node(tree, fi);
6674
6675 return pi;
6676}
6677
6678static void
6679get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6680 int *item_length, const unsigned encoding)
6681{
6682 int length_remaining;
6683
6684 /*
6685 * We only allow a null tvbuff if the item has a zero length,
6686 * i.e. if there's no data backing it.
6687 */
6688 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", 6688, "tvb != ((void*)0) || *length == 0"
))))
;
6689
6690 /*
6691 * XXX - in some protocols, there are 32-bit unsigned length
6692 * fields, so lengths in protocol tree and tvbuff routines
6693 * should really be unsigned. We should have, for those
6694 * field types for which "to the end of the tvbuff" makes sense,
6695 * additional routines that take no length argument and
6696 * add fields that run to the end of the tvbuff.
6697 */
6698 if (*length == -1) {
6699 /*
6700 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6701 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6702 * of -1 means "set the length to what remains in the
6703 * tvbuff".
6704 *
6705 * The assumption is either that
6706 *
6707 * 1) the length of the item can only be determined
6708 * by dissection (typically true of items with
6709 * subitems, which are probably FT_NONE or
6710 * FT_PROTOCOL)
6711 *
6712 * or
6713 *
6714 * 2) if the tvbuff is "short" (either due to a short
6715 * snapshot length or due to lack of reassembly of
6716 * fragments/segments/whatever), we want to display
6717 * what's available in the field (probably FT_BYTES
6718 * or FT_STRING) and then throw an exception later
6719 *
6720 * or
6721 *
6722 * 3) the field is defined to be "what's left in the
6723 * packet"
6724 *
6725 * so we set the length to what remains in the tvbuff so
6726 * that, if we throw an exception while dissecting, it
6727 * has what is probably the right value.
6728 *
6729 * For FT_STRINGZ, it means "the string is null-terminated,
6730 * not null-padded; set the length to the actual length
6731 * of the string", and if the tvbuff if short, we just
6732 * throw an exception.
6733 *
6734 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6735 * it means "find the end of the string",
6736 * and if the tvbuff if short, we just throw an exception.
6737 *
6738 * It's not valid for any other type of field. For those
6739 * fields, we treat -1 the same way we treat other
6740 * negative values - we assume the length is a Really
6741 * Big Positive Number, and throw a ReportedBoundsError
6742 * exception, under the assumption that the Really Big
6743 * Length would run past the end of the packet.
6744 */
6745 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
))
)) {
6746 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6747 /*
6748 * Leave the length as -1, so our caller knows
6749 * it was -1.
6750 */
6751 *item_length = *length;
6752 return;
6753 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6754 switch (tvb_get_uint8(tvb, start) >> 6)
6755 {
6756 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6757 *item_length = 1;
6758 break;
6759 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6760 *item_length = 2;
6761 break;
6762 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6763 *item_length = 4;
6764 break;
6765 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6766 *item_length = 8;
6767 break;
6768 }
6769 }
6770 }
6771
6772 switch (hfinfo->type) {
6773
6774 case FT_PROTOCOL:
6775 case FT_NONE:
6776 case FT_BYTES:
6777 case FT_STRING:
6778 case FT_STRINGZPAD:
6779 case FT_STRINGZTRUNC:
6780 /*
6781 * We allow FT_PROTOCOLs to be zero-length -
6782 * for example, an ONC RPC NULL procedure has
6783 * neither arguments nor reply, so the
6784 * payload for that protocol is empty.
6785 *
6786 * We also allow the others to be zero-length -
6787 * because that's the way the code has been for a
6788 * long, long time.
6789 *
6790 * However, we want to ensure that the start
6791 * offset is not *past* the byte past the end
6792 * of the tvbuff: we throw an exception in that
6793 * case.
6794 */
6795 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6796 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6796, "*length >= 0"
))))
;
6797 break;
6798
6799 case FT_STRINGZ:
6800 /*
6801 * Leave the length as -1, so our caller knows
6802 * it was -1.
6803 */
6804 break;
6805
6806 default:
6807 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6808 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6808))
;
6809 }
6810 *item_length = *length;
6811 } else {
6812 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6813 /*
6814 * These types are for interior nodes of the
6815 * tree, and don't have data associated with
6816 * them; if the length is negative (XXX - see
6817 * above) or goes past the end of the tvbuff,
6818 * cut it short at the end of the tvbuff.
6819 * That way, if this field is selected in
6820 * Wireshark, we don't highlight stuff past
6821 * the end of the data.
6822 *
6823 * If we don't have a tvb, then length must be zero,
6824 * per the DISSECTOR_ASSERT() above.
6825 *
6826 * If we do have a tvb, and the length requested is
6827 * nonzero, we want to ensure that the start offset
6828 * is not *past* the byte past the end of the tvbuff
6829 * data: we throw an exception in that case as above.
6830 */
6831 if (tvb && *length) {
6832 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6833 if (*length < 0 ||
6834 (*length > 0 &&
6835 (length_remaining < *length)))
6836 *length = length_remaining;
6837 }
6838 }
6839 *item_length = *length;
6840 if (*item_length < 0) {
6841 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6842 }
6843 }
6844}
6845
6846static void
6847get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6848 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6849{
6850 unsigned length_remaining;
6851
6852 /*
6853 * We only allow a null tvbuff if the item has a zero length,
6854 * i.e. if there's no data backing it.
6855 */
6856 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", 6856, "tvb != ((void*)0) || *length == 0"
))))
;
6857
6858
6859 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6860 /*
6861 * These types are for interior nodes of the
6862 * tree, and don't have data associated with
6863 * them; if the length is negative (XXX - see
6864 * above) or goes past the end of the tvbuff,
6865 * cut it short at the end of the tvbuff.
6866 * That way, if this field is selected in
6867 * Wireshark, we don't highlight stuff past
6868 * the end of the data.
6869 *
6870 * If we don't have a tvb, then length must be zero,
6871 * per the DISSECTOR_ASSERT() above.
6872 *
6873 * If we do have a tvb, and the length requested is
6874 * nonzero, we want to ensure that the start offset
6875 * is not *past* the byte past the end of the tvbuff
6876 * data: we throw an exception in that case as above.
6877 * (If the length requested is zero, then it's quite
6878 * likely that the start offset is the byte past the
6879 * end, but that's ok.)
6880 */
6881 if (tvb && *length) {
6882 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6883 if (length_remaining < *length) {
6884 *length = length_remaining;
6885 }
6886 }
6887 }
6888 *item_length = *length;
6889}
6890
6891static int
6892get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6893 int length, unsigned item_length, const int encoding)
6894{
6895 uint32_t n;
6896
6897 /*
6898 * We need to get the correct item length here.
6899 * That's normally done by proto_tree_new_item(),
6900 * but we won't be calling it.
6901 */
6902 switch (hfinfo->type) {
6903
6904 case FT_NONE:
6905 case FT_PROTOCOL:
6906 case FT_BYTES:
6907 /*
6908 * The length is the specified length.
6909 */
6910 break;
6911
6912 case FT_UINT_BYTES:
6913 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6914 item_length += n;
6915 if ((int)item_length < length) {
6916 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6917 }
6918 break;
6919
6920 /* XXX - make these just FT_UINT? */
6921 case FT_UINT8:
6922 case FT_UINT16:
6923 case FT_UINT24:
6924 case FT_UINT32:
6925 case FT_UINT40:
6926 case FT_UINT48:
6927 case FT_UINT56:
6928 case FT_UINT64:
6929 /* XXX - make these just FT_INT? */
6930 case FT_INT8:
6931 case FT_INT16:
6932 case FT_INT24:
6933 case FT_INT32:
6934 case FT_INT40:
6935 case FT_INT48:
6936 case FT_INT56:
6937 case FT_INT64:
6938 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6939 if (length < -1) {
6940 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6941 }
6942 if (length == -1) {
6943 uint64_t dummy;
6944 /* This can throw an exception */
6945 /* XXX - do this without fetching the varint? */
6946 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6947 if (length == 0) {
6948 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6949 }
6950 }
6951 item_length = length;
6952 break;
6953 }
6954
6955 /*
6956 * The length is the specified length.
6957 */
6958 break;
6959
6960 case FT_BOOLEAN:
6961 case FT_CHAR:
6962 case FT_IPv4:
6963 case FT_IPXNET:
6964 case FT_IPv6:
6965 case FT_FCWWN:
6966 case FT_AX25:
6967 case FT_VINES:
6968 case FT_ETHER:
6969 case FT_EUI64:
6970 case FT_GUID:
6971 case FT_OID:
6972 case FT_REL_OID:
6973 case FT_SYSTEM_ID:
6974 case FT_FLOAT:
6975 case FT_DOUBLE:
6976 case FT_STRING:
6977 /*
6978 * The length is the specified length.
6979 */
6980 break;
6981
6982 case FT_STRINGZ:
6983 if (length < -1) {
6984 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6985 }
6986 if (length == -1) {
6987 /* This can throw an exception */
6988 item_length = tvb_strsize_enc(tvb, start, encoding);
6989 }
6990 break;
6991
6992 case FT_UINT_STRING:
6993 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6994 item_length += n;
6995 if ((int)item_length < length) {
6996 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6997 }
6998 break;
6999
7000 case FT_STRINGZPAD:
7001 case FT_STRINGZTRUNC:
7002 case FT_ABSOLUTE_TIME:
7003 case FT_RELATIVE_TIME:
7004 case FT_IEEE_11073_SFLOAT:
7005 case FT_IEEE_11073_FLOAT:
7006 /*
7007 * The length is the specified length.
7008 */
7009 break;
7010
7011 default:
7012 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
))
7013 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
))
7014 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
))
7015 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
))
;
7016 break;
7017 }
7018 return item_length;
7019}
7020
7021// This was arbitrarily chosen, but if you're adding 50K items to the tree
7022// without advancing the offset you should probably take a long, hard look
7023// at what you're doing.
7024// We *could* make this a configurable option, but I (Gerald) would like to
7025// avoid adding yet another nerd knob.
7026# define PROTO_TREE_MAX_IDLE50000 50000
7027static field_info *
7028new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7029 const unsigned start, const int item_length)
7030{
7031 field_info *fi;
7032
7033 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7034
7035 fi->hfinfo = hfinfo;
7036 fi->start = start;
7037 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7038 /* add the data source tvbuff */
7039 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7040
7041 // If our start offset hasn't advanced after adding many items it probably
7042 // means we're in a large or infinite loop.
7043 if (fi->start > 0) {
7044 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7045 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7046 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7047 if (wireshark_abort_on_too_many_items) {
7048 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", 7049
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7049 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7049
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7050 }
7051 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7052 * but if not, we should hit the max item error earlier,
7053 * so we shouldn't need to reset the tree count to
7054 * ensure that the exception handler can add the item. */
7055 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)))
7056 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)))
7057 "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)))
7058 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)))
;
7059 }
7060 } else {
7061 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7062 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7063 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7064 }
7065 }
7066 fi->length = item_length;
7067 fi->tree_type = -1;
7068 fi->flags = 0;
7069 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7070 /* If the tree is not visible, set the item hidden, unless we
7071 * need the representation or length and can't fake them.
7072 */
7073 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7074 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7075 }
7076 }
7077 fi->value = fvalue_new(fi->hfinfo->type);
7078 fi->rep = NULL((void*)0);
7079
7080 fi->appendix_start = 0;
7081 fi->appendix_length = 0;
7082
7083 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7084 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7085
7086 return fi;
7087}
7088
7089static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7090{
7091 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7092 return 0;
7093 }
7094
7095 /* Search for field name */
7096 char *ptr = strstr(representation, hfinfo->name);
7097 if (!ptr) {
7098 return 0;
7099 }
7100
7101 /* Check if field name ends with the ": " delimiter */
7102 ptr += strlen(hfinfo->name);
7103 if (strncmp(ptr, ": ", 2) == 0) {
7104 ptr += 2;
7105 }
7106
7107 /* Return offset to after field name */
7108 return ptr - representation;
7109}
7110
7111static size_t label_find_name_pos(const item_label_t *rep)
7112{
7113 size_t name_pos = 0;
7114
7115 /* If the value_pos is too small or too large, we can't find the expected format */
7116 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7117 return 0;
7118 }
7119
7120 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7121 if (rep->representation[rep->value_pos-2] == ':') {
7122 name_pos = rep->value_pos - 2;
7123 }
7124
7125 return name_pos;
7126}
7127
7128/* If the protocol tree is to be visible, set the representation of a
7129 proto_tree entry with the name of the field for the item and with
7130 the value formatted with the supplied printf-style format and
7131 argument list. */
7132static void
7133proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7134{
7135 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7135, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7136
7137 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7138 * items string representation */
7139 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7140 size_t name_pos, ret = 0;
7141 char *str;
7142 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7143 const header_field_info *hf;
7144
7145 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7145, "fi"))))
;
7146
7147 hf = fi->hfinfo;
7148
7149 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;
;
7150 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))
)) {
7151 uint64_t val;
7152 char *p;
7153
7154 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)
)
7155 val = fvalue_get_uinteger(fi->value);
7156 else
7157 val = fvalue_get_uinteger64(fi->value);
7158
7159 val <<= hfinfo_bitshift(hf);
7160
7161 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7162 ret = (p - fi->rep->representation);
7163 }
7164
7165 /* put in the hf name */
7166 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)
;
7167
7168 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7169 /* If possible, Put in the value of the string */
7170 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7171 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"
, 7171, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7172 fi->rep->value_pos = ret;
7173 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7174 if (ret >= ITEM_LABEL_LENGTH240) {
7175 /* Uh oh, we don't have enough room. Tell the user
7176 * that the field is truncated.
7177 */
7178 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7179 }
7180 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7181 }
7182}
7183
7184/* If the protocol tree is to be visible, set the representation of a
7185 proto_tree entry with the representation formatted with the supplied
7186 printf-style format and argument list. */
7187static void
7188proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7189{
7190 size_t ret; /*tmp return value */
7191 char *str;
7192 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7193
7194 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7194, "fi"))))
;
7195
7196 if (!proto_item_is_hidden(pi)) {
7197 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;
;
7198
7199 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7200 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"
, 7200, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7201 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7202 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7203 if (ret >= ITEM_LABEL_LENGTH240) {
7204 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7205 size_t name_pos = label_find_name_pos(fi->rep);
7206 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7207 }
7208 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7209 }
7210}
7211
7212static int
7213proto_strlcpy(char *dest, const char *src, size_t dest_size)
7214{
7215 if (dest_size == 0) return 0;
7216
7217 size_t res = g_strlcpy(dest, src, dest_size);
7218
7219 /* At most dest_size - 1 characters will be copied
7220 * (unless dest_size is 0). */
7221 if (res >= dest_size)
7222 res = dest_size - 1;
7223 return (int) res;
7224}
7225
7226static header_field_info *
7227hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7228{
7229 header_field_info *dup_hfinfo;
7230
7231 if (hfinfo->same_name_prev_id == -1)
7232 return NULL((void*)0);
7233 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", 7233
, __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", 7233, "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", 7233,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7234 return dup_hfinfo;
7235}
7236
7237static void
7238hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7239{
7240 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)
;
7241 last_field_name = NULL((void*)0);
7242
7243 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7244 /* No hfinfo with the same name */
7245 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7246 return;
7247 }
7248
7249 if (hfinfo->same_name_next) {
7250 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7251 }
7252
7253 if (hfinfo->same_name_prev_id != -1) {
7254 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7255 same_name_prev->same_name_next = hfinfo->same_name_next;
7256 if (!hfinfo->same_name_next) {
7257 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7258 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7259 }
7260 }
7261}
7262
7263int
7264proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7265{
7266 const header_field_info *hfinfo = finfo->hfinfo;
7267 int label_len = 0;
7268 char *tmp_str;
7269 const char *str;
7270 const uint8_t *bytes;
7271 uint32_t number;
7272 uint64_t number64;
7273 const char *hf_str_val;
7274 char number_buf[NUMBER_LABEL_LENGTH80];
7275 const char *number_out;
7276 address addr;
7277 const ipv4_addr_and_mask *ipv4;
7278 const ipv6_addr_and_prefix *ipv6;
7279
7280 switch (hfinfo->type) {
7281
7282 case FT_NONE:
7283 case FT_PROTOCOL:
7284 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7285
7286 case FT_UINT_BYTES:
7287 case FT_BYTES:
7288 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7289 hfinfo,
7290 fvalue_get_bytes_data(finfo->value),
7291 (unsigned)fvalue_length2(finfo->value),
7292 label_str_size);
7293 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7294 wmem_free(NULL((void*)0), tmp_str);
7295 break;
7296
7297 case FT_ABSOLUTE_TIME:
7298 {
7299 const nstime_t *value = fvalue_get_time(finfo->value);
7300 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7301 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7302 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7303 }
7304 if (hfinfo->strings) {
7305 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7306 if (time_string != NULL((void*)0)) {
7307 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7308 break;
7309 }
7310 }
7311 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7312 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7313 wmem_free(NULL((void*)0), tmp_str);
7314 break;
7315 }
7316
7317 case FT_RELATIVE_TIME:
7318 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7319 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7320 wmem_free(NULL((void*)0), tmp_str);
7321 break;
7322
7323 case FT_BOOLEAN:
7324 number64 = fvalue_get_uinteger64(finfo->value);
7325 label_len = proto_strlcpy(display_label_str,
7326 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7327 break;
7328
7329 case FT_CHAR:
7330 number = fvalue_get_uinteger(finfo->value);
7331
7332 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7333 char tmp[ITEM_LABEL_LENGTH240];
7334 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7335
7336 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7336, "fmtfunc"))))
;
7337 fmtfunc(tmp, number);
7338
7339 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7340
7341 } else if (hfinfo->strings) {
7342 number_out = hf_try_val_to_str(number, hfinfo);
7343
7344 if (!number_out) {
7345 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7346 }
7347
7348 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7349
7350 } else {
7351 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7352
7353 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7354 }
7355
7356 break;
7357
7358 /* XXX - make these just FT_NUMBER? */
7359 case FT_INT8:
7360 case FT_INT16:
7361 case FT_INT24:
7362 case FT_INT32:
7363 case FT_UINT8:
7364 case FT_UINT16:
7365 case FT_UINT24:
7366 case FT_UINT32:
7367 case FT_FRAMENUM:
7368 hf_str_val = NULL((void*)0);
7369 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
))
?
7370 (uint32_t) fvalue_get_sinteger(finfo->value) :
7371 fvalue_get_uinteger(finfo->value);
7372
7373 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7374 char tmp[ITEM_LABEL_LENGTH240];
7375 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7376
7377 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7377, "fmtfunc"))))
;
7378 fmtfunc(tmp, number);
7379
7380 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7381
7382 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7383 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7384 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7385 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7386 hf_str_val = hf_try_val_to_str(number, hfinfo);
7387 if (hf_str_val)
7388 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7389 } else {
7390 number_out = hf_try_val_to_str(number, hfinfo);
7391
7392 if (!number_out) {
7393 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7394 }
7395
7396 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7397 }
7398 } else {
7399 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7400
7401 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7402 }
7403
7404 break;
7405
7406 case FT_INT40:
7407 case FT_INT48:
7408 case FT_INT56:
7409 case FT_INT64:
7410 case FT_UINT40:
7411 case FT_UINT48:
7412 case FT_UINT56:
7413 case FT_UINT64:
7414 hf_str_val = NULL((void*)0);
7415 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
))
?
7416 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7417 fvalue_get_uinteger64(finfo->value);
7418
7419 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7420 char tmp[ITEM_LABEL_LENGTH240];
7421 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7422
7423 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7423, "fmtfunc64"
))))
;
7424 fmtfunc64(tmp, number64);
7425
7426 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7427 } else if (hfinfo->strings) {
7428 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7429 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7430 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7431 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7432 if (hf_str_val)
7433 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7434 } else {
7435 number_out = hf_try_val64_to_str(number64, hfinfo);
7436
7437 if (!number_out)
7438 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7439
7440 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7441 }
7442 } else {
7443 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7444
7445 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7446 }
7447
7448 break;
7449
7450 case FT_EUI64:
7451 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7452 tmp_str = address_to_display(NULL((void*)0), &addr);
7453 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7454 wmem_free(NULL((void*)0), tmp_str);
7455 break;
7456
7457 case FT_IPv4:
7458 ipv4 = fvalue_get_ipv4(finfo->value);
7459 //XXX: Should we ignore the mask?
7460 set_address_ipv4(&addr, ipv4);
7461 tmp_str = address_to_display(NULL((void*)0), &addr);
7462 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7463 wmem_free(NULL((void*)0), tmp_str);
7464 free_address(&addr);
7465 break;
7466
7467 case FT_IPv6:
7468 ipv6 = fvalue_get_ipv6(finfo->value);
7469 set_address_ipv6(&addr, ipv6);
7470 tmp_str = address_to_display(NULL((void*)0), &addr);
7471 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7472 wmem_free(NULL((void*)0), tmp_str);
7473 free_address(&addr);
7474 break;
7475
7476 case FT_FCWWN:
7477 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7478 tmp_str = address_to_display(NULL((void*)0), &addr);
7479 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7480 wmem_free(NULL((void*)0), tmp_str);
7481 break;
7482
7483 case FT_ETHER:
7484 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7485 tmp_str = address_to_display(NULL((void*)0), &addr);
7486 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7487 wmem_free(NULL((void*)0), tmp_str);
7488 break;
7489
7490 case FT_GUID:
7491 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7492 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7493 wmem_free(NULL((void*)0), tmp_str);
7494 break;
7495
7496 case FT_REL_OID:
7497 bytes = fvalue_get_bytes_data(finfo->value);
7498 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7499 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7500 wmem_free(NULL((void*)0), tmp_str);
7501 break;
7502
7503 case FT_OID:
7504 bytes = fvalue_get_bytes_data(finfo->value);
7505 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7506 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7507 wmem_free(NULL((void*)0), tmp_str);
7508 break;
7509
7510 case FT_SYSTEM_ID:
7511 bytes = fvalue_get_bytes_data(finfo->value);
7512 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7513 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7514 wmem_free(NULL((void*)0), tmp_str);
7515 break;
7516
7517 case FT_FLOAT:
7518 case FT_DOUBLE:
7519 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7520 break;
7521
7522 case FT_IEEE_11073_SFLOAT:
7523 case FT_IEEE_11073_FLOAT:
7524 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7525 break;
7526
7527 case FT_STRING:
7528 case FT_STRINGZ:
7529 case FT_UINT_STRING:
7530 case FT_STRINGZPAD:
7531 case FT_STRINGZTRUNC:
7532 str = fvalue_get_string(finfo->value);
7533 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7534 if (label_len >= label_str_size) {
7535 /* Truncation occurred. Get the real length
7536 * copied (not including '\0') */
7537 label_len = label_str_size ? label_str_size - 1 : 0;
7538 }
7539 break;
7540
7541 default:
7542 /* First try ftype string representation */
7543 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7544 if (!tmp_str) {
7545 /* Default to show as bytes */
7546 bytes = fvalue_get_bytes_data(finfo->value);
7547 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7548 }
7549 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7550 wmem_free(NULL((void*)0), tmp_str);
7551 break;
7552 }
7553 return label_len;
7554}
7555
7556const char *
7557proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7558 char *result, char *expr, const int size)
7559{
7560 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7561 GPtrArray *finfos;
7562 field_info *finfo = NULL((void*)0);
7563 header_field_info* hfinfo;
7564 const char *abbrev = NULL((void*)0);
7565
7566 char *str;
7567 col_custom_t *field_idx;
7568 int field_id;
7569 int ii = 0;
7570
7571 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7571, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7572 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7573 field_id = field_idx->field_id;
7574 if (field_id == 0) {
7575 GPtrArray *fvals = NULL((void*)0);
7576 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7577 if (fvals != NULL((void*)0)) {
7578
7579 // XXX - Handling occurrences is unusual when more
7580 // than one field is involved, e.g. there's four
7581 // results for tcp.port + tcp.port. We may really
7582 // want to apply it to the operands, not the output.
7583 // Note that occurrences are not quite the same as
7584 // the layer operator (should the grammar support
7585 // both?)
7586 /* Calculate single index or set outer boundaries */
7587 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7588 if (occurrence < 0) {
7589 i = occurrence + len;
7590 last = i;
7591 } else if (occurrence > 0) {
7592 i = occurrence - 1;
7593 last = i;
7594 } else {
7595 i = 0;
7596 last = len - 1;
7597 }
7598 if (i < 0 || i >= len) {
7599 g_ptr_array_unref(fvals);
7600 continue;
7601 }
7602 for (; i <= last; i++) {
7603 /* XXX - We could have a "resolved" result
7604 * for types where the value depends only
7605 * on the type, e.g. FT_IPv4, and not on
7606 * hfinfo->strings. Supporting the latter
7607 * requires knowing which hfinfo matched
7608 * if there are multiple with the same
7609 * abbreviation. In any case, we need to
7610 * know the expected return type of the
7611 * field expression.
7612 */
7613 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7614 if (offset_r && (offset_r < (size - 1)))
7615 result[offset_r++] = ',';
7616 if (offset_e && (offset_e < (size - 1)))
7617 expr[offset_e++] = ',';
7618 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7619 // col_{add,append,set}_* calls ws_label_strcpy
7620 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7621
7622 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7623 }
7624 g_ptr_array_unref(fvals);
7625 } else if (passed) {
7626 // XXX - Occurrence doesn't make sense for a test
7627 // output, it should be applied to the operands.
7628 if (offset_r && (offset_r < (size - 1)))
7629 result[offset_r++] = ',';
7630 if (offset_e && (offset_e < (size - 1)))
7631 expr[offset_e++] = ',';
7632 /* Prevent multiple check marks */
7633 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7634 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7635 } else {
7636 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7637 }
7638 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7639 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7640 } else {
7641 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7642 }
7643 }
7644 continue;
7645 }
7646 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", 7646
, __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", 7646,
"(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", 7646,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7647
7648 /* do we need to rewind ? */
7649 if (!hfinfo)
7650 return "";
7651
7652 if (occurrence < 0) {
7653 /* Search other direction */
7654 while (hfinfo->same_name_prev_id != -1) {
7655 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", 7655
, __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", 7655, "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", 7655,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7656 }
7657 }
7658
7659 prev_len = 0; /* Reset handled occurrences */
7660
7661 while (hfinfo) {
7662 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7663
7664 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7665 if (occurrence < 0) {
7666 hfinfo = hfinfo->same_name_next;
7667 } else {
7668 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7669 }
7670 continue;
7671 }
7672
7673 /* Are there enough occurrences of the field? */
7674 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7675 if (occurrence < 0) {
7676 hfinfo = hfinfo->same_name_next;
7677 } else {
7678 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7679 }
7680 prev_len += len;
7681 continue;
7682 }
7683
7684 /* Calculate single index or set outer boundaries */
7685 if (occurrence < 0) {
7686 i = occurrence + len + prev_len;
7687 last = i;
7688 } else if (occurrence > 0) {
7689 i = occurrence - 1 - prev_len;
7690 last = i;
7691 } else {
7692 i = 0;
7693 last = len - 1;
7694 }
7695
7696 prev_len += len; /* Count handled occurrences */
7697
7698 while (i <= last) {
7699 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7700
7701 if (offset_r && (offset_r < (size - 1)))
7702 result[offset_r++] = ',';
7703
7704 if (display_details) {
7705 char representation[ITEM_LABEL_LENGTH240];
7706 size_t offset = 0;
7707
7708 if (finfo->rep && finfo->rep->value_len) {
7709 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7710 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7711 } else {
7712 proto_item_fill_label(finfo, representation, &offset);
7713 }
7714 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7715 } else {
7716 switch (hfinfo->type) {
7717
7718 case FT_NONE:
7719 case FT_PROTOCOL:
7720 /* Prevent multiple check marks */
7721 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7722 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7723 } else {
7724 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7725 }
7726 break;
7727
7728 default:
7729 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7730 break;
7731 }
7732 }
7733
7734 if (offset_e && (offset_e < (size - 1)))
7735 expr[offset_e++] = ',';
7736
7737 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
))
)) {
7738 const char *hf_str_val;
7739 /* Integer types with BASE_NONE never get the numeric value. */
7740 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7741 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7742 } 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
)
) {
7743 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7744 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7745 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7746 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7747 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7748 }
7749 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7750 offset_e = (int)strlen(expr);
7751 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7752 /* Prevent multiple check marks */
7753 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7754 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7755 } else {
7756 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7757 }
7758 } else {
7759 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7760 // col_{add,append,set}_* calls ws_label_strcpy
7761 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7762 wmem_free(NULL((void*)0), str);
7763 }
7764 i++;
7765 }
7766
7767 /* XXX: Why is only the first abbreviation returned for a multifield
7768 * custom column? */
7769 if (!abbrev) {
7770 /* Store abbrev for return value */
7771 abbrev = hfinfo->abbrev;
7772 }
7773
7774 if (occurrence == 0) {
7775 /* Fetch next hfinfo with same name (abbrev) */
7776 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7777 } else {
7778 hfinfo = NULL((void*)0);
7779 }
7780 }
7781 }
7782
7783 if (offset_r >= (size - 1)) {
7784 mark_truncated(result, 0, size, NULL((void*)0));
7785 }
7786 if (offset_e >= (size - 1)) {
7787 mark_truncated(expr, 0, size, NULL((void*)0));
7788 }
7789 return abbrev ? abbrev : "";
7790}
7791
7792char *
7793proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7794{
7795 int len, prev_len, last, i;
7796 GPtrArray *finfos;
7797 field_info *finfo = NULL((void*)0);
7798 header_field_info* hfinfo;
7799
7800 char *filter = NULL((void*)0);
7801 GPtrArray *filter_array;
7802
7803 col_custom_t *col_custom;
7804 int field_id;
7805
7806 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7806, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7807 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7808 for (GSList *iter = field_ids; iter; iter = iter->next) {
7809 col_custom = (col_custom_t*)iter->data;
7810 field_id = col_custom->field_id;
7811 if (field_id == 0) {
7812 GPtrArray *fvals = NULL((void*)0);
7813 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7814 if (fvals != NULL((void*)0)) {
7815 // XXX - Handling occurrences is unusual when more
7816 // than one field is involved, e.g. there's four
7817 // results for tcp.port + tcp.port. We really
7818 // want to apply it to the operands, not the output.
7819 /* Calculate single index or set outer boundaries */
7820 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7821 if (occurrence < 0) {
7822 i = occurrence + len;
7823 last = i;
7824 } else if (occurrence > 0) {
7825 i = occurrence - 1;
7826 last = i;
7827 } else {
7828 i = 0;
7829 last = len - 1;
7830 }
7831 if (i < 0 || i >= len) {
7832 g_ptr_array_unref(fvals);
7833 continue;
7834 }
7835 for (; i <= last; i++) {
7836 /* XXX - Should multiple values for one
7837 * field use set membership to reduce
7838 * verbosity, here and below? */
7839 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7840 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7841 wmem_free(NULL((void*)0), str);
7842 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7843 g_ptr_array_add(filter_array, filter);
7844 }
7845 }
7846 g_ptr_array_unref(fvals);
7847 } else if (passed) {
7848 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7849 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7850 g_ptr_array_add(filter_array, filter);
7851 }
7852 } else {
7853 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7854 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7855 g_ptr_array_add(filter_array, filter);
7856 }
7857 }
7858 continue;
7859 }
7860
7861 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", 7861
, __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", 7861,
"(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", 7861,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7862
7863 /* do we need to rewind ? */
7864 if (!hfinfo)
7865 return NULL((void*)0);
7866
7867 if (occurrence < 0) {
7868 /* Search other direction */
7869 while (hfinfo->same_name_prev_id != -1) {
7870 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", 7870
, __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", 7870, "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", 7870,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7871 }
7872 }
7873
7874 prev_len = 0; /* Reset handled occurrences */
7875
7876 while (hfinfo) {
7877 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7878
7879 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7880 if (occurrence < 0) {
7881 hfinfo = hfinfo->same_name_next;
7882 } else {
7883 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7884 }
7885 continue;
7886 }
7887
7888 /* Are there enough occurrences of the field? */
7889 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7890 if (occurrence < 0) {
7891 hfinfo = hfinfo->same_name_next;
7892 } else {
7893 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7894 }
7895 prev_len += len;
7896 continue;
7897 }
7898
7899 /* Calculate single index or set outer boundaries */
7900 if (occurrence < 0) {
7901 i = occurrence + len + prev_len;
7902 last = i;
7903 } else if (occurrence > 0) {
7904 i = occurrence - 1 - prev_len;
7905 last = i;
7906 } else {
7907 i = 0;
7908 last = len - 1;
7909 }
7910
7911 prev_len += len; /* Count handled occurrences */
7912
7913 while (i <= last) {
7914 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7915
7916 filter = proto_construct_match_selected_string(finfo, edt);
7917 if (filter) {
7918 /* Only add the same expression once (especially for FT_PROTOCOL).
7919 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7920 */
7921 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7922 g_ptr_array_add(filter_array, filter);
7923 }
7924 }
7925 i++;
7926 }
7927
7928 if (occurrence == 0) {
7929 /* Fetch next hfinfo with same name (abbrev) */
7930 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7931 } else {
7932 hfinfo = NULL((void*)0);
7933 }
7934 }
7935 }
7936
7937 g_ptr_array_add(filter_array, NULL((void*)0));
7938
7939 /* XXX: Should this be || or && ? */
7940 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7941
7942 g_ptr_array_free(filter_array, true1);
7943
7944 return output;
7945}
7946
7947/* Set text of proto_item after having already been created. */
7948void
7949proto_item_set_text(proto_item *pi, const char *format, ...)
7950{
7951 field_info *fi = NULL((void*)0);
7952 va_list ap;
7953
7954 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7955
7956 fi = PITEM_FINFO(pi)((pi)->finfo);
7957 if (fi == NULL((void*)0))
7958 return;
7959
7960 if (fi->rep) {
7961 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7962 fi->rep = NULL((void*)0);
7963 }
7964
7965 va_start(ap, format)__builtin_va_start(ap, format);
7966 proto_tree_set_representation(pi, format, ap);
7967 va_end(ap)__builtin_va_end(ap);
7968}
7969
7970/* Append to text of proto_item after having already been created. */
7971void
7972proto_item_append_text(proto_item *pi, const char *format, ...)
7973{
7974 field_info *fi = NULL((void*)0);
7975 size_t curlen;
7976 char *str;
7977 va_list ap;
7978
7979 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7980
7981 fi = PITEM_FINFO(pi)((pi)->finfo);
7982 if (fi == NULL((void*)0)) {
7983 return;
7984 }
7985
7986 if (!proto_item_is_hidden(pi)) {
7987 /*
7988 * If we don't already have a representation,
7989 * generate the default representation.
7990 */
7991 if (fi->rep == NULL((void*)0)) {
7992 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;
;
7993 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7994 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7995 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7996 (strncmp(format, ": ", 2) == 0)) {
7997 fi->rep->value_pos += 2;
7998 }
7999 }
8000 if (fi->rep) {
8001 curlen = strlen(fi->rep->representation);
8002 /* curlen doesn't include the \0 byte.
8003 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8004 * the representation has already been truncated (of an up
8005 * to 4 byte UTF-8 character) or is just at the maximum length
8006 * unless we search for " [truncated]" (which may not be
8007 * at the start.)
8008 * It's safer to do nothing.
8009 */
8010 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8011 va_start(ap, format)__builtin_va_start(ap, format);
8012 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8013 va_end(ap)__builtin_va_end(ap);
8014 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"
, 8014, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8015 /* Keep fi->rep->value_pos */
8016 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8017 if (curlen >= ITEM_LABEL_LENGTH240) {
8018 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8019 size_t name_pos = label_find_name_pos(fi->rep);
8020 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8021 }
8022 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8023 }
8024 }
8025 }
8026}
8027
8028/* Prepend to text of proto_item after having already been created. */
8029void
8030proto_item_prepend_text(proto_item *pi, const char *format, ...)
8031{
8032 field_info *fi = NULL((void*)0);
8033 size_t pos;
8034 char representation[ITEM_LABEL_LENGTH240];
8035 char *str;
8036 va_list ap;
8037
8038 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8039
8040 fi = PITEM_FINFO(pi)((pi)->finfo);
8041 if (fi == NULL((void*)0)) {
8042 return;
8043 }
8044
8045 if (!proto_item_is_hidden(pi)) {
8046 /*
8047 * If we don't already have a representation,
8048 * generate the default representation.
8049 */
8050 if (fi->rep == NULL((void*)0)) {
8051 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;
;
8052 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8053 } else
8054 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8055
8056 va_start(ap, format)__builtin_va_start(ap, format);
8057 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8058 va_end(ap)__builtin_va_end(ap);
8059 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"
, 8059, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8060 fi->rep->value_pos += strlen(str);
8061 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8062 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8063 /* XXX: As above, if the old representation is close to the label
8064 * length, it might already be marked as truncated. */
8065 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8066 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8067 size_t name_pos = label_find_name_pos(fi->rep);
8068 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8069 }
8070 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8071 }
8072}
8073
8074static void
8075finfo_set_len(field_info *fi, const unsigned length)
8076{
8077 unsigned length_remaining;
8078
8079 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8080 if (length > length_remaining)
8081 fi->length = length_remaining;
8082 else
8083 fi->length = length;
8084
8085 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8086 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8087 fvalue_set_protocol_length(fi->value, fi->length);
8088 }
8089
8090 /*
8091 * You cannot just make the "len" field of a GByteArray
8092 * larger, if there's no data to back that length;
8093 * you can only make it smaller.
8094 */
8095 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8096 GBytes *bytes = fvalue_get_bytes(fi->value);
8097 size_t size;
8098 const void *data = g_bytes_get_data(bytes, &size);
8099 if ((size_t)fi->length <= size) {
8100 fvalue_set_bytes_data(fi->value, data, fi->length);
8101 }
8102 g_bytes_unref(bytes);
8103 }
8104}
8105
8106void
8107proto_item_set_len(proto_item *pi, const unsigned length)
8108{
8109 field_info *fi;
8110
8111 if (pi == NULL((void*)0))
8112 return;
8113
8114 fi = PITEM_FINFO(pi)((pi)->finfo);
8115 if (fi == NULL((void*)0))
8116 return;
8117
8118 finfo_set_len(fi, length);
8119}
8120
8121/*
8122 * Sets the length of the item based on its start and on the specified
8123 * offset, which is the offset past the end of the item; as the start
8124 * in the item is relative to the beginning of the data source tvbuff,
8125 * we need to pass in a tvbuff - the end offset is relative to the beginning
8126 * of that tvbuff.
8127 */
8128void
8129proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8130{
8131 field_info *fi;
8132 unsigned length;
8133
8134 if (pi == NULL((void*)0))
8135 return;
8136
8137 fi = PITEM_FINFO(pi)((pi)->finfo);
8138 if (fi == NULL((void*)0))
8139 return;
8140
8141 if (G_LIKELY(tvb)(tvb)) {
8142 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"
, 8142, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8143 end += tvb_raw_offset(tvb);
8144 } else {
8145 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", 8145, "((void*)0) == fi->ds_tvb"
))))
;
8146 }
8147 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8147, "end >= fi->start"
))))
;
8148 length = end - fi->start;
8149
8150 finfo_set_len(fi, length);
8151}
8152
8153unsigned
8154proto_item_get_len(const proto_item *pi)
8155{
8156 /* XXX - The only use case where this is really guaranteed to work is
8157 * increasing the length of an item (which has no effect if the item
8158 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8159 *
8160 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8161 *
8162 * Should there be a macro or function to do that, and possibly this
8163 * be deprecated? As a bonus, we could handle overflow.
8164 */
8165 field_info *fi;
8166
8167 if (!pi)
8168 return 0;
8169 fi = PITEM_FINFO(pi)((pi)->finfo);
8170 if (fi) {
8171 return fi->length;
8172 }
8173 return 0;
8174}
8175
8176void
8177proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8178 if (!ti) {
8179 return;
8180 }
8181 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)
;
8182 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)
;
8183}
8184
8185char *
8186proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8187{
8188 field_info *fi;
8189
8190 if (!pi)
8191 return wmem_strdup(scope, "");
8192 fi = PITEM_FINFO(pi)((pi)->finfo);
8193 if (!fi)
8194 return wmem_strdup(scope, "");
8195 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8195, "fi->hfinfo != ((void*)0)"
))))
;
8196 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8197}
8198
8199proto_tree *
8200proto_tree_create_root(packet_info *pinfo)
8201{
8202 proto_node *pnode;
8203
8204 /* Initialize the proto_node */
8205 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8206 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8207 pnode->parent = NULL((void*)0);
8208 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8209 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)))
;
8210
8211 /* Make sure we can access pinfo everywhere */
8212 pnode->tree_data->pinfo = pinfo;
8213
8214 /* Don't initialize the tree_data_t. Wait until we know we need it */
8215 pnode->tree_data->interesting_hfids = NULL((void*)0);
8216
8217 /* Set the default to false so it's easier to
8218 * find errors; if we expect to see the protocol tree
8219 * but for some reason the default 'visible' is not
8220 * changed, then we'll find out very quickly. */
8221 pnode->tree_data->visible = false0;
8222
8223 /* Make sure that we fake protocols (if possible) */
8224 pnode->tree_data->fake_protocols = true1;
8225
8226 /* Keep track of the number of children */
8227 pnode->tree_data->count = 0;
8228
8229 /* Initialize our loop checks */
8230 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8231 pnode->tree_data->max_start = 0;
8232 pnode->tree_data->start_idle_count = 0;
8233
8234 return (proto_tree *)pnode;
8235}
8236
8237
8238/* "prime" a proto_tree with a single hfid that a dfilter
8239 * is interested in. */
8240void
8241proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8242{
8243 header_field_info *hfinfo;
8244
8245 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", 8245, __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", 8245, "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", 8245, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8246 /* this field is referenced by a filter so increase the refcount.
8247 also increase the refcount for the parent, i.e the protocol.
8248 Don't increase the refcount if we're already printing the
8249 type, as that is a superset of direct reference.
8250 */
8251 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8252 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8253 }
8254 /* only increase the refcount if there is a parent.
8255 if this is a protocol and not a field then parent will be -1
8256 and there is no parent to add any refcounting for.
8257 */
8258 if (hfinfo->parent != -1) {
8259 header_field_info *parent_hfinfo;
8260 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", 8260
, __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", 8260,
"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", 8260,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8261
8262 /* Mark parent as indirectly referenced unless it is already directly
8263 * referenced, i.e. the user has specified the parent in a filter.
8264 */
8265 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8266 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8267 }
8268}
8269
8270/* "prime" a proto_tree with a single hfid that a dfilter
8271 * is interested in. */
8272void
8273proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8274{
8275 header_field_info *hfinfo;
8276
8277 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", 8277, __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", 8277, "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", 8277, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8278 /* this field is referenced by an (output) filter so increase the refcount.
8279 also increase the refcount for the parent, i.e the protocol.
8280 */
8281 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8282 /* only increase the refcount if there is a parent.
8283 if this is a protocol and not a field then parent will be -1
8284 and there is no parent to add any refcounting for.
8285 */
8286 if (hfinfo->parent != -1) {
8287 header_field_info *parent_hfinfo;
8288 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", 8288
, __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", 8288,
"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", 8288,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8289
8290 /* Mark parent as indirectly referenced unless it is already directly
8291 * referenced, i.e. the user has specified the parent in a filter.
8292 */
8293 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8294 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8295 }
8296}
8297
8298proto_tree *
8299proto_item_add_subtree(proto_item *pi, const int idx) {
8300 field_info *fi;
8301
8302 if (!pi)
8303 return NULL((void*)0);
8304
8305 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", 8305, "idx >= 0 && idx < num_tree_types"
))))
;
8306
8307 fi = PITEM_FINFO(pi)((pi)->finfo);
8308 if (!fi)
8309 return (proto_tree *)pi;
8310
8311 fi->tree_type = idx;
8312
8313 return (proto_tree *)pi;
8314}
8315
8316proto_tree *
8317proto_item_get_subtree(proto_item *pi) {
8318 field_info *fi;
8319
8320 if (!pi)
8321 return NULL((void*)0);
8322 fi = PITEM_FINFO(pi)((pi)->finfo);
8323 if ( (fi) && (fi->tree_type == -1) )
8324 return NULL((void*)0);
8325 return (proto_tree *)pi;
8326}
8327
8328proto_item *
8329proto_item_get_parent(const proto_item *ti) {
8330 if (!ti)
8331 return NULL((void*)0);
8332 return ti->parent;
8333}
8334
8335proto_item *
8336proto_item_get_parent_nth(proto_item *ti, int gen) {
8337 if (!ti)
8338 return NULL((void*)0);
8339 while (gen--) {
8340 ti = ti->parent;
8341 if (!ti)
8342 return NULL((void*)0);
8343 }
8344 return ti;
8345}
8346
8347
8348proto_item *
8349proto_tree_get_parent(proto_tree *tree) {
8350 if (!tree)
8351 return NULL((void*)0);
8352 return (proto_item *)tree;
8353}
8354
8355proto_tree *
8356proto_tree_get_parent_tree(proto_tree *tree) {
8357 if (!tree)
8358 return NULL((void*)0);
8359
8360 /* we're the root tree, there's no parent
8361 return ourselves so the caller has at least a tree to attach to */
8362 if (!tree->parent)
8363 return tree;
8364
8365 return (proto_tree *)tree->parent;
8366}
8367
8368proto_tree *
8369proto_tree_get_root(proto_tree *tree) {
8370 if (!tree)
8371 return NULL((void*)0);
8372 while (tree->parent) {
8373 tree = tree->parent;
8374 }
8375 return tree;
8376}
8377
8378void
8379proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8380 proto_item *item_to_move)
8381{
8382 /* This function doesn't generate any values. It only reorganizes the protocol tree
8383 * so we can bail out immediately if it isn't visible. */
8384 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8385 return;
8386
8387 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", 8387, "item_to_move->parent == tree"
))))
;
8388 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", 8388, "fixed_item->parent == tree"
))))
;
8389
8390 /*** cut item_to_move out ***/
8391
8392 /* is item_to_move the first? */
8393 if (tree->first_child == item_to_move) {
8394 /* simply change first child to next */
8395 tree->first_child = item_to_move->next;
8396
8397 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", 8397, "tree->last_child != item_to_move"
))))
;
8398 } else {
8399 proto_item *curr_item;
8400 /* find previous and change it's next */
8401 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8402 if (curr_item->next == item_to_move) {
8403 break;
8404 }
8405 }
8406
8407 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8407, "curr_item"
))))
;
8408
8409 curr_item->next = item_to_move->next;
8410
8411 /* fix last_child if required */
8412 if (tree->last_child == item_to_move) {
8413 tree->last_child = curr_item;
8414 }
8415 }
8416
8417 /*** insert to_move after fixed ***/
8418 item_to_move->next = fixed_item->next;
8419 fixed_item->next = item_to_move;
8420 if (tree->last_child == fixed_item) {
8421 tree->last_child = item_to_move;
8422 }
8423}
8424
8425void
8426proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8427 const unsigned length)
8428{
8429 field_info *fi;
8430
8431 if (tree == NULL((void*)0))
8432 return;
8433
8434 fi = PTREE_FINFO(tree)((tree)->finfo);
8435 if (fi == NULL((void*)0))
8436 return;
8437
8438 /* We don't store a separate data source tvb for the appendix, so
8439 * it must be from the same data source. (XXX - Are there any
8440 * situations where it makes sense to have an appendix from a
8441 * different data source?) */
8442 if (G_LIKELY(tvb)(tvb)) {
8443 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"
, 8443, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8444 start += tvb_raw_offset(tvb);
8445 } else {
8446 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", 8446, "((void*)0) == fi->ds_tvb"
))))
;
8447 }
8448
8449 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8450 * main body? */
8451
8452 fi->appendix_start = start;
8453 fi->appendix_length = length;
8454}
8455
8456static void
8457check_protocol_filter_name_or_fail(const char *filter_name)
8458{
8459 /* Require at least two characters. */
8460 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8461 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)
;
8462 }
8463
8464 if (proto_check_field_name(filter_name) != '\0') {
8465 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)
8466 " 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)
8467 " 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)
;
8468 }
8469
8470 /* Check that it doesn't match some very common numeric forms. */
8471 if (filter_name[0] == '0' &&
8472 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8473 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8474 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])
8475 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])
;
8476 }
8477
8478 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8479
8480 /* Check that it contains at least one letter. */
8481 bool_Bool have_letter = false0;
8482 for (const char *s = filter_name; *s != '\0'; s++) {
8483 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8484 have_letter = true1;
8485 break;
8486 }
8487 }
8488 if (!have_letter) {
8489 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)
8490 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8491 }
8492
8493 /* Check for reserved keywords. */
8494 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8495 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)
8496 " 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)
;
8497 }
8498}
8499
8500int
8501proto_register_protocol(const char *name, const char *short_name,
8502 const char *filter_name)
8503{
8504 protocol_t *protocol;
8505 header_field_info *hfinfo;
8506
8507 check_protocol_filter_name_or_fail(filter_name);
8508
8509 /*
8510 * Add this protocol to the list of known protocols;
8511 * the list is sorted by protocol short name.
8512 */
8513 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8514 protocol->name = name;
8515 protocol->short_name = short_name;
8516 protocol->filter_name = filter_name;
8517 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8518 protocol->is_enabled = true1; /* protocol is enabled by default */
8519 protocol->enabled_by_default = true1; /* see previous comment */
8520 protocol->can_toggle = true1;
8521 protocol->parent_proto_id = -1;
8522 protocol->heur_list = NULL((void*)0);
8523
8524 /* List will be sorted later by name, when all protocols completed registering */
8525 protocols = g_list_prepend(protocols, protocol);
8526 /*
8527 * Make sure there's not already a protocol with any of those
8528 * names. Crash if there is, as that's an error in the code
8529 * or an inappropriate plugin.
8530 * This situation has to be fixed to not register more than one
8531 * protocol with the same name.
8532 */
8533 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8534 /* ws_error will terminate the program */
8535 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)
8536 " 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)
;
8537 }
8538 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8539 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)
8540 " 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)
;
8541 }
8542 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8543 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)
8544 " 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)
;
8545 }
8546
8547 /* Here we allocate a new header_field_info struct */
8548 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8549 hfinfo->name = name;
8550 hfinfo->abbrev = filter_name;
8551 hfinfo->type = FT_PROTOCOL;
8552 hfinfo->display = BASE_NONE;
8553 hfinfo->strings = protocol;
8554 hfinfo->bitmask = 0;
8555 hfinfo->ref_type = HF_REF_TYPE_NONE;
8556 hfinfo->blurb = NULL((void*)0);
8557 hfinfo->parent = -1; /* This field differentiates protos and fields */
8558
8559 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8560 return protocol->proto_id;
8561}
8562
8563int
8564proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8565{
8566 protocol_t *protocol;
8567 header_field_info *hfinfo;
8568
8569 /*
8570 * Helper protocols don't need the strict rules as a "regular" protocol
8571 * Just register it in a list and make a hf_ field from it
8572 */
8573 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8574 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)
;
8575 }
8576
8577 if (parent_proto <= 0) {
8578 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)
8579 " 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)
;
8580 }
8581
8582 check_protocol_filter_name_or_fail(filter_name);
8583
8584 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8585 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8586 protocol->name = name;
8587 protocol->short_name = short_name;
8588 protocol->filter_name = filter_name;
8589 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8590
8591 /* Enabling and toggling is really determined by parent protocol,
8592 but provide default values here */
8593 protocol->is_enabled = true1;
8594 protocol->enabled_by_default = true1;
8595 protocol->can_toggle = true1;
8596
8597 protocol->parent_proto_id = parent_proto;
8598 protocol->heur_list = NULL((void*)0);
8599
8600 /* List will be sorted later by name, when all protocols completed registering */
8601 protocols = g_list_prepend(protocols, protocol);
8602
8603 /* Here we allocate a new header_field_info struct */
8604 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8605 hfinfo->name = name;
8606 hfinfo->abbrev = filter_name;
8607 hfinfo->type = field_type;
8608 hfinfo->display = BASE_NONE;
8609 if (field_type == FT_BYTES) {
8610 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8611 }
8612 hfinfo->strings = protocol;
8613 hfinfo->bitmask = 0;
8614 hfinfo->ref_type = HF_REF_TYPE_NONE;
8615 hfinfo->blurb = NULL((void*)0);
8616 hfinfo->parent = -1; /* This field differentiates protos and fields */
8617
8618 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8619 return protocol->proto_id;
8620}
8621
8622bool_Bool
8623proto_deregister_protocol(const char *short_name)
8624{
8625 protocol_t *protocol;
8626 header_field_info *hfinfo;
8627 int proto_id;
8628 unsigned i;
8629
8630 proto_id = proto_get_id_by_short_name(short_name);
8631 protocol = find_protocol_by_id(proto_id);
8632 if (protocol == NULL((void*)0))
8633 return false0;
8634
8635 g_hash_table_remove(proto_names, protocol->name);
8636 g_hash_table_remove(proto_short_names, (void *)short_name);
8637 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8638
8639 if (protocol->fields) {
8640 for (i = 0; i < protocol->fields->len; i++) {
8641 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8642 hfinfo_remove_from_gpa_name_map(hfinfo);
8643 expert_deregister_expertinfo(hfinfo->abbrev);
8644 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8645 }
8646 g_ptr_array_free(protocol->fields, true1);
8647 protocol->fields = NULL((void*)0);
8648 }
8649
8650 g_list_free(protocol->heur_list);
8651
8652 /* Remove this protocol from the list of known protocols */
8653 protocols = g_list_remove(protocols, protocol);
8654
8655 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8656 wmem_map_remove(gpa_name_map, protocol->filter_name);
8657
8658 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)
;
8659 last_field_name = NULL((void*)0);
8660
8661 return true1;
8662}
8663
8664void
8665proto_register_alias(const int proto_id, const char *alias_name)
8666{
8667 protocol_t *protocol;
8668
8669 protocol = find_protocol_by_id(proto_id);
8670 if (alias_name && protocol) {
8671 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8672 }
8673}
8674
8675/*
8676 * Routines to use to iterate over the protocols.
8677 * The argument passed to the iterator routines is an opaque cookie to
8678 * their callers; it's the GList pointer for the current element in
8679 * the list.
8680 * The ID of the protocol is returned, or -1 if there is no protocol.
8681 */
8682int
8683proto_get_first_protocol(void **cookie)
8684{
8685 protocol_t *protocol;
8686
8687 if (protocols == NULL((void*)0))
8688 return -1;
8689 *cookie = protocols;
8690 protocol = (protocol_t *)protocols->data;
8691 return protocol->proto_id;
8692}
8693
8694int
8695proto_get_data_protocol(void *cookie)
8696{
8697 GList *list_item = (GList *)cookie;
8698
8699 protocol_t *protocol = (protocol_t *)list_item->data;
8700 return protocol->proto_id;
8701}
8702
8703int
8704proto_get_next_protocol(void **cookie)
8705{
8706 GList *list_item = (GList *)*cookie;
8707 protocol_t *protocol;
8708
8709 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8710 if (list_item == NULL((void*)0))
8711 return -1;
8712 *cookie = list_item;
8713 protocol = (protocol_t *)list_item->data;
8714 return protocol->proto_id;
8715}
8716
8717header_field_info *
8718proto_get_first_protocol_field(const int proto_id, void **cookie)
8719{
8720 protocol_t *protocol = find_protocol_by_id(proto_id);
8721
8722 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8723 return NULL((void*)0);
8724
8725 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8726 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8727}
8728
8729header_field_info *
8730proto_get_next_protocol_field(const int proto_id, void **cookie)
8731{
8732 protocol_t *protocol = find_protocol_by_id(proto_id);
8733 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8734
8735 i++;
8736
8737 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8738 return NULL((void*)0);
8739
8740 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8741 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8742}
8743
8744protocol_t *
8745find_protocol_by_id(const int proto_id)
8746{
8747 header_field_info *hfinfo;
8748
8749 if (proto_id <= 0)
8750 return NULL((void*)0);
8751
8752 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", 8752, __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", 8752,
"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", 8752, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8753 if (hfinfo->type != FT_PROTOCOL) {
8754 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", 8754, "hfinfo->display & 0x00004000"
))))
;
8755 }
8756 return (protocol_t *)hfinfo->strings;
8757}
8758
8759int
8760proto_get_id(const protocol_t *protocol)
8761{
8762 return protocol->proto_id;
8763}
8764
8765bool_Bool
8766proto_name_already_registered(const char *name)
8767{
8768 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8768, "name", "No name present"))))
;
8769
8770 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8771 return true1;
8772 return false0;
8773}
8774
8775int
8776proto_get_id_by_filter_name(const char *filter_name)
8777{
8778 const protocol_t *protocol = NULL((void*)0);
8779
8780 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", 8780,
"filter_name", "No filter name present"))))
;
8781
8782 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8783
8784 if (protocol == NULL((void*)0))
8785 return -1;
8786 return protocol->proto_id;
8787}
8788
8789int
8790proto_get_id_by_short_name(const char *short_name)
8791{
8792 const protocol_t *protocol = NULL((void*)0);
8793
8794 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", 8794,
"short_name", "No short name present"))))
;
8795
8796 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8797
8798 if (protocol == NULL((void*)0))
8799 return -1;
8800 return protocol->proto_id;
8801}
8802
8803const char *
8804proto_get_protocol_name(const int proto_id)
8805{
8806 protocol_t *protocol;
8807
8808 protocol = find_protocol_by_id(proto_id);
8809
8810 if (protocol == NULL((void*)0))
8811 return NULL((void*)0);
8812 return protocol->name;
8813}
8814
8815const char *
8816proto_get_protocol_short_name(const protocol_t *protocol)
8817{
8818 if (protocol == NULL((void*)0))
8819 return "(none)";
8820 return protocol->short_name;
8821}
8822
8823const char *
8824proto_get_protocol_long_name(const protocol_t *protocol)
8825{
8826 if (protocol == NULL((void*)0))
8827 return "(none)";
8828 return protocol->name;
8829}
8830
8831const char *
8832proto_get_protocol_filter_name(const int proto_id)
8833{
8834 protocol_t *protocol;
8835
8836 protocol = find_protocol_by_id(proto_id);
8837 if (protocol == NULL((void*)0))
8838 return "(none)";
8839 return protocol->filter_name;
8840}
8841
8842void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8843{
8844 heur_dtbl_entry_t* heuristic_dissector;
8845
8846 if (protocol == NULL((void*)0))
8847 return;
8848
8849 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8850 if (heuristic_dissector != NULL((void*)0))
8851 {
8852 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8853 }
8854}
8855
8856void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8857{
8858 if (protocol == NULL((void*)0))
8859 return;
8860
8861 g_list_foreach(protocol->heur_list, func, user_data);
8862}
8863
8864void
8865proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8866 bool_Bool *is_tcp, bool_Bool *is_udp,
8867 bool_Bool *is_sctp, bool_Bool *is_tls,
8868 bool_Bool *is_rtp,
8869 bool_Bool *is_lte_rlc)
8870{
8871 wmem_list_frame_t *protos = wmem_list_head(layers);
8872 int proto_id;
8873 const char *proto_name;
8874
8875 /* Walk the list of a available protocols in the packet and
8876 attempt to find "major" ones. */
8877 /* It might make more sense to assemble and return a bitfield. */
8878 while (protos != NULL((void*)0))
8879 {
8880 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8881 proto_name = proto_get_protocol_filter_name(proto_id);
8882
8883 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8884 (!strcmp(proto_name, "ipv6")))) {
8885 *is_ip = true1;
8886 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8887 *is_tcp = true1;
8888 } else if (is_udp && !strcmp(proto_name, "udp")) {
8889 *is_udp = true1;
8890 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8891 *is_sctp = true1;
8892 } else if (is_tls && !strcmp(proto_name, "tls")) {
8893 *is_tls = true1;
8894 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8895 *is_rtp = true1;
8896 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8897 *is_lte_rlc = true1;
8898 }
8899
8900 protos = wmem_list_frame_next(protos);
8901 }
8902}
8903
8904bool_Bool
8905proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8906{
8907 wmem_list_frame_t *protos = wmem_list_head(layers);
8908 int proto_id;
8909 const char *name;
8910
8911 /* Walk the list of a available protocols in the packet and
8912 attempt to find the specified protocol. */
8913 while (protos != NULL((void*)0))
8914 {
8915 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8916 name = proto_get_protocol_filter_name(proto_id);
8917
8918 if (!strcmp(name, proto_name))
8919 {
8920 return true1;
8921 }
8922
8923 protos = wmem_list_frame_next(protos);
8924 }
8925
8926 return false0;
8927}
8928
8929char *
8930proto_list_layers(const packet_info *pinfo)
8931{
8932 wmem_strbuf_t *buf;
8933 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8934
8935 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8936
8937 /* Walk the list of layers in the packet and
8938 return a string of all entries. */
8939 while (layers != NULL((void*)0))
8940 {
8941 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8942
8943 layers = wmem_list_frame_next(layers);
8944 if (layers != NULL((void*)0)) {
8945 wmem_strbuf_append_c(buf, ':');
8946 }
8947 }
8948
8949 return wmem_strbuf_finalize(buf);
8950}
8951
8952uint8_t
8953proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8954{
8955 int *proto_layer_num_ptr;
8956
8957 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8958 if (proto_layer_num_ptr == NULL((void*)0)) {
8959 return 0;
8960 }
8961
8962 return (uint8_t)*proto_layer_num_ptr;
8963}
8964
8965bool_Bool
8966proto_is_pino(const protocol_t *protocol)
8967{
8968 return (protocol->parent_proto_id != -1);
8969}
8970
8971bool_Bool
8972// NOLINTNEXTLINE(misc-no-recursion)
8973proto_is_protocol_enabled(const protocol_t *protocol)
8974{
8975 if (protocol == NULL((void*)0))
8976 return false0;
8977
8978 //parent protocol determines enable/disable for helper dissectors
8979 if (proto_is_pino(protocol))
8980 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8981
8982 return protocol->is_enabled;
8983}
8984
8985bool_Bool
8986// NOLINTNEXTLINE(misc-no-recursion)
8987proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8988{
8989 //parent protocol determines enable/disable for helper dissectors
8990 if (proto_is_pino(protocol))
8991 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8992
8993 return protocol->enabled_by_default;
8994}
8995
8996bool_Bool
8997// NOLINTNEXTLINE(misc-no-recursion)
8998proto_can_toggle_protocol(const int proto_id)
8999{
9000 protocol_t *protocol;
9001
9002 protocol = find_protocol_by_id(proto_id);
9003 //parent protocol determines toggling for helper dissectors
9004 if (proto_is_pino(protocol))
9005 return proto_can_toggle_protocol(protocol->parent_proto_id);
9006
9007 return protocol->can_toggle;
9008}
9009
9010void
9011proto_disable_by_default(const int proto_id)
9012{
9013 protocol_t *protocol;
9014
9015 protocol = find_protocol_by_id(proto_id);
9016 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9016, "protocol->can_toggle"
))))
;
9017 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", 9017, "proto_is_pino(protocol) == 0"
))))
;
9018 protocol->is_enabled = false0;
9019 protocol->enabled_by_default = false0;
9020}
9021
9022void
9023proto_set_decoding(const int proto_id, const bool_Bool enabled)
9024{
9025 protocol_t *protocol;
9026
9027 protocol = find_protocol_by_id(proto_id);
9028 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9028, "protocol->can_toggle"
))))
;
9029 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", 9029, "proto_is_pino(protocol) == 0"
))))
;
9030 protocol->is_enabled = enabled;
9031}
9032
9033void
9034proto_disable_all(void)
9035{
9036 /* This doesn't explicitly disable heuristic protocols,
9037 * but the heuristic doesn't get called if the parent
9038 * protocol isn't enabled.
9039 */
9040 protocol_t *protocol;
9041 GList *list_item = protocols;
9042
9043 if (protocols == NULL((void*)0))
9044 return;
9045
9046 while (list_item) {
9047 protocol = (protocol_t *)list_item->data;
9048 if (protocol->can_toggle) {
9049 protocol->is_enabled = false0;
9050 }
9051 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9052 }
9053}
9054
9055static void
9056heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9057{
9058 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9059
9060 heur->enabled = heur->enabled_by_default;
9061}
9062
9063void
9064proto_reenable_all(void)
9065{
9066 protocol_t *protocol;
9067 GList *list_item = protocols;
9068
9069 if (protocols == NULL((void*)0))
9070 return;
9071
9072 while (list_item) {
9073 protocol = (protocol_t *)list_item->data;
9074 if (protocol->can_toggle)
9075 protocol->is_enabled = protocol->enabled_by_default;
9076 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9077 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9078 }
9079}
9080
9081void
9082proto_set_cant_toggle(const int proto_id)
9083{
9084 protocol_t *protocol;
9085
9086 protocol = find_protocol_by_id(proto_id);
9087 protocol->can_toggle = false0;
9088}
9089
9090static int
9091proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9092{
9093 g_ptr_array_add(proto->fields, hfi);
9094
9095 return proto_register_field_init(hfi, parent);
9096}
9097
9098/* for use with static arrays only, since we don't allocate our own copies
9099of the header_field_info struct contained within the hf_register_info struct */
9100void
9101proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9102{
9103 hf_register_info *ptr = hf;
9104 protocol_t *proto;
9105 int i;
9106
9107 proto = find_protocol_by_id(parent);
9108
9109 /* if (proto == NULL) - error or return? */
9110
9111 if (proto->fields == NULL((void*)0)) {
9112 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9113 * GLib introduced g_ptr_array_new_from_array, which might have
9114 * given a reason to actually use it. (#17774)
9115 */
9116 proto->fields = g_ptr_array_sized_new(num_records);
9117 }
9118
9119 for (i = 0; i < num_records; i++, ptr++) {
9120 /*
9121 * Make sure we haven't registered this yet.
9122 * Most fields have variables associated with them that
9123 * are initialized to 0; some are initialized to -1 (which
9124 * was the standard before 4.4).
9125 *
9126 * XXX - Since this is called almost 300000 times at startup,
9127 * it might be nice to compare to only 0 and require
9128 * dissectors to pass in zero for unregistered fields.
9129 */
9130 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9131 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9132 "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)
9133 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9134 return;
9135 }
9136
9137 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9138 }
9139}
9140
9141/* deregister already registered fields */
9142void
9143proto_deregister_field (const int parent, int hf_id)
9144{
9145 header_field_info *hfi;
9146 protocol_t *proto;
9147 unsigned i;
9148
9149 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)
;
9150 last_field_name = NULL((void*)0);
9151
9152 if (hf_id == -1 || hf_id == 0)
9153 return;
9154
9155 proto = find_protocol_by_id (parent);
9156 if (!proto || proto->fields == NULL((void*)0)) {
9157 return;
9158 }
9159
9160 for (i = 0; i < proto->fields->len; i++) {
9161 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9162 if (hfi->id == hf_id) {
9163 /* Found the hf_id in this protocol */
9164 wmem_map_remove(gpa_name_map, hfi->abbrev);
9165 g_ptr_array_remove_index_fast(proto->fields, i);
9166 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9167 return;
9168 }
9169 }
9170}
9171
9172/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9173void
9174proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9175{
9176 header_field_info *hfinfo;
9177 protocol_t *proto;
9178
9179 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)
;
9180 last_field_name = NULL((void*)0);
9181
9182 proto = find_protocol_by_id(parent);
9183 if (proto && proto->fields && proto->fields->len > 0) {
9184 unsigned i = proto->fields->len;
9185 do {
9186 i--;
9187
9188 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9189 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) )
) {
9190 hfinfo_remove_from_gpa_name_map(hfinfo);
9191 expert_deregister_expertinfo(hfinfo->abbrev);
9192 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9193 g_ptr_array_remove_index_fast(proto->fields, i);
9194 }
9195 } while (i > 0);
9196 }
9197}
9198
9199void
9200proto_add_deregistered_data (void *data)
9201{
9202 g_ptr_array_add(deregistered_data, data);
9203}
9204
9205void
9206proto_add_deregistered_slice (size_t block_size, void *mem_block)
9207{
9208 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)))
;
9209
9210 slice_data->block_size = block_size;
9211 slice_data->mem_block = mem_block;
9212
9213 g_ptr_array_add(deregistered_slice, slice_data);
9214}
9215
9216void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9217{
9218 if (field_strings == NULL((void*)0)) {
9219 return;
9220 }
9221
9222 switch (field_type) {
9223 case FT_FRAMENUM:
9224 /* This is just an integer represented as a pointer */
9225 break;
9226 case FT_PROTOCOL: {
9227 protocol_t *protocol = (protocol_t *)field_strings;
9228 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)
;
9229 break;
9230 }
9231 case FT_BOOLEAN: {
9232 true_false_string *tf = (true_false_string *)field_strings;
9233 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)
;
9234 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)
;
9235 break;
9236 }
9237 case FT_UINT40:
9238 case FT_INT40:
9239 case FT_UINT48:
9240 case FT_INT48:
9241 case FT_UINT56:
9242 case FT_INT56:
9243 case FT_UINT64:
9244 case FT_INT64: {
9245 if (field_display & BASE_UNIT_STRING0x00001000) {
9246 unit_name_string *unit = (unit_name_string *)field_strings;
9247 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)
;
9248 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)
;
9249 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9250 range_string *rs = (range_string *)field_strings;
9251 while (rs->strptr) {
9252 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
)
;
9253 rs++;
9254 }
9255 } else if (field_display & BASE_EXT_STRING0x00000200) {
9256 val64_string_ext *vse = (val64_string_ext *)field_strings;
9257 val64_string *vs = (val64_string *)vse->_vs_p;
9258 while (vs->strptr) {
9259 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
)
;
9260 vs++;
9261 }
9262 val64_string_ext_free(vse);
9263 field_strings = NULL((void*)0);
9264 } else if (field_display == BASE_CUSTOM) {
9265 /* this will be a pointer to a function, don't free that */
9266 field_strings = NULL((void*)0);
9267 } else {
9268 val64_string *vs64 = (val64_string *)field_strings;
9269 while (vs64->strptr) {
9270 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)
;
9271 vs64++;
9272 }
9273 }
9274 break;
9275 }
9276 case FT_CHAR:
9277 case FT_UINT8:
9278 case FT_INT8:
9279 case FT_UINT16:
9280 case FT_INT16:
9281 case FT_UINT24:
9282 case FT_INT24:
9283 case FT_UINT32:
9284 case FT_INT32:
9285 case FT_FLOAT:
9286 case FT_DOUBLE: {
9287 if (field_display & BASE_UNIT_STRING0x00001000) {
9288 unit_name_string *unit = (unit_name_string *)field_strings;
9289 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)
;
9290 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)
;
9291 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9292 range_string *rs = (range_string *)field_strings;
9293 while (rs->strptr) {
9294 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
)
;
9295 rs++;
9296 }
9297 } else if (field_display & BASE_EXT_STRING0x00000200) {
9298 value_string_ext *vse = (value_string_ext *)field_strings;
9299 value_string *vs = (value_string *)vse->_vs_p;
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 value_string_ext_free(vse);
9305 field_strings = NULL((void*)0);
9306 } else if (field_display == BASE_CUSTOM) {
9307 /* this will be a pointer to a function, don't free that */
9308 field_strings = NULL((void*)0);
9309 } else {
9310 value_string *vs = (value_string *)field_strings;
9311 while (vs->strptr) {
9312 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
)
;
9313 vs++;
9314 }
9315 }
9316 break;
9317 default:
9318 break;
9319 }
9320 }
9321
9322 if (field_type != FT_FRAMENUM) {
9323 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
)
;
9324 }
9325}
9326
9327static void
9328free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9329{
9330 header_field_info *hfi = (header_field_info *) data;
9331 int hf_id = hfi->id;
9332
9333 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
)
;
9334 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
)
;
9335 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
)
;
9336
9337 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9338
9339 if (hfi->parent == -1)
9340 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)
;
9341
9342 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9343}
9344
9345static void
9346free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9347{
9348 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9349}
9350
9351static void
9352free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9353{
9354 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9355
9356 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9357 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)
;
9358}
9359
9360/* free deregistered fields and data */
9361void
9362proto_free_deregistered_fields (void)
9363{
9364 expert_free_deregistered_expertinfos();
9365
9366 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9367 g_ptr_array_free(deregistered_fields, true1);
9368 deregistered_fields = g_ptr_array_new();
9369
9370 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9371 g_ptr_array_free(deregistered_data, true1);
9372 deregistered_data = g_ptr_array_new();
9373
9374 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9375 g_ptr_array_free(deregistered_slice, true1);
9376 deregistered_slice = g_ptr_array_new();
9377}
9378
9379static const value_string hf_display[] = {
9380 { BASE_NONE, "BASE_NONE" },
9381 { BASE_DEC, "BASE_DEC" },
9382 { BASE_HEX, "BASE_HEX" },
9383 { BASE_OCT, "BASE_OCT" },
9384 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9385 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9386 { BASE_CUSTOM, "BASE_CUSTOM" },
9387 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9388 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9389 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9390 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9391 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9392 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9393 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9394 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9395 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9396 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9397 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9398 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9399 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9400 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9401 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9402 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9403 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9404 { BASE_PT_UDP, "BASE_PT_UDP" },
9405 { BASE_PT_TCP, "BASE_PT_TCP" },
9406 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9407 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9408 { BASE_OUI, "BASE_OUI" },
9409 { 0, NULL((void*)0) } };
9410
9411const char* proto_field_display_to_string(int field_display)
9412{
9413 return val_to_str_const(field_display, hf_display, "Unknown");
9414}
9415
9416static inline port_type
9417display_to_port_type(field_display_e e)
9418{
9419 switch (e) {
9420 case BASE_PT_UDP:
9421 return PT_UDP;
9422 case BASE_PT_TCP:
9423 return PT_TCP;
9424 case BASE_PT_DCCP:
9425 return PT_DCCP;
9426 case BASE_PT_SCTP:
9427 return PT_SCTP;
9428 default:
9429 break;
9430 }
9431 return PT_NONE;
9432}
9433
9434/* temporary function containing assert part for easier profiling */
9435static void
9436tmp_fld_check_assert(header_field_info *hfinfo)
9437{
9438 char* tmp_str;
9439
9440 /* The field must have a name (with length > 0) */
9441 if (!hfinfo->name || !hfinfo->name[0]) {
9442 if (hfinfo->abbrev)
9443 /* Try to identify the field */
9444 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)
9445 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9446 else
9447 /* Hum, no luck */
9448 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)"
)
;
9449 }
9450
9451 /* fields with an empty string for an abbreviation aren't filterable */
9452 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9453 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)
;
9454
9455 /* TODO: This check is a significant percentage of startup time (~10%),
9456 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9457 It might be nice to have a way to disable this check when, e.g.,
9458 running TShark many times with the same configuration. */
9459 /* Check that the filter name (abbreviation) is legal;
9460 * it must contain only alphanumerics, '-', "_", and ".". */
9461 unsigned char c;
9462 c = module_check_valid_name(hfinfo->abbrev, false0);
9463 if (c) {
9464 if (c == '.') {
9465 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)
;
9466 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9467 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)
;
9468 } else {
9469 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)
;
9470 }
9471 }
9472
9473 /* These types of fields are allowed to have value_strings,
9474 * true_false_strings or a protocol_t struct
9475 */
9476 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9477 switch (hfinfo->type) {
9478
9479 /*
9480 * These types are allowed to support display value_strings,
9481 * value64_strings, the extended versions of the previous
9482 * two, range strings, or unit strings.
9483 */
9484 case FT_CHAR:
9485 case FT_UINT8:
9486 case FT_UINT16:
9487 case FT_UINT24:
9488 case FT_UINT32:
9489 case FT_UINT40:
9490 case FT_UINT48:
9491 case FT_UINT56:
9492 case FT_UINT64:
9493 case FT_INT8:
9494 case FT_INT16:
9495 case FT_INT24:
9496 case FT_INT32:
9497 case FT_INT40:
9498 case FT_INT48:
9499 case FT_INT56:
9500 case FT_INT64:
9501 case FT_BOOLEAN:
9502 case FT_PROTOCOL:
9503 break;
9504
9505 /*
9506 * This is allowed to have a value of type
9507 * enum ft_framenum_type to indicate what relationship
9508 * the frame in question has to the frame in which
9509 * the field is put.
9510 */
9511 case FT_FRAMENUM:
9512 break;
9513
9514 /*
9515 * These types are allowed to support only unit strings.
9516 */
9517 case FT_FLOAT:
9518 case FT_DOUBLE:
9519 case FT_IEEE_11073_SFLOAT:
9520 case FT_IEEE_11073_FLOAT:
9521 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9522 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))
9523 " (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))
9524 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))
;
9525 }
9526 break;
9527
9528 /*
9529 * These types are allowed to support display
9530 * time_value_strings.
9531 */
9532 case FT_ABSOLUTE_TIME:
9533 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9534 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9535 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9536 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9537 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))
9538 " (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))
9539 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))
;
9540 }
9541 break;
9542
9543 /*
9544 * This type is only allowed to support a string if it's
9545 * a protocol (for pinos).
9546 */
9547 case FT_BYTES:
9548 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9549 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))
9550 " (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))
9551 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))
;
9552 }
9553 break;
9554
9555 default:
9556 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))
9557 " (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))
9558 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))
;
9559 }
9560 }
9561
9562 /* TODO: This check may slow down startup, and output quite a few warnings.
9563 It would be good to be able to enable this (and possibly other checks?)
9564 in non-release builds. */
9565#ifdef ENABLE_CHECK_FILTER
9566 /* Check for duplicate value_string values.
9567 There are lots that have the same value *and* string, so for now only
9568 report those that have same value but different string. */
9569 if ((hfinfo->strings != NULL((void*)0)) &&
9570 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9571 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9572 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9573 (
9574 (hfinfo->type == FT_CHAR) ||
9575 (hfinfo->type == FT_UINT8) ||
9576 (hfinfo->type == FT_UINT16) ||
9577 (hfinfo->type == FT_UINT24) ||
9578 (hfinfo->type == FT_UINT32) ||
9579 (hfinfo->type == FT_INT8) ||
9580 (hfinfo->type == FT_INT16) ||
9581 (hfinfo->type == FT_INT24) ||
9582 (hfinfo->type == FT_INT32) )) {
9583
9584 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9585 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9586 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9587 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9588 } else {
9589 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9590 CHECK_HF_VALUE(value_string, "u", start_values);
9591 }
9592 } else {
9593 const value_string *start_values = (const value_string*)hfinfo->strings;
9594 CHECK_HF_VALUE(value_string, "u", start_values);
9595 }
9596 }
9597
9598 if (hfinfo->type == FT_BOOLEAN) {
9599 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9600 if (tfs) {
9601 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9602 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9604
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9603 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9604
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9604 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9604
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9605 }
9606 }
9607 }
9608
9609 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9610 const range_string *rs = (const range_string*)(hfinfo->strings);
9611 if (rs) {
9612 const range_string *this_it = rs;
9613
9614 do {
9615 if (this_it->value_max < this_it->value_min) {
9616 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"
, 9620, __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)
9617 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9620, __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)
9618 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9620, __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)
9619 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9620, __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)
9620 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9620, __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)
;
9621 ++this_it;
9622 continue;
9623 }
9624
9625 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9626 /* Not OK if this one is completely hidden by an earlier one! */
9627 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9628 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"
, 9634, __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)
9629 "(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"
, 9634, __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)
9630 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9634, __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)
9631 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9634, __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)
9632 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9634, __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)
9633 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9634, __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)
9634 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9634, __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)
;
9635 }
9636 }
9637 ++this_it;
9638 } while (this_it->strptr);
9639 }
9640 }
9641#endif
9642
9643 switch (hfinfo->type) {
9644
9645 case FT_CHAR:
9646 /* Require the char type to have BASE_HEX, BASE_OCT,
9647 * BASE_CUSTOM, or BASE_NONE as its base.
9648 *
9649 * If the display value is BASE_NONE and there is a
9650 * strings conversion then the dissector writer is
9651 * telling us that the field's numerical value is
9652 * meaningless; we'll avoid showing the value to the
9653 * user.
9654 */
9655 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9656 case BASE_HEX:
9657 case BASE_OCT:
9658 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9659 break;
9660 case BASE_NONE:
9661 if (hfinfo->strings == NULL((void*)0))
9662 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
))
9663 " 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
))
9664 " 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
))
9665 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
))
9666 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
))
;
9667 break;
9668 default:
9669 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9670 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)
9671 " 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)
9672 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)
9673 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)
;
9674 //wmem_free(NULL, tmp_str);
9675 }
9676 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9677 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
))
9678 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
))
9679 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
))
;
9680 }
9681 break;
9682 case FT_INT8:
9683 case FT_INT16:
9684 case FT_INT24:
9685 case FT_INT32:
9686 case FT_INT40:
9687 case FT_INT48:
9688 case FT_INT56:
9689 case FT_INT64:
9690 /* Hexadecimal and octal are, in printf() and everywhere
9691 * else, unsigned so don't allow dissectors to register a
9692 * signed field to be displayed unsigned. (Else how would
9693 * we display negative values?)
9694 */
9695 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9696 case BASE_HEX:
9697 case BASE_OCT:
9698 case BASE_DEC_HEX:
9699 case BASE_HEX_DEC:
9700 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9701 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)
9702 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)
9703 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)
;
9704 //wmem_free(NULL, tmp_str);
9705 }
9706 /* FALL THROUGH */
9707 case FT_UINT8:
9708 case FT_UINT16:
9709 case FT_UINT24:
9710 case FT_UINT32:
9711 case FT_UINT40:
9712 case FT_UINT48:
9713 case FT_UINT56:
9714 case FT_UINT64:
9715 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
))
) {
9716 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9717 if (hfinfo->type != FT_UINT16) {
9718 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))
9719 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))
9720 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))
;
9721 }
9722 if (hfinfo->strings != NULL((void*)0)) {
9723 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)
9724 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)
9725 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)
;
9726 }
9727 if (hfinfo->bitmask != 0) {
9728 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)
9729 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)
9730 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)
;
9731 }
9732 wmem_free(NULL((void*)0), tmp_str);
9733 break;
9734 }
9735
9736 if (hfinfo->display == BASE_OUI) {
9737 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9738 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) {
9739 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))
9740 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))
9741 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))
;
9742 }
9743 if (hfinfo->strings != NULL((void*)0)) {
9744 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)
9745 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)
9746 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)
;
9747 }
9748 /* It can be a FT_UINT24 with a 0 bitmask, or
9749 * larger with a bitmask with 24 bits set. */
9750 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9751 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)
9752 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)
9753 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)
;
9754 }
9755 wmem_free(NULL((void*)0), tmp_str);
9756 break;
9757 }
9758
9759 /* Require integral types (other than frame number,
9760 * which is always displayed in decimal) to have a
9761 * number base.
9762 *
9763 * If the display value is BASE_NONE and there is a
9764 * strings conversion then the dissector writer is
9765 * telling us that the field's numerical value is
9766 * meaningless; we'll avoid showing the value to the
9767 * user.
9768 */
9769 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9770 case BASE_DEC:
9771 case BASE_HEX:
9772 case BASE_OCT:
9773 case BASE_DEC_HEX:
9774 case BASE_HEX_DEC:
9775 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9776 break;
9777 case BASE_NONE:
9778 if (hfinfo->strings == NULL((void*)0)) {
9779 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
))
9780 " 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
))
9781 " 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
))
9782 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
))
9783 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
))
;
9784 }
9785 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9786 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
))
9787 " 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
))
9788 " 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
))
9789 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
))
9790 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
))
;
9791 }
9792 break;
9793
9794 default:
9795 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9796 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)
9797 " 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)
9798 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)
9799 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)
;
9800 //wmem_free(NULL, tmp_str);
9801 }
9802 break;
9803 case FT_BYTES:
9804 case FT_UINT_BYTES:
9805 /* Require bytes to have a "display type" that could
9806 * add a character between displayed bytes.
9807 */
9808 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9809 case BASE_NONE:
9810 case SEP_DOT:
9811 case SEP_DASH:
9812 case SEP_COLON:
9813 case SEP_SPACE:
9814 break;
9815 default:
9816 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9817 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)
9818 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)
;
9819 //wmem_free(NULL, tmp_str);
9820 }
9821 if (hfinfo->bitmask != 0)
9822 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
))
9823 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
))
9824 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
))
;
9825 //allowed to support string if its a protocol (for pinos)
9826 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9827 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
))
9828 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
))
9829 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
))
;
9830 break;
9831
9832 case FT_PROTOCOL:
9833 case FT_FRAMENUM:
9834 if (hfinfo->display != BASE_NONE) {
9835 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9836 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)
9837 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)
9838 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)
;
9839 //wmem_free(NULL, tmp_str);
9840 }
9841 if (hfinfo->bitmask != 0)
9842 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
))
9843 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
))
9844 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
))
;
9845 break;
9846
9847 case FT_BOOLEAN:
9848 break;
9849
9850 case FT_ABSOLUTE_TIME:
9851 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9852 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9853 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)
9854 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)
;
9855 //wmem_free(NULL, tmp_str);
9856 }
9857 if (hfinfo->bitmask != 0)
9858 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
))
9859 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
))
9860 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
))
;
9861 break;
9862
9863 case FT_STRING:
9864 case FT_STRINGZ:
9865 case FT_UINT_STRING:
9866 case FT_STRINGZPAD:
9867 case FT_STRINGZTRUNC:
9868 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9869 case BASE_NONE:
9870 case BASE_STR_WSP:
9871 break;
9872
9873 default:
9874 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9875 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)
9876 " 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)
9877 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)
9878 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)
;
9879 //wmem_free(NULL, tmp_str);
9880 }
9881
9882 if (hfinfo->bitmask != 0)
9883 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
))
9884 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
))
9885 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
))
;
9886 if (hfinfo->strings != NULL((void*)0))
9887 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
))
9888 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
))
9889 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
))
;
9890 break;
9891
9892 case FT_IPv4:
9893 switch (hfinfo->display) {
9894 case BASE_NONE:
9895 case BASE_NETMASK:
9896 break;
9897
9898 default:
9899 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9900 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)
9901 " 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)
9902 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)
9903 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)
;
9904 //wmem_free(NULL, tmp_str);
9905 break;
9906 }
9907 break;
9908 case FT_FLOAT:
9909 case FT_DOUBLE:
9910 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9911 case BASE_NONE:
9912 case BASE_DEC:
9913 case BASE_HEX:
9914 case BASE_EXP:
9915 case BASE_CUSTOM:
9916 break;
9917 default:
9918 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9919 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)
9920 " 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)
9921 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)
9922 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)
;
9923 //wmem_free(NULL, tmp_str);
9924 }
9925 if (hfinfo->bitmask != 0)
9926 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
))
9927 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
))
9928 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
))
;
9929 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9930 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
))
9931 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
))
9932 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
))
;
9933 break;
9934 case FT_IEEE_11073_SFLOAT:
9935 case FT_IEEE_11073_FLOAT:
9936 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9937 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9938 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)
9939 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)
9940 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)
9941 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)
;
9942 //wmem_free(NULL, tmp_str);
9943 }
9944 if (hfinfo->bitmask != 0)
9945 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
))
9946 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
))
9947 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
))
;
9948 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9949 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
))
9950 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
))
9951 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
))
;
9952 break;
9953 default:
9954 if (hfinfo->display != BASE_NONE) {
9955 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9956 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)
9957 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)
9958 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)
9959 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)
;
9960 //wmem_free(NULL, tmp_str);
9961 }
9962 if (hfinfo->bitmask != 0)
9963 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
))
9964 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
))
9965 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
))
;
9966 if (hfinfo->strings != NULL((void*)0))
9967 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
))
9968 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
))
9969 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
))
;
9970 break;
9971 }
9972}
9973
9974static void
9975register_type_length_mismatch(void)
9976{
9977 static ei_register_info ei[] = {
9978 { &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)}}
}},
9979 { &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)}}
}},
9980 };
9981
9982 expert_module_t* expert_type_length_mismatch;
9983
9984 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9985
9986 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9987 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9988
9989 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9990 disabling them makes no sense. */
9991 proto_set_cant_toggle(proto_type_length_mismatch);
9992}
9993
9994static void
9995register_byte_array_string_decodinws_error(void)
9996{
9997 static ei_register_info ei[] = {
9998 { &ei_byte_array_string_decoding_failed_error,
9999 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10000 "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)}}
10001 }
10002 },
10003 };
10004
10005 expert_module_t* expert_byte_array_string_decoding_error;
10006
10007 proto_byte_array_string_decoding_error =
10008 proto_register_protocol("Byte Array-String Decoding Error",
10009 "Byte Array-string decoding error",
10010 "_ws.byte_array_string.decoding_error");
10011
10012 expert_byte_array_string_decoding_error =
10013 expert_register_protocol(proto_byte_array_string_decoding_error);
10014 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10015
10016 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10017 disabling them makes no sense. */
10018 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10019}
10020
10021static void
10022register_date_time_string_decodinws_error(void)
10023{
10024 static ei_register_info ei[] = {
10025 { &ei_date_time_string_decoding_failed_error,
10026 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10027 "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)}}
10028 }
10029 },
10030 };
10031
10032 expert_module_t* expert_date_time_string_decoding_error;
10033
10034 proto_date_time_string_decoding_error =
10035 proto_register_protocol("Date and Time-String Decoding Error",
10036 "Date and Time-string decoding error",
10037 "_ws.date_time_string.decoding_error");
10038
10039 expert_date_time_string_decoding_error =
10040 expert_register_protocol(proto_date_time_string_decoding_error);
10041 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10042
10043 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10044 disabling them makes no sense. */
10045 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10046}
10047
10048static void
10049register_string_errors(void)
10050{
10051 static ei_register_info ei[] = {
10052 { &ei_string_trailing_characters,
10053 { "_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)}}
}
10054 },
10055 };
10056
10057 expert_module_t* expert_string_errors;
10058
10059 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10060
10061 expert_string_errors = expert_register_protocol(proto_string_errors);
10062 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10063
10064 /* "String Errors" isn't really a protocol, it's an error indication;
10065 disabling them makes no sense. */
10066 proto_set_cant_toggle(proto_string_errors);
10067}
10068
10069static int
10070proto_register_field_init(header_field_info *hfinfo, const int parent)
10071{
10072
10073 tmp_fld_check_assert(hfinfo);
10074
10075 hfinfo->parent = parent;
10076 hfinfo->same_name_next = NULL((void*)0);
10077 hfinfo->same_name_prev_id = -1;
10078
10079 /* if we always add and never delete, then id == len - 1 is correct */
10080 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10081 if (!gpa_hfinfo.hfi) {
10082 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10083 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10084 /* The entry with index 0 is not used. */
10085 gpa_hfinfo.hfi[0] = NULL((void*)0);
10086 gpa_hfinfo.len = 1;
10087 } else {
10088 gpa_hfinfo.allocated_len += 1000;
10089 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10090 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10091 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10092 }
10093 }
10094 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10095 gpa_hfinfo.len++;
10096 hfinfo->id = gpa_hfinfo.len - 1;
10097
10098 /* if we have real names, enter this field in the name tree */
10099 /* Already checked in tmp_fld_check_assert */
10100 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10101 {
10102
10103 header_field_info *same_name_next_hfinfo;
10104
10105 /* We allow multiple hfinfo's to be registered under the same
10106 * abbreviation. This was done for X.25, as, depending
10107 * on whether it's modulo-8 or modulo-128 operation,
10108 * some bitfield fields may be in different bits of
10109 * a byte, and we want to be able to refer to that field
10110 * with one name regardless of whether the packets
10111 * are modulo-8 or modulo-128 packets. */
10112
10113 /* wmem_map_insert - if key is already present the previous
10114 * hfinfo with the same key/name is returned, otherwise NULL */
10115 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10116 if (same_name_hfinfo) {
10117 /* There's already a field with this name.
10118 * Put the current field *before* that field
10119 * in the list of fields with this name, Thus,
10120 * we end up with an effectively
10121 * doubly-linked-list of same-named hfinfo's,
10122 * with the head of the list (stored in the
10123 * hash) being the last seen hfinfo.
10124 */
10125 same_name_next_hfinfo =
10126 same_name_hfinfo->same_name_next;
10127
10128 hfinfo->same_name_next = same_name_next_hfinfo;
10129 if (same_name_next_hfinfo)
10130 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10131
10132 same_name_hfinfo->same_name_next = hfinfo;
10133 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10134#ifdef ENABLE_CHECK_FILTER
10135 while (same_name_hfinfo) {
10136 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10137 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", 10137
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10138 same_name_hfinfo = same_name_hfinfo->same_name_next;
10139 }
10140#endif
10141 }
10142 }
10143
10144 return hfinfo->id;
10145}
10146
10147void
10148proto_register_subtree_array(int * const *indices, const int num_indices)
10149{
10150 int i;
10151 int *const *ptr = indices;
10152
10153 /*
10154 * If we've already allocated the array of tree types, expand
10155 * it; this lets plugins such as mate add tree types after
10156 * the initial startup. (If we haven't already allocated it,
10157 * we don't allocate it; on the first pass, we just assign
10158 * ett values and keep track of how many we've assigned, and
10159 * when we're finished registering all dissectors we allocate
10160 * the array, so that we do only one allocation rather than
10161 * wasting CPU time and memory by growing the array for each
10162 * dissector that registers ett values.)
10163 */
10164 if (tree_is_expanded != NULL((void*)0)) {
10165 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10166
10167 /* set new items to 0 */
10168 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10169 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10170 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10171 }
10172
10173 /*
10174 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10175 * returning the indices through the pointers in the array whose
10176 * first element is pointed to by "indices", and update
10177 * "num_tree_types" appropriately.
10178 */
10179 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10180 if (**ptr != -1 && **ptr != 0) {
10181 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.")
10182 " 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.")
10183 " 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.")
10184 " 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.")
;
10185 }
10186 **ptr = num_tree_types;
10187 }
10188}
10189
10190static void
10191mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10192{
10193 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10194 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10195 char *last_char;
10196
10197 /* ..... field_name: dataaaaaaaaaaaaa
10198 * |
10199 * ^^^^^ name_pos
10200 *
10201 * ..... field_name […]: dataaaaaaaaaaaaa
10202 *
10203 * name_pos==0 means that we have only data or only a field_name
10204 */
10205
10206 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10206, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10207
10208 if (name_pos >= size - trunc_len) {
10209 /* No room for trunc_str after the field_name, put it first. */
10210 name_pos = 0;
10211 }
10212
10213 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10214 if (name_pos == 0) {
10215 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10216 memcpy(label_str, trunc_str + 1, trunc_len);
10217 } else {
10218 memcpy(label_str + name_pos, trunc_str, trunc_len);
10219 }
10220 /* in general, label_str is UTF-8
10221 we can truncate it only at the beginning of a new character
10222 we go backwards from the byte right after our buffer and
10223 find the next starting byte of a UTF-8 character, this is
10224 where we cut
10225 there's no need to use g_utf8_find_prev_char(), the search
10226 will always succeed since we copied trunc_str into the
10227 buffer */
10228 /* g_utf8_prev_char does not deference the memory address
10229 * passed in (until after decrementing it, so it is perfectly
10230 * legal to pass in a pointer one past the last element.
10231 */
10232 last_char = g_utf8_prev_char(label_str + size);
10233 *last_char = '\0';
10234 /* This is unnecessary (above always terminates), but try to
10235 * convince Coverity to avoid dozens of false positives. */
10236 label_str[size - 1] = '\0';
10237
10238 if (value_pos && *value_pos > 0) {
10239 if (name_pos == 0) {
10240 *value_pos += trunc_len;
10241 } else {
10242 /* Move one back to include trunc_str in the value. */
10243 *value_pos -= 1;
10244 }
10245 }
10246
10247 /* Check if value_pos is past label_str. */
10248 if (value_pos && *value_pos >= size) {
10249 *value_pos = size - 1;
10250 }
10251}
10252
10253static void
10254label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10255{
10256 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10257}
10258
10259static size_t
10260label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10261{
10262 size_t name_pos;
10263
10264 /* "%s: %s", hfinfo->name, text */
10265 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)
;
10266 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10267 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10268 if (value_pos) {
10269 *value_pos = pos;
10270 }
10271 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10272 }
10273
10274 if (pos >= ITEM_LABEL_LENGTH240) {
10275 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10276 label_mark_truncated(label_str, name_pos, value_pos);
10277 }
10278
10279 return pos;
10280}
10281
10282static size_t
10283label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10284{
10285 size_t name_pos;
10286
10287 /* "%s: %s (%s)", hfinfo->name, text, descr */
10288 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)
;
10289 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10290 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10291 if (value_pos) {
10292 *value_pos = pos;
10293 }
10294 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10295 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)
;
10296 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)
;
10297 } else {
10298 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)
;
10299 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10300 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)
;
10301 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10302 }
10303 }
10304
10305 if (pos >= ITEM_LABEL_LENGTH240) {
10306 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10307 label_mark_truncated(label_str, name_pos, value_pos);
10308 }
10309
10310 return pos;
10311}
10312
10313void
10314proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10315{
10316 const header_field_info *hfinfo;
10317 const char *str;
10318 const uint8_t *bytes;
10319 uint32_t integer;
10320 const ipv4_addr_and_mask *ipv4;
10321 const ipv6_addr_and_prefix *ipv6;
10322 const e_guid_t *guid;
10323 char *name;
10324 address addr;
10325 char *addr_str;
10326 char *tmp;
10327
10328 if (!label_str) {
10329 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10329, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10330 return;
10331 }
10332
10333 label_str[0]= '\0';
10334
10335 if (!fi) {
10336 return;
10337 }
10338
10339 hfinfo = fi->hfinfo;
10340
10341 switch (hfinfo->type) {
10342 case FT_NONE:
10343 case FT_PROTOCOL:
10344 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10345 if (value_pos) {
10346 *value_pos = strlen(hfinfo->name);
10347 }
10348 break;
10349
10350 case FT_BOOLEAN:
10351 fill_label_boolean(fi, label_str, value_pos);
10352 break;
10353
10354 case FT_BYTES:
10355 case FT_UINT_BYTES:
10356 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10357 fvalue_get_bytes_data(fi->value),
10358 (unsigned)fvalue_length2(fi->value));
10359 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10360 wmem_free(NULL((void*)0), tmp);
10361 break;
10362
10363 case FT_CHAR:
10364 if (hfinfo->bitmask) {
10365 fill_label_bitfield_char(fi, label_str, value_pos);
10366 } else {
10367 fill_label_char(fi, label_str, value_pos);
10368 }
10369 break;
10370
10371 /* Four types of integers to take care of:
10372 * Bitfield, with val_string
10373 * Bitfield, w/o val_string
10374 * Non-bitfield, with val_string
10375 * Non-bitfield, w/o val_string
10376 */
10377 case FT_UINT8:
10378 case FT_UINT16:
10379 case FT_UINT24:
10380 case FT_UINT32:
10381 if (hfinfo->bitmask) {
10382 fill_label_bitfield(fi, label_str, value_pos, false0);
10383 } else {
10384 fill_label_number(fi, label_str, value_pos, false0);
10385 }
10386 break;
10387
10388 case FT_FRAMENUM:
10389 fill_label_number(fi, label_str, value_pos, false0);
10390 break;
10391
10392 case FT_UINT40:
10393 case FT_UINT48:
10394 case FT_UINT56:
10395 case FT_UINT64:
10396 if (hfinfo->bitmask) {
10397 fill_label_bitfield64(fi, label_str, value_pos, false0);
10398 } else {
10399 fill_label_number64(fi, label_str, value_pos, false0);
10400 }
10401 break;
10402
10403 case FT_INT8:
10404 case FT_INT16:
10405 case FT_INT24:
10406 case FT_INT32:
10407 if (hfinfo->bitmask) {
10408 fill_label_bitfield(fi, label_str, value_pos, true1);
10409 } else {
10410 fill_label_number(fi, label_str, value_pos, true1);
10411 }
10412 break;
10413
10414 case FT_INT40:
10415 case FT_INT48:
10416 case FT_INT56:
10417 case FT_INT64:
10418 if (hfinfo->bitmask) {
10419 fill_label_bitfield64(fi, label_str, value_pos, true1);
10420 } else {
10421 fill_label_number64(fi, label_str, value_pos, true1);
10422 }
10423 break;
10424
10425 case FT_FLOAT:
10426 case FT_DOUBLE:
10427 fill_label_float(fi, label_str, value_pos);
10428 break;
10429
10430 case FT_ABSOLUTE_TIME:
10431 {
10432 const nstime_t *value = fvalue_get_time(fi->value);
10433 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10434 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10435 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10436 }
10437 if (hfinfo->strings) {
10438 /*
10439 * Table of time valus to be displayed
10440 * specially.
10441 */
10442 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10443 if (time_string != NULL((void*)0)) {
10444 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10445 break;
10446 }
10447 }
10448 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10449 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10450 wmem_free(NULL((void*)0), tmp);
10451 break;
10452 }
10453 case FT_RELATIVE_TIME:
10454 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10455 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10456 wmem_free(NULL((void*)0), tmp);
10457 break;
10458
10459 case FT_IPXNET:
10460 integer = fvalue_get_uinteger(fi->value);
10461 tmp = get_ipxnet_name(NULL((void*)0), integer);
10462 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10463 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10464 wmem_free(NULL((void*)0), tmp);
10465 wmem_free(NULL((void*)0), addr_str);
10466 break;
10467
10468 case FT_VINES:
10469 addr.type = AT_VINES;
10470 addr.len = VINES_ADDR_LEN6;
10471 addr.data = fvalue_get_bytes_data(fi->value);
10472
10473 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10474 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10475 wmem_free(NULL((void*)0), addr_str);
10476 break;
10477
10478 case FT_ETHER:
10479 bytes = fvalue_get_bytes_data(fi->value);
10480
10481 addr.type = AT_ETHER;
10482 addr.len = 6;
10483 addr.data = bytes;
10484
10485 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10486 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10487 wmem_free(NULL((void*)0), addr_str);
10488 break;
10489
10490 case FT_IPv4:
10491 ipv4 = fvalue_get_ipv4(fi->value);
10492 set_address_ipv4(&addr, ipv4);
10493
10494 if (hfinfo->display == BASE_NETMASK) {
10495 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10496 } else {
10497 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10498 }
10499 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10500 wmem_free(NULL((void*)0), addr_str);
10501 free_address(&addr);
10502 break;
10503
10504 case FT_IPv6:
10505 ipv6 = fvalue_get_ipv6(fi->value);
10506 set_address_ipv6(&addr, ipv6);
10507
10508 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10509 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10510 wmem_free(NULL((void*)0), addr_str);
10511 free_address(&addr);
10512 break;
10513
10514 case FT_FCWWN:
10515 bytes = fvalue_get_bytes_data(fi->value);
10516 addr.type = AT_FCWWN;
10517 addr.len = FCWWN_ADDR_LEN8;
10518 addr.data = bytes;
10519
10520 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10521 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10522 wmem_free(NULL((void*)0), addr_str);
10523 break;
10524
10525 case FT_GUID:
10526 guid = fvalue_get_guid(fi->value);
10527 tmp = guid_to_str(NULL((void*)0), guid);
10528 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10529 wmem_free(NULL((void*)0), tmp);
10530 break;
10531
10532 case FT_OID:
10533 bytes = fvalue_get_bytes_data(fi->value);
10534 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10535 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10536 if (name) {
10537 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10538 wmem_free(NULL((void*)0), name);
10539 } else {
10540 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10541 }
10542 wmem_free(NULL((void*)0), tmp);
10543 break;
10544
10545 case FT_REL_OID:
10546 bytes = fvalue_get_bytes_data(fi->value);
10547 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10548 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10549 if (name) {
10550 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10551 wmem_free(NULL((void*)0), name);
10552 } else {
10553 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10554 }
10555 wmem_free(NULL((void*)0), tmp);
10556 break;
10557
10558 case FT_SYSTEM_ID:
10559 bytes = fvalue_get_bytes_data(fi->value);
10560 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10561 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10562 wmem_free(NULL((void*)0), tmp);
10563 break;
10564
10565 case FT_EUI64:
10566 bytes = fvalue_get_bytes_data(fi->value);
10567 addr.type = AT_EUI64;
10568 addr.len = EUI64_ADDR_LEN8;
10569 addr.data = bytes;
10570
10571 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10572 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10573 wmem_free(NULL((void*)0), addr_str);
10574 break;
10575 case FT_STRING:
10576 case FT_STRINGZ:
10577 case FT_UINT_STRING:
10578 case FT_STRINGZPAD:
10579 case FT_STRINGZTRUNC:
10580 case FT_AX25:
10581 str = fvalue_get_string(fi->value);
10582 label_fill(label_str, 0, hfinfo, str, value_pos);
10583 break;
10584
10585 case FT_IEEE_11073_SFLOAT:
10586 case FT_IEEE_11073_FLOAT:
10587 fill_label_ieee_11073_float(fi, label_str, value_pos);
10588 break;
10589
10590 default:
10591 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
))
10592 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
))
10593 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
))
10594 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
))
;
10595 break;
10596 }
10597}
10598
10599static void
10600fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10601{
10602 char *p;
10603 unsigned bitfield_byte_length = 0;
10604 int bitwidth;
10605 uint64_t unshifted_value;
10606 uint64_t value;
10607
10608 const header_field_info *hfinfo = fi->hfinfo;
10609
10610 value = fvalue_get_uinteger64(fi->value);
10611 if (hfinfo->bitmask) {
10612 /* Figure out the bit width */
10613 bitwidth = hfinfo_container_bitwidth(hfinfo);
10614
10615 /* Un-shift bits */
10616 unshifted_value = value;
10617 unshifted_value <<= hfinfo_bitshift(hfinfo);
10618
10619 /* Create the bitfield first */
10620 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10621 bitfield_byte_length = (unsigned) (p - label_str);
10622 }
10623
10624 /* Fill in the textual info */
10625 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10626}
10627
10628static const char *
10629hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10630{
10631 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10632 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10633
10634 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10635 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10636 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10637 else
10638 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10639 }
10640
10641 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10642 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10643
10644 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10645 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10646
10647 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10648}
10649
10650static const char *
10651hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10652{
10653 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10654 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10655 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10656 else
10657 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10658 }
10659
10660 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10661 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10662
10663 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10664 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10665
10666 /* If this is reached somebody registered a 64-bit field with a 32-bit
10667 * value-string, which isn't right. */
10668 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)
10669 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10670
10671 /* This is necessary to squelch MSVC errors; is there
10672 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10673 never returns? */
10674 return NULL((void*)0);
10675}
10676
10677static const char *
10678hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10679{
10680 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10681 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10682
10683 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)
;
10684
10685 /* This is necessary to squelch MSVC errors; is there
10686 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10687 never returns? */
10688 return NULL((void*)0);
10689}
10690
10691static const char *
10692hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10693{
10694 const char *str = hf_try_val_to_str(value, hfinfo);
10695
10696 return (str) ? str : unknown_str;
10697}
10698
10699static const char *
10700hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10701{
10702 const char *str = hf_try_val64_to_str(value, hfinfo);
10703
10704 return (str) ? str : unknown_str;
10705}
10706
10707/* Fills data for bitfield chars with val_strings */
10708static void
10709fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10710{
10711 char *p;
10712 unsigned bitfield_byte_length;
10713 int bitwidth;
10714 uint32_t unshifted_value;
10715 uint32_t value;
10716
10717 char buf[32];
10718 const char *out;
10719
10720 const header_field_info *hfinfo = fi->hfinfo;
10721
10722 /* Figure out the bit width */
10723 bitwidth = hfinfo_container_bitwidth(hfinfo);
10724
10725 /* Un-shift bits */
10726 value = fvalue_get_uinteger(fi->value);
10727
10728 unshifted_value = value;
10729 if (hfinfo->bitmask) {
10730 unshifted_value <<= hfinfo_bitshift(hfinfo);
10731 }
10732
10733 /* Create the bitfield first */
10734 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10735 bitfield_byte_length = (unsigned) (p - label_str);
10736
10737 /* Fill in the textual info using stored (shifted) value */
10738 if (hfinfo->display == BASE_CUSTOM) {
10739 char tmp[ITEM_LABEL_LENGTH240];
10740 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10741
10742 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10742, "fmtfunc"))))
;
10743 fmtfunc(tmp, value);
10744 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10745 }
10746 else if (hfinfo->strings) {
10747 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10748
10749 out = hfinfo_char_vals_format(hfinfo, buf, value);
10750 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10751 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10752 else
10753 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10754 }
10755 else {
10756 out = hfinfo_char_value_format(hfinfo, buf, value);
10757
10758 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10759 }
10760}
10761
10762/* Fills data for bitfield ints with val_strings */
10763static void
10764fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10765{
10766 char *p;
10767 unsigned bitfield_byte_length;
10768 int bitwidth;
10769 uint32_t value, unshifted_value;
10770 char buf[NUMBER_LABEL_LENGTH80];
10771 const char *out;
10772
10773 const header_field_info *hfinfo = fi->hfinfo;
10774
10775 /* Figure out the bit width */
10776 if (fi->flags & FI_VARINT0x00040000)
10777 bitwidth = fi->length*8;
10778 else
10779 bitwidth = hfinfo_container_bitwidth(hfinfo);
10780
10781 /* Un-shift bits */
10782 if (is_signed)
10783 value = fvalue_get_sinteger(fi->value);
10784 else
10785 value = fvalue_get_uinteger(fi->value);
10786
10787 unshifted_value = value;
10788 if (hfinfo->bitmask) {
10789 unshifted_value <<= hfinfo_bitshift(hfinfo);
10790 }
10791
10792 /* Create the bitfield first */
10793 if (fi->flags & FI_VARINT0x00040000)
10794 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10795 else
10796 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10797 bitfield_byte_length = (unsigned) (p - label_str);
10798
10799 /* Fill in the textual info using stored (shifted) value */
10800 if (hfinfo->display == BASE_CUSTOM) {
10801 char tmp[ITEM_LABEL_LENGTH240];
10802 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10803
10804 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10804, "fmtfunc"))))
;
10805 fmtfunc(tmp, value);
10806 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10807 }
10808 else if (hfinfo->strings) {
10809 const char *val_str = hf_try_val_to_str(value, hfinfo);
10810
10811 out = hfinfo_number_vals_format(hfinfo, buf, value);
10812 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10813 /*
10814 * Unique values only display value_string string
10815 * if there is a match. Otherwise it's just a number
10816 */
10817 if (val_str) {
10818 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10819 } else {
10820 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10821 }
10822 } else {
10823 if (val_str == NULL((void*)0))
10824 val_str = "Unknown";
10825
10826 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10827 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10828 else
10829 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10830 }
10831 }
10832 else {
10833 out = hfinfo_number_value_format(hfinfo, buf, value);
10834
10835 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10836 }
10837}
10838
10839static void
10840fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10841{
10842 char *p;
10843 unsigned bitfield_byte_length;
10844 int bitwidth;
10845 uint64_t value, unshifted_value;
10846 char buf[NUMBER_LABEL_LENGTH80];
10847 const char *out;
10848
10849 const header_field_info *hfinfo = fi->hfinfo;
10850
10851 /* Figure out the bit width */
10852 if (fi->flags & FI_VARINT0x00040000)
10853 bitwidth = fi->length*8;
10854 else
10855 bitwidth = hfinfo_container_bitwidth(hfinfo);
10856
10857 /* Un-shift bits */
10858 if (is_signed)
10859 value = fvalue_get_sinteger64(fi->value);
10860 else
10861 value = fvalue_get_uinteger64(fi->value);
10862
10863 unshifted_value = value;
10864 if (hfinfo->bitmask) {
10865 unshifted_value <<= hfinfo_bitshift(hfinfo);
10866 }
10867
10868 /* Create the bitfield first */
10869 if (fi->flags & FI_VARINT0x00040000)
10870 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10871 else
10872 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10873 bitfield_byte_length = (unsigned) (p - label_str);
10874
10875 /* Fill in the textual info using stored (shifted) value */
10876 if (hfinfo->display == BASE_CUSTOM) {
10877 char tmp[ITEM_LABEL_LENGTH240];
10878 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10879
10880 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10880, "fmtfunc64"
))))
;
10881 fmtfunc64(tmp, value);
10882 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10883 }
10884 else if (hfinfo->strings) {
10885 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10886
10887 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10888 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10889 /*
10890 * Unique values only display value_string string
10891 * if there is a match. Otherwise it's just a number
10892 */
10893 if (val_str) {
10894 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10895 } else {
10896 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10897 }
10898 } else {
10899 if (val_str == NULL((void*)0))
10900 val_str = "Unknown";
10901
10902 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10903 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10904 else
10905 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10906 }
10907 }
10908 else {
10909 out = hfinfo_number_value_format64(hfinfo, buf, value);
10910
10911 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10912 }
10913}
10914
10915static void
10916fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10917{
10918 const header_field_info *hfinfo = fi->hfinfo;
10919 uint32_t value;
10920
10921 char buf[32];
10922 const char *out;
10923
10924 value = fvalue_get_uinteger(fi->value);
10925
10926 /* Fill in the textual info */
10927 if (hfinfo->display == BASE_CUSTOM) {
10928 char tmp[ITEM_LABEL_LENGTH240];
10929 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10930
10931 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10931, "fmtfunc"))))
;
10932 fmtfunc(tmp, value);
10933 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10934 }
10935 else if (hfinfo->strings) {
10936 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10937
10938 out = hfinfo_char_vals_format(hfinfo, buf, value);
10939 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10940 }
10941 else {
10942 out = hfinfo_char_value_format(hfinfo, buf, value);
10943
10944 label_fill(label_str, 0, hfinfo, out, value_pos);
10945 }
10946}
10947
10948static void
10949fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10950{
10951 const header_field_info *hfinfo = fi->hfinfo;
10952 uint32_t value;
10953
10954 char buf[NUMBER_LABEL_LENGTH80];
10955 const char *out;
10956
10957 if (is_signed)
10958 value = fvalue_get_sinteger(fi->value);
10959 else
10960 value = fvalue_get_uinteger(fi->value);
10961
10962 /* Fill in the textual info */
10963 if (hfinfo->display == BASE_CUSTOM) {
10964 char tmp[ITEM_LABEL_LENGTH240];
10965 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10966
10967 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10967, "fmtfunc"))))
;
10968 fmtfunc(tmp, value);
10969 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10970 }
10971 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10972 /*
10973 * It makes no sense to have a value-string table for a
10974 * frame-number field - they're just integers giving
10975 * the ordinal frame number.
10976 */
10977 const char *val_str = hf_try_val_to_str(value, hfinfo);
10978
10979 out = hfinfo_number_vals_format(hfinfo, buf, value);
10980 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10981 /*
10982 * Unique values only display value_string string
10983 * if there is a match. Otherwise it's just a number
10984 */
10985 if (val_str) {
10986 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10987 } else {
10988 label_fill(label_str, 0, hfinfo, out, value_pos);
10989 }
10990 } else {
10991 if (val_str == NULL((void*)0))
10992 val_str = "Unknown";
10993
10994 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10995 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10996 else
10997 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10998 }
10999 }
11000 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
))
) {
11001 char tmp[ITEM_LABEL_LENGTH240];
11002
11003 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11004 display_to_port_type((field_display_e)hfinfo->display), value);
11005 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11006 }
11007 else {
11008 out = hfinfo_number_value_format(hfinfo, buf, value);
11009
11010 label_fill(label_str, 0, hfinfo, out, value_pos);
11011 }
11012}
11013
11014static void
11015fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11016{
11017 const header_field_info *hfinfo = fi->hfinfo;
11018 uint64_t value;
11019
11020 char buf[NUMBER_LABEL_LENGTH80];
11021 const char *out;
11022
11023 if (is_signed)
11024 value = fvalue_get_sinteger64(fi->value);
11025 else
11026 value = fvalue_get_uinteger64(fi->value);
11027
11028 /* Fill in the textual info */
11029 if (hfinfo->display == BASE_CUSTOM) {
11030 char tmp[ITEM_LABEL_LENGTH240];
11031 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11032
11033 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11033, "fmtfunc64"
))))
;
11034 fmtfunc64(tmp, value);
11035 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11036 }
11037 else if (hfinfo->strings) {
11038 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11039
11040 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11041 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11042 /*
11043 * Unique values only display value_string string
11044 * if there is a match. Otherwise it's just a number
11045 */
11046 if (val_str) {
11047 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11048 } else {
11049 label_fill(label_str, 0, hfinfo, out, value_pos);
11050 }
11051 } else {
11052 if (val_str == NULL((void*)0))
11053 val_str = "Unknown";
11054
11055 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11056 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11057 else
11058 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11059 }
11060 }
11061 else {
11062 out = hfinfo_number_value_format64(hfinfo, buf, value);
11063
11064 label_fill(label_str, 0, hfinfo, out, value_pos);
11065 }
11066}
11067
11068static size_t
11069fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11070{
11071 int display;
11072 int n;
11073 double value;
11074
11075 if (label_str_size < 12) {
11076 /* Not enough room to write an entire floating point value. */
11077 return 0;
11078 }
11079
11080 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11081 value = fvalue_get_floating(fi->value);
11082
11083 if (display == BASE_CUSTOM) {
11084 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11085 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11085, "fmtfunc"))))
;
11086 fmtfunc(label_str, value);
11087 return strlen(label_str);
11088 }
11089
11090 switch (display) {
11091 case BASE_NONE:
11092 if (fi->hfinfo->type == FT_FLOAT) {
11093 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11094 } else {
11095 n = (int)strlen(dtoa_g_fmt(label_str, value));
11096 }
11097 break;
11098 case BASE_DEC:
11099 n = snprintf(label_str, label_str_size, "%f", value);
11100 break;
11101 case BASE_HEX:
11102 n = snprintf(label_str, label_str_size, "%a", value);
11103 break;
11104 case BASE_EXP:
11105 n = snprintf(label_str, label_str_size, "%e", value);
11106 break;
11107 default:
11108 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11108
, __func__, "assertion \"not reached\" failed")
;
11109 }
11110 if (n < 0) {
11111 return 0; /* error */
11112 }
11113 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11114 const char *hf_str_val;
11115 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11116 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11117 }
11118 if (n > label_str_size) {
11119 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11119, __func__, "label length too small"); } } while (0)
;
11120 return strlen(label_str);
11121 }
11122
11123 return n;
11124}
11125
11126void
11127fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11128{
11129 char tmp[ITEM_LABEL_LENGTH240];
11130
11131 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11132 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11133}
11134
11135static size_t
11136fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11137{
11138 int display;
11139 size_t pos = 0;
11140 double value;
11141 char* tmp_str;
11142
11143 if (label_str_size < 12) {
11144 /* Not enough room to write an entire floating point value. */
11145 return 0;
11146 }
11147
11148 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11149 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11150 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11151 wmem_free(NULL((void*)0), tmp_str);
11152
11153 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11154 const char *hf_str_val;
11155 fvalue_to_double(fi->value, &value);
11156 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11157 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)
;
11158 }
11159 if ((int)pos > label_str_size) {
11160 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11160, __func__, "label length too small"); } } while (0)
;
11161 return strlen(label_str);
11162 }
11163
11164 return pos;
11165}
11166
11167void
11168fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11169{
11170 char tmp[ITEM_LABEL_LENGTH240];
11171
11172 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11173 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11174}
11175
11176int
11177hfinfo_bitshift(const header_field_info *hfinfo)
11178{
11179 return ws_ctz(hfinfo->bitmask);
11180}
11181
11182
11183static int
11184hfinfo_bitoffset(const header_field_info *hfinfo)
11185{
11186 if (!hfinfo->bitmask) {
11187 return 0;
11188 }
11189
11190 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11191 * as the first bit */
11192 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11193}
11194
11195static int
11196hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11197{
11198 if (!hfinfo->bitmask) {
11199 return 0;
11200 }
11201
11202 /* ilog2 = first set bit, ctz = last set bit */
11203 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11204}
11205
11206static int
11207hfinfo_type_bitwidth(enum ftenum type)
11208{
11209 int bitwidth = 0;
11210
11211 switch (type) {
11212 case FT_CHAR:
11213 case FT_UINT8:
11214 case FT_INT8:
11215 bitwidth = 8;
11216 break;
11217 case FT_UINT16:
11218 case FT_INT16:
11219 bitwidth = 16;
11220 break;
11221 case FT_UINT24:
11222 case FT_INT24:
11223 bitwidth = 24;
11224 break;
11225 case FT_UINT32:
11226 case FT_INT32:
11227 bitwidth = 32;
11228 break;
11229 case FT_UINT40:
11230 case FT_INT40:
11231 bitwidth = 40;
11232 break;
11233 case FT_UINT48:
11234 case FT_INT48:
11235 bitwidth = 48;
11236 break;
11237 case FT_UINT56:
11238 case FT_INT56:
11239 bitwidth = 56;
11240 break;
11241 case FT_UINT64:
11242 case FT_INT64:
11243 bitwidth = 64;
11244 break;
11245 default:
11246 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11246))
;
11247 ;
11248 }
11249 return bitwidth;
11250}
11251
11252
11253static int
11254hfinfo_container_bitwidth(const header_field_info *hfinfo)
11255{
11256 if (!hfinfo->bitmask) {
11257 return 0;
11258 }
11259
11260 if (hfinfo->type == FT_BOOLEAN) {
11261 return hfinfo->display; /* hacky? :) */
11262 }
11263
11264 return hfinfo_type_bitwidth(hfinfo->type);
11265}
11266
11267static int
11268hfinfo_hex_digits(const header_field_info *hfinfo)
11269{
11270 int bitwidth;
11271
11272 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11273 * appropriate to determine the number of hex digits for the field.
11274 * So instead, we compute it from the bitmask.
11275 */
11276 if (hfinfo->bitmask != 0) {
11277 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11278 } else {
11279 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11280 }
11281
11282 /* Divide by 4, rounding up, to get number of hex digits. */
11283 return (bitwidth + 3) / 4;
11284}
11285
11286const char *
11287hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11288{
11289 char *ptr = &buf[6];
11290 static const char hex_digits[16] =
11291 { '0', '1', '2', '3', '4', '5', '6', '7',
11292 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11293
11294 *ptr = '\0';
11295 *(--ptr) = '\'';
11296 /* Properly format value */
11297 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11298 /*
11299 * Printable, so just show the character, and, if it needs
11300 * to be escaped, escape it.
11301 */
11302 *(--ptr) = value;
11303 if (value == '\\' || value == '\'')
11304 *(--ptr) = '\\';
11305 } else {
11306 /*
11307 * Non-printable; show it as an escape sequence.
11308 */
11309 switch (value) {
11310
11311 case '\0':
11312 /*
11313 * Show a NUL with only one digit.
11314 */
11315 *(--ptr) = '0';
11316 break;
11317
11318 case '\a':
11319 case '\b':
11320 case '\f':
11321 case '\n':
11322 case '\r':
11323 case '\t':
11324 case '\v':
11325 *(--ptr) = value - '\a' + 'a';
11326 break;
11327
11328 default:
11329 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11330
11331 case BASE_OCT:
11332 *(--ptr) = (value & 0x7) + '0';
11333 value >>= 3;
11334 *(--ptr) = (value & 0x7) + '0';
11335 value >>= 3;
11336 *(--ptr) = (value & 0x7) + '0';
11337 break;
11338
11339 case BASE_HEX:
11340 *(--ptr) = hex_digits[value & 0x0F];
11341 value >>= 4;
11342 *(--ptr) = hex_digits[value & 0x0F];
11343 *(--ptr) = 'x';
11344 break;
11345
11346 default:
11347 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11348 }
11349 }
11350 *(--ptr) = '\\';
11351 }
11352 *(--ptr) = '\'';
11353 return ptr;
11354}
11355
11356static const char *
11357hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11358{
11359 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11360 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
))
;
11361
11362 *ptr = '\0';
11363 /* Properly format value */
11364 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11365 case BASE_DEC:
11366 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11367
11368 case BASE_DEC_HEX:
11369 *(--ptr) = ')';
11370 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11371 *(--ptr) = '(';
11372 *(--ptr) = ' ';
11373 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11374 return ptr;
11375
11376 case BASE_OCT:
11377 return oct_to_str_back(ptr, value);
11378
11379 case BASE_HEX:
11380 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11381
11382 case BASE_HEX_DEC:
11383 *(--ptr) = ')';
11384 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11385 *(--ptr) = '(';
11386 *(--ptr) = ' ';
11387 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11388 return ptr;
11389
11390 case BASE_PT_UDP:
11391 case BASE_PT_TCP:
11392 case BASE_PT_DCCP:
11393 case BASE_PT_SCTP:
11394 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11395 display_to_port_type((field_display_e)display), value);
11396 return buf;
11397 case BASE_OUI:
11398 {
11399 uint8_t p_oui[3];
11400 const char *manuf_name;
11401
11402 p_oui[0] = value >> 16 & 0xFF;
11403 p_oui[1] = value >> 8 & 0xFF;
11404 p_oui[2] = value & 0xFF;
11405
11406 /* Attempt an OUI lookup. */
11407 manuf_name = uint_get_manuf_name_if_known(value);
11408 if (manuf_name == NULL((void*)0)) {
11409 /* Could not find an OUI. */
11410 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11411 }
11412 else {
11413 /* Found an address string. */
11414 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11415 }
11416 return buf;
11417 }
11418
11419 default:
11420 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11421 }
11422 return ptr;
11423}
11424
11425static const char *
11426hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11427{
11428 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11429 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
))
;
11430
11431 *ptr = '\0';
11432 /* Properly format value */
11433 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11434 case BASE_DEC:
11435 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11436
11437 case BASE_DEC_HEX:
11438 *(--ptr) = ')';
11439 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11440 *(--ptr) = '(';
11441 *(--ptr) = ' ';
11442 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11443 return ptr;
11444
11445 case BASE_OCT:
11446 return oct64_to_str_back(ptr, value);
11447
11448 case BASE_HEX:
11449 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11450
11451 case BASE_HEX_DEC:
11452 *(--ptr) = ')';
11453 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11454 *(--ptr) = '(';
11455 *(--ptr) = ' ';
11456 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11457 return ptr;
11458
11459 default:
11460 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11461 }
11462
11463 return ptr;
11464}
11465
11466static const char *
11467hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11468{
11469 int display = hfinfo->display;
11470
11471 if (hfinfo->type == FT_FRAMENUM) {
11472 /*
11473 * Frame numbers are always displayed in decimal.
11474 */
11475 display = BASE_DEC;
11476 }
11477
11478 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11479}
11480
11481static const char *
11482hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11483{
11484 int display = hfinfo->display;
11485
11486 if (hfinfo->type == FT_FRAMENUM) {
11487 /*
11488 * Frame numbers are always displayed in decimal.
11489 */
11490 display = BASE_DEC;
11491 }
11492
11493 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11494}
11495
11496static const char *
11497hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11498{
11499 /* Get the underlying BASE_ value */
11500 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11501
11502 return hfinfo_char_value_format_display(display, buf, value);
11503}
11504
11505static const char *
11506hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11507{
11508 /* Get the underlying BASE_ value */
11509 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11510
11511 if (hfinfo->type == FT_FRAMENUM) {
11512 /*
11513 * Frame numbers are always displayed in decimal.
11514 */
11515 display = BASE_DEC;
11516 }
11517
11518 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11519 display = BASE_DEC;
11520 } else if (display == BASE_OUI) {
11521 display = BASE_HEX;
11522 }
11523
11524 switch (display) {
11525 case BASE_NONE:
11526 /* case BASE_DEC: */
11527 case BASE_DEC_HEX:
11528 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11529 case BASE_CUSTOM:
11530 display = BASE_DEC;
11531 break;
11532
11533 /* case BASE_HEX: */
11534 case BASE_HEX_DEC:
11535 display = BASE_HEX;
11536 break;
11537 }
11538
11539 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11540}
11541
11542static const char *
11543hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11544{
11545 /* Get the underlying BASE_ value */
11546 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11547
11548 if (hfinfo->type == FT_FRAMENUM) {
11549 /*
11550 * Frame numbers are always displayed in decimal.
11551 */
11552 display = BASE_DEC;
11553 }
11554
11555 switch (display) {
11556 case BASE_NONE:
11557 /* case BASE_DEC: */
11558 case BASE_DEC_HEX:
11559 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11560 case BASE_CUSTOM:
11561 display = BASE_DEC;
11562 break;
11563
11564 /* case BASE_HEX: */
11565 case BASE_HEX_DEC:
11566 display = BASE_HEX;
11567 break;
11568 }
11569
11570 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11571}
11572
11573static const char *
11574hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11575{
11576 /* Get the underlying BASE_ value */
11577 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11578
11579 return hfinfo_char_value_format_display(display, buf, value);
11580}
11581
11582static const char *
11583hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11584{
11585 /* Get the underlying BASE_ value */
11586 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11587
11588 if (display == BASE_NONE)
11589 return NULL((void*)0);
11590
11591 if (display == BASE_DEC_HEX)
11592 display = BASE_DEC;
11593 if (display == BASE_HEX_DEC)
11594 display = BASE_HEX;
11595
11596 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11597}
11598
11599static const char *
11600hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11601{
11602 /* Get the underlying BASE_ value */
11603 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11604
11605 if (display == BASE_NONE)
11606 return NULL((void*)0);
11607
11608 if (display == BASE_DEC_HEX)
11609 display = BASE_DEC;
11610 if (display == BASE_HEX_DEC)
11611 display = BASE_HEX;
11612
11613 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11614}
11615
11616const char *
11617proto_registrar_get_name(const int n)
11618{
11619 header_field_info *hfinfo;
11620
11621 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", 11621
, __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", 11621
, "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", 11621, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11622 return hfinfo->name;
11623}
11624
11625const char *
11626proto_registrar_get_abbrev(const int n)
11627{
11628 header_field_info *hfinfo;
11629
11630 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", 11630
, __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", 11630
, "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", 11630, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11631 return hfinfo->abbrev;
11632}
11633
11634enum ftenum
11635proto_registrar_get_ftype(const int n)
11636{
11637 header_field_info *hfinfo;
11638
11639 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", 11639
, __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", 11639
, "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", 11639, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11640 return hfinfo->type;
11641}
11642
11643int
11644proto_registrar_get_parent(const int n)
11645{
11646 header_field_info *hfinfo;
11647
11648 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", 11648
, __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", 11648
, "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", 11648, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11649 return hfinfo->parent;
11650}
11651
11652bool_Bool
11653proto_registrar_is_protocol(const int n)
11654{
11655 header_field_info *hfinfo;
11656
11657 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", 11657
, __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", 11657
, "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", 11657, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11658 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11659}
11660
11661/* Returns length of field in packet (not necessarily the length
11662 * in our internal representation, as in the case of IPv4).
11663 * 0 means undeterminable at time of registration
11664 * -1 means the field is not registered. */
11665int
11666proto_registrar_get_length(const int n)
11667{
11668 header_field_info *hfinfo;
11669
11670 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", 11670
, __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", 11670
, "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", 11670, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11671 return ftype_wire_size(hfinfo->type);
11672}
11673
11674size_t
11675proto_registrar_get_count(struct proto_registrar_stats *stats)
11676{
11677 header_field_info *hfinfo;
11678
11679 // Index zero is not used. We have to skip it.
11680 size_t total_count = gpa_hfinfo.len - 1;
11681 if (stats == NULL((void*)0)) {
11682 return total_count;
11683 }
11684 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11685 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11686 stats->deregistered_count++;
11687 continue; /* This is a deregistered protocol or header field */
11688 }
11689
11690 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", 11690
, __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", 11690, "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", 11690, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11691
11692 if (proto_registrar_is_protocol(id))
11693 stats->protocol_count++;
11694
11695 if (hfinfo->same_name_prev_id != -1)
11696 stats->same_name_count++;
11697 }
11698
11699 return total_count;
11700}
11701
11702/* Looks for a protocol or a field in a proto_tree. Returns true if
11703 * it exists anywhere, or false if it exists nowhere. */
11704bool_Bool
11705proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11706{
11707 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11708
11709 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11710 return true1;
11711 }
11712 else {
11713 return false0;
11714 }
11715}
11716
11717/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11718 * This only works if the hfindex was "primed" before the dissection
11719 * took place, as we just pass back the already-created GPtrArray*.
11720 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11721 * handles that. */
11722GPtrArray *
11723proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11724{
11725 if (!tree)
11726 return NULL((void*)0);
11727
11728 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11729 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11730 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11731 else
11732 return NULL((void*)0);
11733}
11734
11735bool_Bool
11736proto_tracking_interesting_fields(const proto_tree *tree)
11737{
11738 GHashTable *interesting_hfids;
11739
11740 if (!tree)
11741 return false0;
11742
11743 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11744
11745 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11746}
11747
11748/* Helper struct for proto_find_info() and proto_all_finfos() */
11749typedef struct {
11750 GPtrArray *array;
11751 int id;
11752} ffdata_t;
11753
11754/* Helper function for proto_find_info() */
11755static bool_Bool
11756find_finfo(proto_node *node, void * data)
11757{
11758 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11759 if (fi && fi->hfinfo) {
11760 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11761 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11762 }
11763 }
11764
11765 /* Don't stop traversing. */
11766 return false0;
11767}
11768
11769/* Helper function for proto_find_first_info() */
11770static bool_Bool
11771find_first_finfo(proto_node *node, void *data)
11772{
11773 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11774 if (fi && fi->hfinfo) {
11775 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11776 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11777
11778 /* Stop traversing. */
11779 return true1;
11780 }
11781 }
11782
11783 /* Continue traversing. */
11784 return false0;
11785}
11786
11787/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11788* This works on any proto_tree, primed or unprimed, but actually searches
11789* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11790* The caller does need to free the returned GPtrArray with
11791* g_ptr_array_free(<array>, true).
11792*/
11793GPtrArray *
11794proto_find_finfo(proto_tree *tree, const int id)
11795{
11796 ffdata_t ffdata;
11797
11798 ffdata.array = g_ptr_array_new();
11799 ffdata.id = id;
11800
11801 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11802
11803 return ffdata.array;
11804}
11805
11806/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11807* This works on any proto_tree, primed or unprimed, but actually searches
11808* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11809* The caller does need to free the returned GPtrArray with
11810* g_ptr_array_free(<array>, true).
11811*/
11812GPtrArray *
11813proto_find_first_finfo(proto_tree *tree, const int id)
11814{
11815 ffdata_t ffdata;
11816
11817 ffdata.array = g_ptr_array_new();
11818 ffdata.id = id;
11819
11820 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11821
11822 return ffdata.array;
11823}
11824
11825/* Helper function for proto_all_finfos() */
11826static bool_Bool
11827every_finfo(proto_node *node, void * data)
11828{
11829 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11830 if (fi && fi->hfinfo) {
11831 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11832 }
11833
11834 /* Don't stop traversing. */
11835 return false0;
11836}
11837
11838/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11839 * The caller does need to free the returned GPtrArray with
11840 * g_ptr_array_free(<array>, true).
11841 */
11842GPtrArray *
11843proto_all_finfos(proto_tree *tree)
11844{
11845 ffdata_t ffdata;
11846
11847 /* Pre allocate enough space to hold all fields in most cases */
11848 ffdata.array = g_ptr_array_sized_new(512);
11849 ffdata.id = 0;
11850
11851 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11852
11853 return ffdata.array;
11854}
11855
11856
11857typedef struct {
11858 unsigned offset;
11859 field_info *finfo;
11860 tvbuff_t *tvb;
11861} offset_search_t;
11862
11863static bool_Bool
11864check_for_offset(proto_node *node, void * data)
11865{
11866 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11867 offset_search_t *offsearch = (offset_search_t *)data;
11868
11869 /* !fi == the top most container node which holds nothing */
11870 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11871 if (offsearch->offset >= (unsigned) fi->start &&
11872 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11873
11874 offsearch->finfo = fi;
11875 return false0; /* keep traversing */
11876 }
11877 }
11878 return false0; /* keep traversing */
11879}
11880
11881/* Search a proto_tree backwards (from leaves to root) looking for the field
11882 * whose start/length occupies 'offset' */
11883/* XXX - I couldn't find an easy way to search backwards, so I search
11884 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11885 * the one I want to return to the user. This algorithm is inefficient
11886 * and could be re-done, but I'd have to handle all the children and
11887 * siblings of each node myself. When I have more time I'll do that.
11888 * (yeah right) */
11889field_info *
11890proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11891{
11892 offset_search_t offsearch;
11893
11894 offsearch.offset = offset;
11895 offsearch.finfo = NULL((void*)0);
11896 offsearch.tvb = tvb;
11897
11898 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11899
11900 return offsearch.finfo;
11901}
11902
11903typedef struct {
11904 unsigned length;
11905 char *buf;
11906} decoded_data_t;
11907
11908static bool_Bool
11909check_for_undecoded(proto_node *node, void * data)
11910{
11911 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11912 decoded_data_t* decoded = (decoded_data_t*)data;
11913 unsigned i;
11914 unsigned byte;
11915 unsigned bit;
11916
11917 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11918 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11919 byte = i / 8;
11920 bit = i % 8;
11921 decoded->buf[byte] |= (1 << bit);
11922 }
11923 }
11924
11925 return false0;
11926}
11927
11928char*
11929proto_find_undecoded_data(proto_tree *tree, unsigned length)
11930{
11931 decoded_data_t decoded;
11932 decoded.length = length;
11933 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11934
11935 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11936 return decoded.buf;
11937}
11938
11939/* Dumps the protocols in the registration database to stdout. An independent
11940 * program can take this output and format it into nice tables or HTML or
11941 * whatever.
11942 *
11943 * There is one record per line. The fields are tab-delimited.
11944 *
11945 * Field 1 = protocol name
11946 * Field 2 = protocol short name
11947 * Field 3 = protocol filter name
11948 * Field 4 = protocol enabled
11949 * Field 5 = protocol enabled by default
11950 * Field 6 = protocol can toggle
11951 */
11952void
11953proto_registrar_dump_protocols(void)
11954{
11955 protocol_t *protocol;
11956 int i;
11957 void *cookie = NULL((void*)0);
11958
11959
11960 i = proto_get_first_protocol(&cookie);
11961 while (i != -1) {
11962 protocol = find_protocol_by_id(i);
11963 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11964 protocol->name,
11965 protocol->short_name,
11966 protocol->filter_name,
11967 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11968 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11969 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11970 i = proto_get_next_protocol(&cookie);
11971 }
11972}
11973
11974/* Dumps the value_strings, extended value string headers, range_strings
11975 * or true/false strings for fields that have them.
11976 * There is one record per line. Fields are tab-delimited.
11977 * There are four types of records: Value String, Extended Value String Header,
11978 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11979 * the type of record.
11980 *
11981 * Note that a record will be generated only if the value_string,... is referenced
11982 * in a registered hfinfo entry.
11983 *
11984 *
11985 * Value Strings
11986 * -------------
11987 * Field 1 = 'V'
11988 * Field 2 = Field abbreviation to which this value string corresponds
11989 * Field 3 = Integer value
11990 * Field 4 = String
11991 *
11992 * Extended Value String Headers
11993 * -----------------------------
11994 * Field 1 = 'E'
11995 * Field 2 = Field abbreviation to which this extended value string header corresponds
11996 * Field 3 = Extended Value String "Name"
11997 * Field 4 = Number of entries in the associated value_string array
11998 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11999 *
12000 * Range Strings
12001 * -------------
12002 * Field 1 = 'R'
12003 * Field 2 = Field abbreviation to which this range string corresponds
12004 * Field 3 = Integer value: lower bound
12005 * Field 4 = Integer value: upper bound
12006 * Field 5 = String
12007 *
12008 * True/False Strings
12009 * ------------------
12010 * Field 1 = 'T'
12011 * Field 2 = Field abbreviation to which this true/false string corresponds
12012 * Field 3 = True String
12013 * Field 4 = False String
12014 */
12015void
12016proto_registrar_dump_values(void)
12017{
12018 header_field_info *hfinfo;
12019 int i, len, vi;
12020 const value_string *vals;
12021 const val64_string *vals64;
12022 const range_string *range;
12023 const true_false_string *tfs;
12024 const unit_name_string *units;
12025
12026 len = gpa_hfinfo.len;
12027 for (i = 1; i < len ; i++) {
12028 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12029 continue; /* This is a deregistered protocol or field */
12030
12031 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", 12031
, __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", 12031
, "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", 12031, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12032
12033 if (hfinfo->id == hf_text_only) {
12034 continue;
12035 }
12036
12037 /* ignore protocols */
12038 if (proto_registrar_is_protocol(i)) {
12039 continue;
12040 }
12041 /* process header fields */
12042#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12043 /*
12044 * If this field isn't at the head of the list of
12045 * fields with this name, skip this field - all
12046 * fields with the same name are really just versions
12047 * of the same field stored in different bits, and
12048 * should have the same type/radix/value list, and
12049 * just differ in their bit masks. (If a field isn't
12050 * a bitfield, but can be, say, 1 or 2 bytes long,
12051 * it can just be made FT_UINT16, meaning the
12052 * *maximum* length is 2 bytes, and be used
12053 * for all lengths.)
12054 */
12055 if (hfinfo->same_name_prev_id != -1)
12056 continue;
12057#endif
12058 vals = NULL((void*)0);
12059 vals64 = NULL((void*)0);
12060 range = NULL((void*)0);
12061 tfs = NULL((void*)0);
12062 units = NULL((void*)0);
12063
12064 if (hfinfo->strings != NULL((void*)0)) {
12065 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12066 (hfinfo->type == FT_CHAR ||
12067 hfinfo->type == FT_UINT8 ||
12068 hfinfo->type == FT_UINT16 ||
12069 hfinfo->type == FT_UINT24 ||
12070 hfinfo->type == FT_UINT32 ||
12071 hfinfo->type == FT_UINT40 ||
12072 hfinfo->type == FT_UINT48 ||
12073 hfinfo->type == FT_UINT56 ||
12074 hfinfo->type == FT_UINT64 ||
12075 hfinfo->type == FT_INT8 ||
12076 hfinfo->type == FT_INT16 ||
12077 hfinfo->type == FT_INT24 ||
12078 hfinfo->type == FT_INT32 ||
12079 hfinfo->type == FT_INT40 ||
12080 hfinfo->type == FT_INT48 ||
12081 hfinfo->type == FT_INT56 ||
12082 hfinfo->type == FT_INT64 ||
12083 hfinfo->type == FT_FLOAT ||
12084 hfinfo->type == FT_DOUBLE)) {
12085
12086 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12087 range = (const range_string *)hfinfo->strings;
12088 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12089 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12090 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12091 } else {
12092 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12093 }
12094 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12095 vals64 = (const val64_string *)hfinfo->strings;
12096 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12097 units = (const unit_name_string *)hfinfo->strings;
12098 } else {
12099 vals = (const value_string *)hfinfo->strings;
12100 }
12101 }
12102 else if (hfinfo->type == FT_BOOLEAN) {
12103 tfs = (const struct true_false_string *)hfinfo->strings;
12104 }
12105 }
12106
12107 /* Print value strings? */
12108 if (vals) {
12109 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12110 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12111 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12112 if (!val64_string_ext_validate(vse_p)) {
12113 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12113, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12114 continue;
12115 }
12116 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12117 printf("E\t%s\t%u\t%s\t%s\n",
12118 hfinfo->abbrev,
12119 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12120 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12121 val64_string_ext_match_type_str(vse_p));
12122 } else {
12123 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12124 if (!value_string_ext_validate(vse_p)) {
12125 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12125, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12126 continue;
12127 }
12128 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12129 printf("E\t%s\t%u\t%s\t%s\n",
12130 hfinfo->abbrev,
12131 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12132 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12133 value_string_ext_match_type_str(vse_p));
12134 }
12135 }
12136 vi = 0;
12137 while (vals[vi].strptr) {
12138 /* Print in the proper base */
12139 if (hfinfo->type == FT_CHAR) {
12140 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12141 printf("V\t%s\t'%c'\t%s\n",
12142 hfinfo->abbrev,
12143 vals[vi].value,
12144 vals[vi].strptr);
12145 } else {
12146 if (hfinfo->display == BASE_HEX) {
12147 printf("V\t%s\t'\\x%02x'\t%s\n",
12148 hfinfo->abbrev,
12149 vals[vi].value,
12150 vals[vi].strptr);
12151 }
12152 else {
12153 printf("V\t%s\t'\\%03o'\t%s\n",
12154 hfinfo->abbrev,
12155 vals[vi].value,
12156 vals[vi].strptr);
12157 }
12158 }
12159 } else {
12160 if (hfinfo->display == BASE_HEX) {
12161 printf("V\t%s\t0x%x\t%s\n",
12162 hfinfo->abbrev,
12163 vals[vi].value,
12164 vals[vi].strptr);
12165 }
12166 else {
12167 printf("V\t%s\t%u\t%s\n",
12168 hfinfo->abbrev,
12169 vals[vi].value,
12170 vals[vi].strptr);
12171 }
12172 }
12173 vi++;
12174 }
12175 }
12176 else if (vals64) {
12177 vi = 0;
12178 while (vals64[vi].strptr) {
12179 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12180 hfinfo->abbrev,
12181 vals64[vi].value,
12182 vals64[vi].strptr);
12183 vi++;
12184 }
12185 }
12186
12187 /* print range strings? */
12188 else if (range) {
12189 vi = 0;
12190 while (range[vi].strptr) {
12191 /* Print in the proper base */
12192 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12193 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12194 hfinfo->abbrev,
12195 range[vi].value_min,
12196 range[vi].value_max,
12197 range[vi].strptr);
12198 }
12199 else {
12200 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12201 hfinfo->abbrev,
12202 range[vi].value_min,
12203 range[vi].value_max,
12204 range[vi].strptr);
12205 }
12206 vi++;
12207 }
12208 }
12209
12210 /* Print true/false strings? */
12211 else if (tfs) {
12212 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12213 tfs->true_string, tfs->false_string);
12214 }
12215 /* Print unit strings? */
12216 else if (units) {
12217 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12218 units->singular, units->plural ? units->plural : "(no plural)");
12219 }
12220 }
12221}
12222
12223/* Prints the number of registered fields.
12224 * Useful for determining an appropriate value for
12225 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12226 *
12227 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12228 * the number of fields, true otherwise.
12229 */
12230bool_Bool
12231proto_registrar_dump_fieldcount(void)
12232{
12233 struct proto_registrar_stats stats = {0, 0, 0};
12234 size_t total_count = proto_registrar_get_count(&stats);
12235
12236 printf("There are %zu header fields registered, of which:\n"
12237 "\t%zu are deregistered\n"
12238 "\t%zu are protocols\n"
12239 "\t%zu have the same name as another field\n\n",
12240 total_count, stats.deregistered_count, stats.protocol_count,
12241 stats.same_name_count);
12242
12243 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12244 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12245 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12246 "\n");
12247
12248 printf("The header field table consumes %u KiB of memory.\n",
12249 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12250 printf("The fields themselves consume %u KiB of memory.\n",
12251 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12252
12253 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12254}
12255
12256static void
12257elastic_add_base_mapping(json_dumper *dumper)
12258{
12259 json_dumper_set_member_name(dumper, "index_patterns");
12260 json_dumper_begin_array(dumper);
12261 // The index names from write_json_index() in print.c
12262 json_dumper_value_string(dumper, "packets-*");
12263 json_dumper_end_array(dumper);
12264
12265 json_dumper_set_member_name(dumper, "settings");
12266 json_dumper_begin_object(dumper);
12267 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12268 json_dumper_value_anyf(dumper, "%d", 1000000);
12269 json_dumper_end_object(dumper);
12270}
12271
12272static char*
12273ws_type_to_elastic(unsigned type)
12274{
12275 switch(type) {
12276 case FT_INT8:
12277 return "byte";
12278 case FT_UINT8:
12279 case FT_INT16:
12280 return "short";
12281 case FT_UINT16:
12282 case FT_INT32:
12283 case FT_UINT24:
12284 case FT_INT24:
12285 return "integer";
12286 case FT_FRAMENUM:
12287 case FT_UINT32:
12288 case FT_UINT40:
12289 case FT_UINT48:
12290 case FT_UINT56:
12291 case FT_INT40:
12292 case FT_INT48:
12293 case FT_INT56:
12294 case FT_INT64:
12295 return "long";
12296 case FT_UINT64:
12297 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12298 case FT_FLOAT:
12299 return "float";
12300 case FT_DOUBLE:
12301 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12302 return "double";
12303 case FT_IPv6:
12304 case FT_IPv4:
12305 return "ip";
12306 case FT_ABSOLUTE_TIME:
12307 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12308 case FT_BOOLEAN:
12309 return "boolean";
12310 default:
12311 return NULL((void*)0);
12312 }
12313}
12314
12315static char*
12316dot_to_underscore(char* str)
12317{
12318 unsigned i;
12319 for (i = 0; i < strlen(str); i++) {
12320 if (str[i] == '.')
12321 str[i] = '_';
12322 }
12323 return str;
12324}
12325
12326/* Dumps a mapping file for ElasticSearch
12327 * This is the v1 (legacy) _template API.
12328 * At some point it may need to be updated with the composable templates
12329 * introduced in Elasticsearch 7.8 (_index_template)
12330 */
12331void
12332proto_registrar_dump_elastic(const char* filter)
12333{
12334 header_field_info *hfinfo;
12335 header_field_info *parent_hfinfo;
12336 unsigned i;
12337 bool_Bool open_object = true1;
12338 const char* prev_proto = NULL((void*)0);
12339 char* str;
12340 char** protos = NULL((void*)0);
12341 char* proto;
12342 bool_Bool found;
12343 unsigned j;
12344 char* type;
12345 char* prev_item = NULL((void*)0);
12346
12347 /* We have filtering protocols. Extract them. */
12348 if (filter) {
12349 protos = g_strsplit(filter, ",", -1);
12350 }
12351
12352 /*
12353 * To help tracking down the json tree, objects have been appended with a comment:
12354 * n.label -> where n is the indentation level and label the name of the object
12355 */
12356
12357 json_dumper dumper = {
12358 .output_file = stdoutstdout,
12359 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12360 };
12361 json_dumper_begin_object(&dumper); // 1.root
12362 elastic_add_base_mapping(&dumper);
12363
12364 json_dumper_set_member_name(&dumper, "mappings");
12365 json_dumper_begin_object(&dumper); // 2.mappings
12366
12367 json_dumper_set_member_name(&dumper, "properties");
12368 json_dumper_begin_object(&dumper); // 3.properties
12369 json_dumper_set_member_name(&dumper, "timestamp");
12370 json_dumper_begin_object(&dumper); // 4.timestamp
12371 json_dumper_set_member_name(&dumper, "type");
12372 json_dumper_value_string(&dumper, "date");
12373 json_dumper_end_object(&dumper); // 4.timestamp
12374
12375 json_dumper_set_member_name(&dumper, "layers");
12376 json_dumper_begin_object(&dumper); // 4.layers
12377 json_dumper_set_member_name(&dumper, "properties");
12378 json_dumper_begin_object(&dumper); // 5.properties
12379
12380 for (i = 1; i < gpa_hfinfo.len; i++) {
12381 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12382 continue; /* This is a deregistered protocol or header field */
12383
12384 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", 12384
, __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", 12384
, "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", 12384, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12385
12386 /*
12387 * Skip the pseudo-field for "proto_tree_add_text()" since
12388 * we don't want it in the list of filterable protocols.
12389 */
12390 if (hfinfo->id == hf_text_only)
12391 continue;
12392
12393 if (!proto_registrar_is_protocol(i)) {
12394 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", 12394
, __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", 12394
, "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", 12394
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12395
12396 /*
12397 * Skip the field if filter protocols have been set and this one's
12398 * parent is not listed.
12399 */
12400 if (protos) {
12401 found = false0;
12402 j = 0;
12403 proto = protos[0];
12404 while(proto) {
12405 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12406 found = true1;
12407 break;
12408 }
12409 j++;
12410 proto = protos[j];
12411 }
12412 if (!found)
12413 continue;
12414 }
12415
12416 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12417 json_dumper_end_object(&dumper); // 7.properties
12418 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12419 open_object = true1;
12420 }
12421
12422 prev_proto = parent_hfinfo->abbrev;
12423
12424 if (open_object) {
12425 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12426 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12427 json_dumper_set_member_name(&dumper, "properties");
12428 json_dumper_begin_object(&dumper); // 7.properties
12429 open_object = false0;
12430 }
12431 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12432 type = ws_type_to_elastic(hfinfo->type);
12433 /* when type is NULL, we have the default mapping: string */
12434 if (type) {
12435 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12436 dot_to_underscore(str);
12437 if (g_strcmp0(prev_item, str)) {
12438 json_dumper_set_member_name(&dumper, str);
12439 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12440 json_dumper_set_member_name(&dumper, "type");
12441 json_dumper_value_string(&dumper, type);
12442 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12443 }
12444 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)
;
12445 prev_item = str;
12446 }
12447 }
12448 }
12449 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)
;
12450
12451 if (prev_proto) {
12452 json_dumper_end_object(&dumper); // 7.properties
12453 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12454 }
12455
12456 json_dumper_end_object(&dumper); // 5.properties
12457 json_dumper_end_object(&dumper); // 4.layers
12458 json_dumper_end_object(&dumper); // 3.properties
12459 json_dumper_end_object(&dumper); // 2.mappings
12460 json_dumper_end_object(&dumper); // 1.root
12461 bool_Bool ret = json_dumper_finish(&dumper);
12462 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12462, "ret"))))
;
12463
12464 g_strfreev(protos);
12465}
12466
12467/* Dumps the contents of the registration database to stdout. An independent
12468 * program can take this output and format it into nice tables or HTML or
12469 * whatever.
12470 *
12471 * There is one record per line. Each record is either a protocol or a header
12472 * field, differentiated by the first field. The fields are tab-delimited.
12473 *
12474 * Protocols
12475 * ---------
12476 * Field 1 = 'P'
12477 * Field 2 = descriptive protocol name
12478 * Field 3 = protocol abbreviation
12479 *
12480 * Header Fields
12481 * -------------
12482 * Field 1 = 'F'
12483 * Field 2 = descriptive field name
12484 * Field 3 = field abbreviation
12485 * Field 4 = type ( textual representation of the ftenum type )
12486 * Field 5 = parent protocol abbreviation
12487 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12488 * Field 7 = bitmask: format: hex: 0x....
12489 * Field 8 = blurb describing field
12490 */
12491void
12492proto_registrar_dump_fields(void)
12493{
12494 header_field_info *hfinfo, *parent_hfinfo;
12495 int i, len;
12496 const char *enum_name;
12497 const char *base_name;
12498 const char *blurb;
12499 char width[5];
12500
12501 len = gpa_hfinfo.len;
12502 for (i = 1; i < len ; i++) {
12503 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12504 continue; /* This is a deregistered protocol or header field */
12505
12506 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", 12506
, __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", 12506
, "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", 12506, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12507
12508 /*
12509 * Skip the pseudo-field for "proto_tree_add_text()" since
12510 * we don't want it in the list of filterable fields.
12511 */
12512 if (hfinfo->id == hf_text_only)
12513 continue;
12514
12515 /* format for protocols */
12516 if (proto_registrar_is_protocol(i)) {
12517 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12518 }
12519 /* format for header fields */
12520 else {
12521 /*
12522 * If this field isn't at the head of the list of
12523 * fields with this name, skip this field - all
12524 * fields with the same name are really just versions
12525 * of the same field stored in different bits, and
12526 * should have the same type/radix/value list, and
12527 * just differ in their bit masks. (If a field isn't
12528 * a bitfield, but can be, say, 1 or 2 bytes long,
12529 * it can just be made FT_UINT16, meaning the
12530 * *maximum* length is 2 bytes, and be used
12531 * for all lengths.)
12532 */
12533 if (hfinfo->same_name_prev_id != -1)
12534 continue;
12535
12536 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12536
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12536
, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12536
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12537
12538 enum_name = ftype_name(hfinfo->type);
12539 base_name = "";
12540
12541 if (hfinfo->type == FT_CHAR ||
12542 hfinfo->type == FT_UINT8 ||
12543 hfinfo->type == FT_UINT16 ||
12544 hfinfo->type == FT_UINT24 ||
12545 hfinfo->type == FT_UINT32 ||
12546 hfinfo->type == FT_UINT40 ||
12547 hfinfo->type == FT_UINT48 ||
12548 hfinfo->type == FT_UINT56 ||
12549 hfinfo->type == FT_UINT64 ||
12550 hfinfo->type == FT_INT8 ||
12551 hfinfo->type == FT_INT16 ||
12552 hfinfo->type == FT_INT24 ||
12553 hfinfo->type == FT_INT32 ||
12554 hfinfo->type == FT_INT40 ||
12555 hfinfo->type == FT_INT48 ||
12556 hfinfo->type == FT_INT56 ||
12557 hfinfo->type == FT_INT64) {
12558
12559 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12560 case BASE_NONE:
12561 case BASE_DEC:
12562 case BASE_HEX:
12563 case BASE_OCT:
12564 case BASE_DEC_HEX:
12565 case BASE_HEX_DEC:
12566 case BASE_CUSTOM:
12567 case BASE_PT_UDP:
12568 case BASE_PT_TCP:
12569 case BASE_PT_DCCP:
12570 case BASE_PT_SCTP:
12571 case BASE_OUI:
12572 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12573 break;
12574 default:
12575 base_name = "????";
12576 break;
12577 }
12578 } else if (hfinfo->type == FT_BOOLEAN) {
12579 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12580 snprintf(width, sizeof(width), "%d", hfinfo->display);
12581 base_name = width;
12582 }
12583
12584 blurb = hfinfo->blurb;
12585 if (blurb == NULL((void*)0))
12586 blurb = "";
12587 else if (strlen(blurb) == 0)
12588 blurb = "\"\"";
12589
12590 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12591 hfinfo->name, hfinfo->abbrev, enum_name,
12592 parent_hfinfo->abbrev, base_name,
12593 hfinfo->bitmask, blurb);
12594 }
12595 }
12596}
12597
12598/* Dumps all abbreviated field and protocol completions of the given string to
12599 * stdout. An independent program may use this for command-line tab completion
12600 * of fields.
12601 */
12602bool_Bool
12603proto_registrar_dump_field_completions(const char *prefix)
12604{
12605 header_field_info *hfinfo;
12606 int i, len;
12607 size_t prefix_len;
12608 bool_Bool matched = false0;
12609
12610 prefix_len = strlen(prefix);
12611 len = gpa_hfinfo.len;
12612 for (i = 1; i < len ; i++) {
12613 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12614 continue; /* This is a deregistered protocol or header field */
12615
12616 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", 12616
, __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", 12616
, "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", 12616, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12617
12618 /*
12619 * Skip the pseudo-field for "proto_tree_add_text()" since
12620 * we don't want it in the list of filterable fields.
12621 */
12622 if (hfinfo->id == hf_text_only)
12623 continue;
12624
12625 /* format for protocols */
12626 if (proto_registrar_is_protocol(i)) {
12627 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12628 matched = true1;
12629 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12630 }
12631 }
12632 /* format for header fields */
12633 else {
12634 /*
12635 * If this field isn't at the head of the list of
12636 * fields with this name, skip this field - all
12637 * fields with the same name are really just versions
12638 * of the same field stored in different bits, and
12639 * should have the same type/radix/value list, and
12640 * just differ in their bit masks. (If a field isn't
12641 * a bitfield, but can be, say, 1 or 2 bytes long,
12642 * it can just be made FT_UINT16, meaning the
12643 * *maximum* length is 2 bytes, and be used
12644 * for all lengths.)
12645 */
12646 if (hfinfo->same_name_prev_id != -1)
12647 continue;
12648
12649 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12650 matched = true1;
12651 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12652 }
12653 }
12654 }
12655 return matched;
12656}
12657
12658/* Dumps field types and descriptive names to stdout. An independent
12659 * program can take this output and format it into nice tables or HTML or
12660 * whatever.
12661 *
12662 * There is one record per line. The fields are tab-delimited.
12663 *
12664 * Field 1 = field type name, e.g. FT_UINT8
12665 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12666 */
12667void
12668proto_registrar_dump_ftypes(void)
12669{
12670 int fte;
12671
12672 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12673 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12674 }
12675}
12676
12677/* This function indicates whether it's possible to construct a
12678 * "match selected" display filter string for the specified field,
12679 * returns an indication of whether it's possible, and, if it's
12680 * possible and "filter" is non-null, constructs the filter and
12681 * sets "*filter" to point to it.
12682 * You do not need to [g_]free() this string since it will be automatically
12683 * freed once the next packet is dissected.
12684 */
12685static bool_Bool
12686construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12687 char **filter)
12688{
12689 const header_field_info *hfinfo;
12690 int start, length, length_remaining;
12691
12692 if (!finfo)
12693 return false0;
12694
12695 hfinfo = finfo->hfinfo;
12696 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12696, "hfinfo"))))
;
12697
12698 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12699 * then "the numeric value ... is not used when preparing
12700 * filters for the field in question." If it's any other
12701 * base, we'll generate the filter normally (which will
12702 * be numeric, even though the human-readable string does
12703 * work for filtering.)
12704 *
12705 * XXX - It might be nice to use fvalue_to_string_repr() in
12706 * "proto_item_fill_label()" as well, although, there, you'd
12707 * have to deal with the base *and* with resolved values for
12708 * addresses.
12709 *
12710 * Perhaps in addition to taking the repr type (DISPLAY
12711 * or DFILTER) and the display (base), fvalue_to_string_repr()
12712 * should have the the "strings" values in the header_field_info
12713 * structure for the field as a parameter, so it can have
12714 * if the field is Boolean or an enumerated integer type,
12715 * the tables used to generate human-readable values.
12716 */
12717 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12718 const char *str = NULL((void*)0);
12719
12720 switch (hfinfo->type) {
12721
12722 case FT_INT8:
12723 case FT_INT16:
12724 case FT_INT24:
12725 case FT_INT32:
12726 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12727 break;
12728
12729 case FT_CHAR:
12730 case FT_UINT8:
12731 case FT_UINT16:
12732 case FT_UINT24:
12733 case FT_UINT32:
12734 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12735 break;
12736
12737 default:
12738 break;
12739 }
12740
12741 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12742 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12743 return true1;
12744 }
12745 }
12746
12747 switch (hfinfo->type) {
12748
12749 case FT_PROTOCOL:
12750 if (filter != NULL((void*)0))
12751 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12752 break;
12753
12754 case FT_NONE:
12755 /*
12756 * If the length is 0, just match the name of the
12757 * field.
12758 *
12759 * (Also check for negative values, just in case,
12760 * as we'll cast it to an unsigned value later.)
12761 */
12762 length = finfo->length;
12763 if (length == 0) {
12764 if (filter != NULL((void*)0))
12765 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12766 break;
12767 }
12768 if (length < 0)
12769 return false0;
12770
12771 /*
12772 * This doesn't have a value, so we'd match
12773 * on the raw bytes at this address.
12774 *
12775 * Should we be allowed to access to the raw bytes?
12776 * If "edt" is NULL, the answer is "no".
12777 */
12778 if (edt == NULL((void*)0))
12779 return false0;
12780
12781 /*
12782 * Is this field part of the raw frame tvbuff?
12783 * If not, we can't use "frame[N:M]" to match
12784 * it.
12785 *
12786 * XXX - should this be frame-relative, or
12787 * protocol-relative?
12788 *
12789 * XXX - does this fallback for non-registered
12790 * fields even make sense?
12791 */
12792 if (finfo->ds_tvb != edt->tvb)
12793 return false0; /* you lose */
12794
12795 /*
12796 * Don't go past the end of that tvbuff.
12797 */
12798 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12799 if (length > length_remaining)
12800 length = length_remaining;
12801 if (length <= 0)
12802 return false0;
12803
12804 if (filter != NULL((void*)0)) {
12805 start = finfo->start;
12806 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12807 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12808 wmem_free(NULL((void*)0), str);
12809 }
12810 break;
12811
12812 /* By default, use the fvalue's "to_string_repr" method. */
12813 default:
12814 if (filter != NULL((void*)0)) {
12815 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12816 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12817 wmem_free(NULL((void*)0), str);
12818 }
12819 break;
12820 }
12821
12822 return true1;
12823}
12824
12825/*
12826 * Returns true if we can do a "match selected" on the field, false
12827 * otherwise.
12828 */
12829bool_Bool
12830proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12831{
12832 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12833}
12834
12835/* This function attempts to construct a "match selected" display filter
12836 * string for the specified field; if it can do so, it returns a pointer
12837 * to the string, otherwise it returns NULL.
12838 *
12839 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12840 */
12841char *
12842proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12843{
12844 char *filter = NULL((void*)0);
12845
12846 if (!construct_match_selected_string(finfo, edt, &filter))
12847 {
12848 wmem_free(NULL((void*)0), filter);
12849 return NULL((void*)0);
12850 }
12851 return filter;
12852}
12853
12854/* This function is common code for all proto_tree_add_bitmask... functions.
12855 */
12856
12857static bool_Bool
12858proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12859 const unsigned len, const int ett, int * const *fields,
12860 const int flags, bool_Bool first,
12861 bool_Bool use_parent_tree,
12862 proto_tree* tree, uint64_t value)
12863{
12864 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12865 uint64_t bitmask = 0;
12866 uint64_t tmpval;
12867 header_field_info *hf;
12868 uint32_t integer32;
12869 int bit_offset;
12870 int no_of_bits;
12871
12872 if (!*fields)
12873 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"
)
;
12874
12875 if (len > 8)
12876 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12877 /**
12878 * packet-frame.c uses len=0 since the value is taken from the packet
12879 * metadata, not the packet bytes. In that case, assume that all bits
12880 * in the provided value are valid.
12881 */
12882 if (len > 0) {
12883 available_bits >>= (8 - len)*8;
12884 }
12885
12886 if (use_parent_tree == false0)
12887 tree = proto_item_add_subtree(item, ett);
12888
12889 while (*fields) {
12890 uint64_t present_bits;
12891 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", 12891, __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", 12891
, "**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", 12891, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12892 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", 12892
, "hf->bitmask != 0", hf->abbrev))))
;
12893
12894 bitmask |= hf->bitmask;
12895
12896 /* Skip fields that aren't fully present */
12897 present_bits = available_bits & hf->bitmask;
12898 if (present_bits != hf->bitmask) {
12899 fields++;
12900 continue;
12901 }
12902
12903 switch (hf->type) {
12904 case FT_CHAR:
12905 case FT_UINT8:
12906 case FT_UINT16:
12907 case FT_UINT24:
12908 case FT_UINT32:
12909 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12910 break;
12911
12912 case FT_INT8:
12913 case FT_INT16:
12914 case FT_INT24:
12915 case FT_INT32:
12916 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12917 break;
12918
12919 case FT_UINT40:
12920 case FT_UINT48:
12921 case FT_UINT56:
12922 case FT_UINT64:
12923 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12924 break;
12925
12926 case FT_INT40:
12927 case FT_INT48:
12928 case FT_INT56:
12929 case FT_INT64:
12930 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12931 break;
12932
12933 case FT_BOOLEAN:
12934 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12935 break;
12936
12937 default:
12938 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))
12939 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))
12940 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))
12941 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))
;
12942 break;
12943 }
12944 if (flags & BMT_NO_APPEND0x01) {
12945 fields++;
12946 continue;
12947 }
12948 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12949
12950 /* XXX: README.developer and the comments have always defined
12951 * BMT_NO_INT as "only boolean flags are added to the title /
12952 * don't add non-boolean (integral) fields", but the
12953 * implementation has always added BASE_CUSTOM and fields with
12954 * value_strings, though not fields with unit_strings.
12955 * Possibly this is because some dissectors use a FT_UINT8
12956 * with a value_string for fields that should be a FT_BOOLEAN.
12957 */
12958 switch (hf->type) {
12959 case FT_CHAR:
12960 if (hf->display == BASE_CUSTOM) {
12961 char lbl[ITEM_LABEL_LENGTH240];
12962 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12963
12964 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12964, "fmtfunc"))))
;
12965 fmtfunc(lbl, (uint32_t) tmpval);
12966 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12967 hf->name, lbl);
12968 first = false0;
12969 }
12970 else if (hf->strings) {
12971 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12972 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12973 first = false0;
12974 }
12975 else if (!(flags & BMT_NO_INT0x02)) {
12976 char buf[32];
12977 const char *out;
12978
12979 if (!first) {
12980 proto_item_append_text(item, ", ");
12981 }
12982
12983 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12984 proto_item_append_text(item, "%s: %s", hf->name, out);
12985 first = false0;
12986 }
12987
12988 break;
12989
12990 case FT_UINT8:
12991 case FT_UINT16:
12992 case FT_UINT24:
12993 case FT_UINT32:
12994 if (hf->display == BASE_CUSTOM) {
12995 char lbl[ITEM_LABEL_LENGTH240];
12996 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12997
12998 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12998, "fmtfunc"))))
;
12999 fmtfunc(lbl, (uint32_t) tmpval);
13000 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13001 hf->name, lbl);
13002 first = false0;
13003 }
13004 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13005 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13006 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13007 first = false0;
13008 }
13009 else if (!(flags & BMT_NO_INT0x02)) {
13010 char buf[NUMBER_LABEL_LENGTH80];
13011 const char *out = NULL((void*)0);
13012
13013 if (!first) {
13014 proto_item_append_text(item, ", ");
13015 }
13016
13017 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13018 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13019 }
13020 if (out == NULL((void*)0)) {
13021 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13022 }
13023 proto_item_append_text(item, "%s: %s", hf->name, out);
13024 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13025 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13026 }
13027 first = false0;
13028 }
13029
13030 break;
13031
13032 case FT_INT8:
13033 case FT_INT16:
13034 case FT_INT24:
13035 case FT_INT32:
13036 integer32 = (uint32_t) tmpval;
13037 if (hf->bitmask) {
13038 no_of_bits = ws_count_ones(hf->bitmask);
13039 integer32 = ws_sign_ext32(integer32, no_of_bits);
13040 }
13041 if (hf->display == BASE_CUSTOM) {
13042 char lbl[ITEM_LABEL_LENGTH240];
13043 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13044
13045 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13045, "fmtfunc"))))
;
13046 fmtfunc(lbl, (int32_t) integer32);
13047 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13048 hf->name, lbl);
13049 first = false0;
13050 }
13051 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13052 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13053 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13054 first = false0;
13055 }
13056 else if (!(flags & BMT_NO_INT0x02)) {
13057 char buf[NUMBER_LABEL_LENGTH80];
13058 const char *out = NULL((void*)0);
13059
13060 if (!first) {
13061 proto_item_append_text(item, ", ");
13062 }
13063
13064 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13065 out = hf_try_val_to_str((int32_t) integer32, hf);
13066 }
13067 if (out == NULL((void*)0)) {
13068 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13069 }
13070 proto_item_append_text(item, "%s: %s", hf->name, out);
13071 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13072 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13073 }
13074 first = false0;
13075 }
13076
13077 break;
13078
13079 case FT_UINT40:
13080 case FT_UINT48:
13081 case FT_UINT56:
13082 case FT_UINT64:
13083 if (hf->display == BASE_CUSTOM) {
13084 char lbl[ITEM_LABEL_LENGTH240];
13085 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13086
13087 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13087, "fmtfunc"))))
;
13088 fmtfunc(lbl, tmpval);
13089 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13090 hf->name, lbl);
13091 first = false0;
13092 }
13093 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13094 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13095 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13096 first = false0;
13097 }
13098 else if (!(flags & BMT_NO_INT0x02)) {
13099 char buf[NUMBER_LABEL_LENGTH80];
13100 const char *out = NULL((void*)0);
13101
13102 if (!first) {
13103 proto_item_append_text(item, ", ");
13104 }
13105
13106 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13107 out = hf_try_val64_to_str(tmpval, hf);
13108 }
13109 if (out == NULL((void*)0)) {
13110 out = hfinfo_number_value_format64(hf, buf, tmpval);
13111 }
13112 proto_item_append_text(item, "%s: %s", hf->name, out);
13113 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13114 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13115 }
13116 first = false0;
13117 }
13118
13119 break;
13120
13121 case FT_INT40:
13122 case FT_INT48:
13123 case FT_INT56:
13124 case FT_INT64:
13125 if (hf->bitmask) {
13126 no_of_bits = ws_count_ones(hf->bitmask);
13127 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13128 }
13129 if (hf->display == BASE_CUSTOM) {
13130 char lbl[ITEM_LABEL_LENGTH240];
13131 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13132
13133 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13133, "fmtfunc"))))
;
13134 fmtfunc(lbl, (int64_t) tmpval);
13135 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13136 hf->name, lbl);
13137 first = false0;
13138 }
13139 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13140 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13141 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13142 first = false0;
13143 }
13144 else if (!(flags & BMT_NO_INT0x02)) {
13145 char buf[NUMBER_LABEL_LENGTH80];
13146 const char *out = NULL((void*)0);
13147
13148 if (!first) {
13149 proto_item_append_text(item, ", ");
13150 }
13151
13152 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13153 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13154 }
13155 if (out == NULL((void*)0)) {
13156 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13157 }
13158 proto_item_append_text(item, "%s: %s", hf->name, out);
13159 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13160 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13161 }
13162 first = false0;
13163 }
13164
13165 break;
13166
13167 case FT_BOOLEAN:
13168 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13169 /* If we have true/false strings, emit full - otherwise messages
13170 might look weird */
13171 const struct true_false_string *tfs =
13172 (const struct true_false_string *)hf->strings;
13173
13174 if (tmpval) {
13175 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13176 hf->name, tfs->true_string);
13177 first = false0;
13178 } else if (!(flags & BMT_NO_FALSE0x04)) {
13179 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13180 hf->name, tfs->false_string);
13181 first = false0;
13182 }
13183 } else if (hf->bitmask & value) {
13184 /* If the flag is set, show the name */
13185 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13186 first = false0;
13187 }
13188 break;
13189 default:
13190 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))
13191 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))
13192 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))
13193 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))
;
13194 break;
13195 }
13196
13197 fields++;
13198 }
13199
13200 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13201 * but then again most dissectors don't set the bitmask field for
13202 * the higher level bitmask hfi, so calculate the bitmask from the
13203 * fields present. */
13204 if (item) {
13205 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13206 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13207 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)
;
13208 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)
;
13209 }
13210 return first;
13211}
13212
13213/* This function will dissect a sequence of bytes that describe a
13214 * bitmask and supply the value of that sequence through a pointer.
13215 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13216 * to be dissected.
13217 * This field will form an expansion under which the individual fields of the
13218 * bitmask is dissected and displayed.
13219 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13220 *
13221 * fields is an array of pointers to int that lists all the fields of the
13222 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13223 * or another integer of the same type/size as hf_hdr with a mask specified.
13224 * This array is terminated by a NULL entry.
13225 *
13226 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13227 * FT_integer fields that have a value_string attached will have the
13228 * matched string displayed on the expansion line.
13229 */
13230proto_item *
13231proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13232 const unsigned offset, const int hf_hdr,
13233 const int ett, int * const *fields,
13234 const unsigned encoding, uint64_t *retval)
13235{
13236 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);
13237}
13238
13239/* This function will dissect a sequence of bytes that describe a
13240 * bitmask.
13241 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13242 * to be dissected.
13243 * This field will form an expansion under which the individual fields of the
13244 * bitmask is dissected and displayed.
13245 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13246 *
13247 * fields is an array of pointers to int that lists all the fields of the
13248 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13249 * or another integer of the same type/size as hf_hdr with a mask specified.
13250 * This array is terminated by a NULL entry.
13251 *
13252 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13253 * FT_integer fields that have a value_string attached will have the
13254 * matched string displayed on the expansion line.
13255 */
13256proto_item *
13257proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13258 const unsigned offset, const int hf_hdr,
13259 const int ett, int * const *fields,
13260 const unsigned encoding)
13261{
13262 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13263}
13264
13265/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13266 * what data is appended to the header.
13267 */
13268proto_item *
13269proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13270 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13271 uint64_t *retval)
13272{
13273 proto_item *item = NULL((void*)0);
13274 header_field_info *hf;
13275 unsigned len;
13276 uint64_t value;
13277
13278 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", 13278, __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", 13278
, "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", 13278, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13279 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", 13279, (hf)->abbrev)))
;
13280 len = ftype_wire_size(hf->type);
13281 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13282
13283 if (parent_tree) {
13284 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13285 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13286 flags, false0, false0, NULL((void*)0), value);
13287 }
13288
13289 *retval = value;
13290 if (hf->bitmask) {
13291 /* Mask out irrelevant portions */
13292 *retval &= hf->bitmask;
13293 /* Shift bits */
13294 *retval >>= hfinfo_bitshift(hf);
13295 }
13296
13297 return item;
13298}
13299
13300/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13301 * what data is appended to the header.
13302 */
13303proto_item *
13304proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13305 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13306{
13307 proto_item *item = NULL((void*)0);
13308 header_field_info *hf;
13309 unsigned len;
13310 uint64_t value;
13311
13312 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", 13312, __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", 13312
, "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", 13312, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13313 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", 13313, (hf)->abbrev)))
;
13314
13315 if (parent_tree) {
13316 len = ftype_wire_size(hf->type);
13317 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13318 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13319 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13320 flags, false0, false0, NULL((void*)0), value);
13321 }
13322
13323 return item;
13324}
13325
13326/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13327 can't be retrieved directly from tvb) */
13328proto_item *
13329proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13330 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13331{
13332 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13333 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13334}
13335
13336/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13337WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13338proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13339 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13340{
13341 proto_item *item = NULL((void*)0);
13342 header_field_info *hf;
13343 unsigned len;
13344
13345 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", 13345, __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", 13345
, "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", 13345, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13346 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", 13346, (hf)->abbrev)))
;
13347 /* the proto_tree_add_uint/_uint64() calls below
13348 will fail if tvb==NULL and len!=0 */
13349 len = tvb ? ftype_wire_size(hf->type) : 0;
13350
13351 if (parent_tree) {
13352 if (len <= 4)
13353 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13354 else
13355 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13356
13357 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13358 flags, false0, false0, NULL((void*)0), value);
13359 }
13360
13361 return item;
13362}
13363
13364/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13365void
13366proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13367 const unsigned len, int * const *fields, const unsigned encoding)
13368{
13369 uint64_t value;
13370
13371 if (tree) {
13372 value = get_uint64_value(tree, tvb, offset, len, encoding);
13373 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13374 BMT_NO_APPEND0x01, false0, true1, tree, value);
13375 }
13376}
13377
13378WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13379proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13380 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13381{
13382 uint64_t value;
13383
13384 value = get_uint64_value(tree, tvb, offset, len, encoding);
13385 if (tree) {
13386 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13387 BMT_NO_APPEND0x01, false0, true1, tree, value);
13388 }
13389 if (retval) {
13390 *retval = value;
13391 }
13392}
13393
13394WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13395proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13396 const unsigned len, int * const *fields, const uint64_t value)
13397{
13398 if (tree) {
13399 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13400 BMT_NO_APPEND0x01, false0, true1, tree, value);
13401 }
13402}
13403
13404
13405/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13406 * This is intended to support bitmask fields whose lengths can vary, perhaps
13407 * as the underlying standard evolves over time.
13408 * With this API there is the possibility of being called to display more or
13409 * less data than the dissector was coded to support.
13410 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13411 * Thus when presented with "too much" or "too little" data, MSbits will be
13412 * ignored or MSfields sacrificed.
13413 *
13414 * Only fields for which all defined bits are available are displayed.
13415 */
13416proto_item *
13417proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13418 const unsigned offset, const unsigned len, const int hf_hdr,
13419 const int ett, int * const *fields, struct expert_field* exp,
13420 const unsigned encoding)
13421{
13422 proto_item *item = NULL((void*)0);
13423 header_field_info *hf;
13424 unsigned decodable_len;
13425 unsigned decodable_offset;
13426 uint32_t decodable_value;
13427 uint64_t value;
13428
13429 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", 13429, __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", 13429
, "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", 13429, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13430 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", 13430, (hf)->abbrev)))
;
13431
13432 decodable_offset = offset;
13433 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13434
13435 /* If we are ftype_wire_size-limited,
13436 * make sure we decode as many LSBs as possible.
13437 */
13438 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13439 decodable_offset += (len - decodable_len);
13440 }
13441
13442 if (parent_tree) {
13443 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13444 decodable_len, encoding);
13445
13446 /* The root item covers all the bytes even if we can't decode them all */
13447 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13448 decodable_value);
13449 }
13450
13451 if (decodable_len < len) {
13452 /* Dissector likely requires updating for new protocol revision */
13453 expert_add_info_format(NULL((void*)0), item, exp,
13454 "Only least-significant %d of %d bytes decoded",
13455 decodable_len, len);
13456 }
13457
13458 if (item) {
13459 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13460 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13461 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13462 }
13463
13464 return item;
13465}
13466
13467/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13468proto_item *
13469proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13470 const unsigned offset, const unsigned len,
13471 const char *name, const char *fallback,
13472 const int ett, int * const *fields,
13473 const unsigned encoding, const int flags)
13474{
13475 proto_item *item = NULL((void*)0);
13476 uint64_t value;
13477
13478 if (parent_tree) {
13479 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13480 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13481 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13482 flags, true1, false0, NULL((void*)0), value) && fallback) {
13483 /* Still at first item - append 'fallback' text if any */
13484 proto_item_append_text(item, "%s", fallback);
13485 }
13486 }
13487
13488 return item;
13489}
13490
13491proto_item *
13492proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13493 const unsigned bit_offset, const int no_of_bits,
13494 const unsigned encoding)
13495{
13496 header_field_info *hfinfo;
13497 int octet_length;
13498 unsigned octet_offset;
13499
13500 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", 13500, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13500
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13500, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13501
13502 if (no_of_bits < 0) {
13503 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13504 }
13505 octet_length = (no_of_bits + 7) >> 3;
13506 octet_offset = bit_offset >> 3;
13507 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13508
13509 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13510 * but only after doing a bunch more work (which we can, in the common
13511 * case, shortcut here).
13512 */
13513 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13514 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", 13514
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13514, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13514, "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", 13514, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13515
13516 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13517}
13518
13519/*
13520 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13521 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13522 * Offset should be given in bits from the start of the tvb.
13523 */
13524
13525static proto_item *
13526_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13527 const unsigned bit_offset, const int no_of_bits,
13528 uint64_t *return_value, const unsigned encoding)
13529{
13530 unsigned offset;
13531 unsigned length;
13532 uint8_t tot_no_bits;
13533 char *bf_str;
13534 char lbl_str[ITEM_LABEL_LENGTH240];
13535 uint64_t value = 0;
13536 uint8_t *bytes = NULL((void*)0);
13537 size_t bytes_length = 0;
13538
13539 proto_item *pi;
13540 header_field_info *hf_field;
13541
13542 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13543 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", 13543, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13543
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13543, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13544
13545 if (hf_field->bitmask != 0) {
13546 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)
13547 " 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)
13548 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)
;
13549 }
13550
13551 if (no_of_bits < 0) {
13552 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13553 } else if (no_of_bits == 0) {
13554 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)
13555 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)
;
13556 }
13557
13558 /* Byte align offset */
13559 offset = bit_offset>>3;
13560
13561 /*
13562 * Calculate the number of octets used to hold the bits
13563 */
13564 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13565 length = (tot_no_bits + 7) >> 3;
13566
13567 if (no_of_bits < 65) {
13568 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13569 } else if (hf_field->type != FT_BYTES) {
13570 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)
13571 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)
;
13572 return NULL((void*)0);
13573 }
13574
13575 /* Sign extend for signed types */
13576 switch (hf_field->type) {
13577 case FT_INT8:
13578 case FT_INT16:
13579 case FT_INT24:
13580 case FT_INT32:
13581 case FT_INT40:
13582 case FT_INT48:
13583 case FT_INT56:
13584 case FT_INT64:
13585 value = ws_sign_ext64(value, no_of_bits);
13586 break;
13587
13588 default:
13589 break;
13590 }
13591
13592 if (return_value) {
13593 *return_value = value;
13594 }
13595
13596 /* Coast clear. Try and fake it */
13597 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13598 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", 13598
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13598, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13598, "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", 13598, __func__, "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); } } }
;
13599
13600 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13601
13602 switch (hf_field->type) {
13603 case FT_BOOLEAN:
13604 /* Boolean field */
13605 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13606 "%s = %s: %s",
13607 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13608 break;
13609
13610 case FT_CHAR:
13611 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13612 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13613 break;
13614
13615 case FT_UINT8:
13616 case FT_UINT16:
13617 case FT_UINT24:
13618 case FT_UINT32:
13619 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13620 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13621 break;
13622
13623 case FT_INT8:
13624 case FT_INT16:
13625 case FT_INT24:
13626 case FT_INT32:
13627 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13628 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13629 break;
13630
13631 case FT_UINT40:
13632 case FT_UINT48:
13633 case FT_UINT56:
13634 case FT_UINT64:
13635 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13636 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13637 break;
13638
13639 case FT_INT40:
13640 case FT_INT48:
13641 case FT_INT56:
13642 case FT_INT64:
13643 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13644 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13645 break;
13646
13647 case FT_BYTES:
13648 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13649 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13650 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13651 proto_item_set_text(pi, "%s", lbl_str);
13652 return pi;
13653
13654 /* TODO: should handle FT_UINT_BYTES ? */
13655
13656 default:
13657 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))
13658 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))
13659 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))
13660 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))
;
13661 return NULL((void*)0);
13662 }
13663
13664 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13665 return pi;
13666}
13667
13668proto_item *
13669proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13670 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13671 uint64_t *return_value)
13672{
13673 proto_item *pi;
13674 int no_of_bits;
13675 unsigned octet_offset;
13676 unsigned mask_initial_bit_offset;
13677 unsigned mask_greatest_bit_offset;
13678 unsigned octet_length;
13679 uint8_t i;
13680 char bf_str[256];
13681 char lbl_str[ITEM_LABEL_LENGTH240];
13682 uint64_t value;
13683 uint64_t composite_bitmask;
13684 uint64_t composite_bitmap;
13685
13686 header_field_info *hf_field;
13687
13688 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13689 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", 13689, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13689
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13689, "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
13690
13691 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13692 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)
13693 " 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)
13694 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)
;
13695 }
13696
13697 mask_initial_bit_offset = bit_offset % 8;
13698
13699 no_of_bits = 0;
13700 value = 0;
13701 i = 0;
13702 mask_greatest_bit_offset = 0;
13703 composite_bitmask = 0;
13704 composite_bitmap = 0;
13705
13706 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
13707 uint64_t crumb_mask, crumb_value;
13708 uint8_t crumb_end_bit_offset;
13709
13710 crumb_value = tvb_get_bits64(tvb,
13711 bit_offset + crumb_spec[i].crumb_bit_offset,
13712 crumb_spec[i].crumb_bit_length,
13713 ENC_BIG_ENDIAN0x00000000);
13714 value += crumb_value;
13715 no_of_bits += crumb_spec[i].crumb_bit_length;
13716 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", 13716
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13717
13718 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13719 octet containing the initial offset.
13720 If the mask is beyond 32 bits, then give up on bit map display.
13721 This could be improved in future, probably showing a table
13722 of 32 or 64 bits per row */
13723 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13724 crumb_end_bit_offset = mask_initial_bit_offset
13725 + crumb_spec[i].crumb_bit_offset
13726 + crumb_spec[i].crumb_bit_length;
13727 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'
13728
13729 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13730 mask_greatest_bit_offset = crumb_end_bit_offset;
13731 }
13732 /* Currently the bitmap of the crumbs are only shown if
13733 * smaller than 32 bits. Do not bother calculating the
13734 * mask if it is larger than that. */
13735 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13736 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'
13737 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13738 }
13739 }
13740 /* Shift left for the next segment */
13741 value <<= crumb_spec[++i].crumb_bit_length;
13742 }
13743
13744 /* Sign extend for signed types */
13745 switch (hf_field->type) {
13746 case FT_INT8:
13747 case FT_INT16:
13748 case FT_INT24:
13749 case FT_INT32:
13750 case FT_INT40:
13751 case FT_INT48:
13752 case FT_INT56:
13753 case FT_INT64:
13754 value = ws_sign_ext64(value, no_of_bits);
13755 break;
13756 default:
13757 break;
13758 }
13759
13760 if (return_value) {
13761 *return_value = value;
13762 }
13763
13764 /* Coast clear. Try and fake it */
13765 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13766 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", 13766
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13766, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13766, "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", 13766, __func__, "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); } } }
;
13767
13768 /* initialise the format string */
13769 bf_str[0] = '\0';
13770
13771 octet_offset = bit_offset >> 3;
13772
13773 /* Round up mask length to nearest octet */
13774 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13775 mask_greatest_bit_offset = octet_length << 3;
13776
13777 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13778 It would be a useful enhancement to eliminate this restriction. */
13779 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13780 other_decode_bitfield_value(bf_str,
13781 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13782 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13783 mask_greatest_bit_offset);
13784 } else {
13785 /* If the bitmask is too large, try to describe its contents. */
13786 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13787 }
13788
13789 switch (hf_field->type) {
13790 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13791 /* Boolean field */
13792 return proto_tree_add_boolean_format(tree, hfindex,
13793 tvb, octet_offset, octet_length, value,
13794 "%s = %s: %s",
13795 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13796 break;
13797
13798 case FT_CHAR:
13799 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13800 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13801 break;
13802
13803 case FT_UINT8:
13804 case FT_UINT16:
13805 case FT_UINT24:
13806 case FT_UINT32:
13807 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13808 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13809 break;
13810
13811 case FT_INT8:
13812 case FT_INT16:
13813 case FT_INT24:
13814 case FT_INT32:
13815 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13816 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13817 break;
13818
13819 case FT_UINT40:
13820 case FT_UINT48:
13821 case FT_UINT56:
13822 case FT_UINT64:
13823 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13824 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13825 break;
13826
13827 case FT_INT40:
13828 case FT_INT48:
13829 case FT_INT56:
13830 case FT_INT64:
13831 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13832 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13833 break;
13834
13835 default:
13836 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))
13837 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))
13838 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))
13839 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))
;
13840 return NULL((void*)0);
13841 }
13842 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13843 return pi;
13844}
13845
13846void
13847proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13848 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13849{
13850 header_field_info *hfinfo;
13851 unsigned start = bit_offset >> 3;
13852 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13853
13854 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13855 * so that we can use the tree's memory scope in calculating the string */
13856 if (length == -1) {
13857 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13858 } else {
13859 tvb_ensure_bytes_exist(tvb, start, length);
13860 }
13861 if (!tree) return;
13862
13863 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", 13863, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13863
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13863, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13864 proto_tree_add_text_internal(tree, tvb, start, length,
13865 "%s crumb %d of %s (decoded above)",
13866 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13867 tvb_get_bits32(tvb,
13868 bit_offset,
13869 crumb_spec[crumb_index].crumb_bit_length,
13870 ENC_BIG_ENDIAN0x00000000),
13871 ENC_BIG_ENDIAN0x00000000),
13872 crumb_index,
13873 hfinfo->name);
13874}
13875
13876proto_item *
13877proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13878 const unsigned bit_offset, const int no_of_bits,
13879 uint64_t *return_value, const unsigned encoding)
13880{
13881 proto_item *item;
13882
13883 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13884 bit_offset, no_of_bits,
13885 return_value, encoding))) {
13886 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)
;
13887 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)
;
13888 }
13889 return item;
13890}
13891
13892static proto_item *
13893_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13894 tvbuff_t *tvb, const unsigned bit_offset,
13895 const int no_of_bits, void *value_ptr,
13896 const unsigned encoding, char *value_str)
13897{
13898 unsigned offset;
13899 unsigned length;
13900 uint8_t tot_no_bits;
13901 char *str;
13902 uint64_t value = 0;
13903 header_field_info *hf_field;
13904
13905 /* We do not have to return a value, try to fake it as soon as possible */
13906 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13907 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", 13907
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13907, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13907, "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", 13907, __func__, "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); } } }
;
13908
13909 if (hf_field->bitmask != 0) {
13910 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)
13911 " 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)
13912 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)
;
13913 }
13914
13915 if (no_of_bits < 0) {
13916 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13917 } else if (no_of_bits == 0) {
13918 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)
13919 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)
;
13920 }
13921
13922 /* Byte align offset */
13923 offset = bit_offset>>3;
13924
13925 /*
13926 * Calculate the number of octets used to hold the bits
13927 */
13928 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13929 length = tot_no_bits>>3;
13930 /* If we are using part of the next octet, increase length by 1 */
13931 if (tot_no_bits & 0x07)
13932 length++;
13933
13934 if (no_of_bits < 65) {
13935 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13936 } else {
13937 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)
13938 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)
;
13939 return NULL((void*)0);
13940 }
13941
13942 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13943
13944 (void) g_strlcat(str, " = ", 256+64);
13945 (void) g_strlcat(str, hf_field->name, 256+64);
13946
13947 /*
13948 * This function does not receive an actual value but a dimensionless pointer to that value.
13949 * For this reason, the type of the header field is examined in order to determine
13950 * what kind of value we should read from this address.
13951 * The caller of this function must make sure that for the specific header field type the address of
13952 * a compatible value is provided.
13953 */
13954 switch (hf_field->type) {
13955 case FT_BOOLEAN:
13956 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13957 "%s: %s", str, value_str);
13958 break;
13959
13960 case FT_CHAR:
13961 case FT_UINT8:
13962 case FT_UINT16:
13963 case FT_UINT24:
13964 case FT_UINT32:
13965 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13966 "%s: %s", str, value_str);
13967 break;
13968
13969 case FT_UINT40:
13970 case FT_UINT48:
13971 case FT_UINT56:
13972 case FT_UINT64:
13973 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13974 "%s: %s", str, value_str);
13975 break;
13976
13977 case FT_INT8:
13978 case FT_INT16:
13979 case FT_INT24:
13980 case FT_INT32:
13981 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13982 "%s: %s", str, value_str);
13983 break;
13984
13985 case FT_INT40:
13986 case FT_INT48:
13987 case FT_INT56:
13988 case FT_INT64:
13989 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13990 "%s: %s", str, value_str);
13991 break;
13992
13993 case FT_FLOAT:
13994 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13995 "%s: %s", str, value_str);
13996 break;
13997
13998 default:
13999 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))
14000 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))
14001 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))
14002 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))
;
14003 return NULL((void*)0);
14004 }
14005}
14006
14007static proto_item *
14008proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14009 tvbuff_t *tvb, const unsigned bit_offset,
14010 const int no_of_bits, void *value_ptr,
14011 const unsigned encoding, char *value_str)
14012{
14013 proto_item *item;
14014
14015 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14016 tvb, bit_offset, no_of_bits,
14017 value_ptr, encoding, value_str))) {
14018 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)
;
14019 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)
;
14020 }
14021 return item;
14022}
14023
14024#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);
\
14025 va_start(ap, format)__builtin_va_start(ap, format); \
14026 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14027 va_end(ap)__builtin_va_end(ap);
14028
14029proto_item *
14030proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14031 tvbuff_t *tvb, const unsigned bit_offset,
14032 const int no_of_bits, uint32_t value,
14033 const unsigned encoding,
14034 const char *format, ...)
14035{
14036 va_list ap;
14037 char *dst;
14038 header_field_info *hf_field;
14039
14040 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14041
14042 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", 14042
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14042, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14042, "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", 14042, __func__, "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); } } }
;
14043
14044 switch (hf_field->type) {
14045 case FT_UINT8:
14046 case FT_UINT16:
14047 case FT_UINT24:
14048 case FT_UINT32:
14049 break;
14050
14051 default:
14052 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)
14053 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)
;
14054 return NULL((void*)0);
14055 }
14056
14057 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);
;
14058
14059 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14060}
14061
14062proto_item *
14063proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14064 tvbuff_t *tvb, const unsigned bit_offset,
14065 const int no_of_bits, uint64_t value,
14066 const unsigned encoding,
14067 const char *format, ...)
14068{
14069 va_list ap;
14070 char *dst;
14071 header_field_info *hf_field;
14072
14073 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14074
14075 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", 14075
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14075, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14075, "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", 14075, __func__, "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); } } }
;
14076
14077 switch (hf_field->type) {
14078 case FT_UINT40:
14079 case FT_UINT48:
14080 case FT_UINT56:
14081 case FT_UINT64:
14082 break;
14083
14084 default:
14085 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)
14086 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)
;
14087 return NULL((void*)0);
14088 }
14089
14090 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);
;
14091
14092 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14093}
14094
14095proto_item *
14096proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14097 tvbuff_t *tvb, const unsigned bit_offset,
14098 const int no_of_bits, float value,
14099 const unsigned encoding,
14100 const char *format, ...)
14101{
14102 va_list ap;
14103 char *dst;
14104 header_field_info *hf_field;
14105
14106 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14107
14108 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", 14108
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14108, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14108, "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", 14108, __func__, "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); } } }
;
14109
14110 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",
14110, ((hf_field))->abbrev))))
;
14111
14112 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);
;
14113
14114 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14115}
14116
14117proto_item *
14118proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14119 tvbuff_t *tvb, const unsigned bit_offset,
14120 const int no_of_bits, int32_t value,
14121 const unsigned encoding,
14122 const char *format, ...)
14123{
14124 va_list ap;
14125 char *dst;
14126 header_field_info *hf_field;
14127
14128 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14129
14130 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", 14130
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14130, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14130, "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", 14130, __func__, "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); } } }
;
14131
14132 switch (hf_field->type) {
14133 case FT_INT8:
14134 case FT_INT16:
14135 case FT_INT24:
14136 case FT_INT32:
14137 break;
14138
14139 default:
14140 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)
14141 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)
;
14142 return NULL((void*)0);
14143 }
14144
14145 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);
;
14146
14147 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14148}
14149
14150proto_item *
14151proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14152 tvbuff_t *tvb, const unsigned bit_offset,
14153 const int no_of_bits, int64_t value,
14154 const unsigned encoding,
14155 const char *format, ...)
14156{
14157 va_list ap;
14158 char *dst;
14159 header_field_info *hf_field;
14160
14161 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14162
14163 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", 14163
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14163, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14163, "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", 14163, __func__, "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); } } }
;
14164
14165 switch (hf_field->type) {
14166 case FT_INT40:
14167 case FT_INT48:
14168 case FT_INT56:
14169 case FT_INT64:
14170 break;
14171
14172 default:
14173 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)
14174 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)
;
14175 return NULL((void*)0);
14176 }
14177
14178 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);
;
14179
14180 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14181}
14182
14183proto_item *
14184proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14185 tvbuff_t *tvb, const unsigned bit_offset,
14186 const int no_of_bits, uint64_t value,
14187 const unsigned encoding,
14188 const char *format, ...)
14189{
14190 va_list ap;
14191 char *dst;
14192 header_field_info *hf_field;
14193
14194 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14195
14196 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", 14196
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14196, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14196, "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", 14196, __func__, "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); } } }
;
14197
14198 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"
, 14198, ((hf_field))->abbrev))))
;
14199
14200 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
14201
14202 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14203}
14204
14205proto_item *
14206proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14207 const unsigned bit_offset, const int no_of_chars)
14208{
14209 proto_item *pi;
14210 header_field_info *hfinfo;
14211 int byte_length;
14212 unsigned byte_offset;
14213 char *string;
14214
14215 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14216
14217 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", 14217
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14217, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14217, "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", 14217, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14218
14219 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"
, 14219, ((hfinfo))->abbrev))))
;
14220
14221 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14222 byte_offset = bit_offset >> 3;
14223
14224 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14225
14226 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14227 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14227, "byte_length >= 0"
))))
;
14228 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14229
14230 return pi;
14231}
14232
14233proto_item *
14234proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14235 const unsigned bit_offset, const int no_of_chars)
14236{
14237 proto_item *pi;
14238 header_field_info *hfinfo;
14239 int byte_length;
14240 unsigned byte_offset;
14241 char *string;
14242
14243 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14244
14245 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", 14245
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14245, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14245, "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", 14245, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14246
14247 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"
, 14247, ((hfinfo))->abbrev))))
;
14248
14249 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14250 byte_offset = bit_offset >> 3;
14251
14252 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14253
14254 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14255 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14255, "byte_length >= 0"
))))
;
14256 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14257
14258 return pi;
14259}
14260
14261const value_string proto_checksum_vals[] = {
14262 { PROTO_CHECKSUM_E_BAD, "Bad" },
14263 { PROTO_CHECKSUM_E_GOOD, "Good" },
14264 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14265 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14266 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14267
14268 { 0, NULL((void*)0) }
14269};
14270
14271#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14272
14273proto_item *
14274proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14275 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14276 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14277{
14278 header_field_info *hfinfo;
14279 uint32_t checksum;
14280 uint32_t len;
14281 proto_item* ti = NULL((void*)0);
14282 proto_item* ti2;
14283 bool_Bool incorrect_checksum = true1;
14284
14285 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", 14285, __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", 14285
, "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", 14285, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14286
14287 switch (hfinfo->type) {
14288 case FT_UINT8:
14289 len = 1;
14290 break;
14291 case FT_UINT16:
14292 len = 2;
14293 break;
14294 case FT_UINT24:
14295 len = 3;
14296 break;
14297 case FT_UINT32:
14298 len = 4;
14299 break;
14300 default:
14301 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)
14302 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14303 }
14304
14305 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14306 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14307 proto_item_set_generated(ti);
14308 // Backward compatible with use of -1
14309 if (hf_checksum_status > 0) {
14310 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14311 proto_item_set_generated(ti2);
14312 }
14313 return ti;
14314 }
14315
14316 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14317 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14318 proto_item_set_generated(ti);
14319 } else {
14320 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14321 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14322 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14323 if (computed_checksum == 0) {
14324 proto_item_append_text(ti, " [correct]");
14325 // Backward compatible with use of -1
14326 if (hf_checksum_status > 0) {
14327 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14328 proto_item_set_generated(ti2);
14329 }
14330 incorrect_checksum = false0;
14331 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14332 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14333 /* XXX - This can't distinguish between "shouldbe"
14334 * 0x0000 and 0xFFFF unless we know whether there
14335 * were any nonzero bits (other than the checksum).
14336 * Protocols should not use this path if they might
14337 * have an all zero packet.
14338 * Some implementations put the wrong zero; maybe
14339 * we should have a special expert info for that?
14340 */
14341 }
14342 } else {
14343 if (checksum == computed_checksum) {
14344 proto_item_append_text(ti, " [correct]");
14345 // Backward compatible with use of -1
14346 if (hf_checksum_status > 0) {
14347 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14348 proto_item_set_generated(ti2);
14349 }
14350 incorrect_checksum = false0;
14351 }
14352 }
14353
14354 if (incorrect_checksum) {
14355 // Backward compatible with use of -1
14356 if (hf_checksum_status > 0) {
14357 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14358 proto_item_set_generated(ti2);
14359 }
14360 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14361 proto_item_append_text(ti, " [incorrect]");
14362 if (bad_checksum_expert != NULL((void*)0))
14363 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14364 } else {
14365 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14366 if (bad_checksum_expert != NULL((void*)0))
14367 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);
14368 }
14369 }
14370 } else {
14371 // Backward compatible with use of -1
14372 if (hf_checksum_status > 0) {
14373 proto_item_append_text(ti, " [unverified]");
14374 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14375 proto_item_set_generated(ti2);
14376 }
14377 }
14378 }
14379
14380 return ti;
14381}
14382
14383proto_item *
14384proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14385 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14386 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14387{
14388 header_field_info *hfinfo;
14389 uint8_t *checksum = NULL((void*)0);
14390 proto_item* ti = NULL((void*)0);
14391 proto_item* ti2;
14392 bool_Bool incorrect_checksum = true1;
14393
14394 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", 14394, __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", 14394
, "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", 14394, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14395
14396 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",
14396, ((hfinfo))->abbrev))))
;
14397
14398 /* Make sure a NULL computed_checksum isn't dereferenced.
14399 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14400 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14401 * cases the behavior is unexpected and still a programmer error;
14402 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14403 * _NOT_PRESENT nor _GENERATED is correct.
14404 */
14405 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", 14405, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14406
14407 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14408 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14409 proto_item_set_generated(ti);
14410 // Backward compatible with use of -1
14411 if (hf_checksum_status > 0) {
14412 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14413 proto_item_set_generated(ti2);
14414 }
14415 return ti;
14416 }
14417
14418 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14419 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14420 proto_item_set_generated(ti);
14421 return ti;
14422 }
14423
14424 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14425 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14426 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14427 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14428 bool_Bool non_zero_flag = false0;
14429 for (size_t index = 0; index < checksum_len; index++) {
14430 if (computed_checksum[index]) {
14431 non_zero_flag = true1;
14432 break;
14433 }
14434 }
14435 if (!non_zero_flag) {
14436 proto_item_append_text(ti, " [correct]");
14437 // Backward compatible with use of -1
14438 if (hf_checksum_status > 0) {
14439 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14440 proto_item_set_generated(ti2);
14441 }
14442 incorrect_checksum = false0;
14443 }
14444 } else {
14445 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14446 proto_item_append_text(ti, " [correct]");
14447 // Backward compatible with use of -1
14448 if (hf_checksum_status > 0) {
14449 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14450 proto_item_set_generated(ti2);
14451 }
14452 incorrect_checksum = false0;
14453 }
14454 }
14455
14456 if (incorrect_checksum) {
14457 // Backward compatible with use of -1
14458 if (hf_checksum_status > 0) {
14459 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14460 proto_item_set_generated(ti2);
14461 }
14462 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14463 proto_item_append_text(ti, " [incorrect]");
14464 if (bad_checksum_expert != NULL((void*)0))
14465 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14466 } else {
14467 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14468 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14469 if (bad_checksum_expert != NULL((void*)0))
14470 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14471 }
14472 }
14473 } else {
14474 // Backward compatible with use of -1
14475 if (hf_checksum_status > 0) {
14476 proto_item_append_text(ti, " [unverified]");
14477 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14478 proto_item_set_generated(ti2);
14479 }
14480 }
14481
14482 return ti;
14483}
14484
14485unsigned char
14486proto_check_field_name(const char *field_name)
14487{
14488 return module_check_valid_name(field_name, false0);
14489}
14490
14491unsigned char
14492proto_check_field_name_lower(const char *field_name)
14493{
14494 return module_check_valid_name(field_name, true1);
14495}
14496
14497bool_Bool
14498tree_expanded(int tree_type)
14499{
14500 if (tree_type <= 0) {
14501 return false0;
14502 }
14503 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", 14503, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14504 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14505}
14506
14507void
14508tree_expanded_set(int tree_type, bool_Bool value)
14509{
14510 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", 14510, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14511
14512 if (value)
14513 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14514 else
14515 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14516}
14517
14518/*
14519 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14520 *
14521 * Local variables:
14522 * c-basic-offset: 8
14523 * tab-width: 8
14524 * indent-tabs-mode: t
14525 * End:
14526 *
14527 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14528 * :indentSize=8:tabSize=8:noTabs=false:
14529 */