Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13881, 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 REX_API=extern -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-08-24-100314-3660-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <[email protected]>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 unsigned cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is equal to 0 */
102#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
103 if (length == 0) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is equal to 0 */
111#define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
112 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (length == 0) { ((void)0); return ((void*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const unsigned start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 unsigned start, int *length);
300
301static proto_item *
302proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303 unsigned start, unsigned *length);
304
305static void
306proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307static void
308proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309
310static void
311proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312static void
313proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314static void
315proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316static void
317proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318static void
319proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320static void
321proto_tree_set_string(field_info *fi, const char* value);
322static void
323proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326static void
327proto_tree_set_vines(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330static void
331proto_tree_set_ether(field_info *fi, const uint8_t* value);
332static void
333proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334static void
335proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336static void
337proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338static void
339proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340static void
341proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342static void
343proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344static void
345proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346static void
347proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348static void
349proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350static void
351proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352static void
353proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354static void
355proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356static void
357proto_tree_set_boolean(field_info *fi, uint64_t value);
358static void
359proto_tree_set_float(field_info *fi, float value);
360static void
361proto_tree_set_double(field_info *fi, double value);
362static void
363proto_tree_set_uint(field_info *fi, uint32_t value);
364static void
365proto_tree_set_int(field_info *fi, int32_t value);
366static void
367proto_tree_set_uint64(field_info *fi, uint64_t value);
368static void
369proto_tree_set_int64(field_info *fi, int64_t value);
370static void
371proto_tree_set_eui64(field_info *fi, const uint64_t value);
372static void
373proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374
375/* Handle type length mismatch (now filterable) expert info */
376static int proto_type_length_mismatch;
377static expert_field ei_type_length_mismatch_error;
378static expert_field ei_type_length_mismatch_warn;
379static void register_type_length_mismatch(void);
380
381/* Handle byte array string decoding errors with expert info */
382static int proto_byte_array_string_decoding_error;
383static expert_field ei_byte_array_string_decoding_failed_error;
384static void register_byte_array_string_decodinws_error(void);
385
386/* Handle date and time string decoding errors with expert info */
387static int proto_date_time_string_decoding_error;
388static expert_field ei_date_time_string_decoding_failed_error;
389static void register_date_time_string_decodinws_error(void);
390
391/* Handle string errors expert info */
392static int proto_string_errors;
393static expert_field ei_string_trailing_characters;
394static void register_string_errors(void);
395
396/* Handle varint errors expert info */
397static int proto_varint_errors;
398static expert_field ei_varint_decoding_failed_error;
399static void register_varint_errors(void);
400
401static int proto_register_field_init(header_field_info *hfinfo, const int parent);
402
403/* special-case header field used within proto.c */
404static header_field_info hfi_text_only =
405 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
406int hf_text_only;
407
408/* Structure for information about a protocol */
409struct _protocol {
410 const char *name; /* long description */
411 const char *short_name; /* short description */
412 const char *filter_name; /* name of this protocol in filters */
413 GPtrArray *fields; /* fields for this protocol */
414 int proto_id; /* field ID for this protocol */
415 bool_Bool is_enabled; /* true if protocol is enabled */
416 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
417 bool_Bool can_toggle; /* true if is_enabled can be changed */
418 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
419 For dissectors that need a protocol name so they
420 can be added to a dissector table, but use the
421 parent_proto_id for things like enable/disable */
422 GList *heur_list; /* Heuristic dissectors associated with this protocol */
423};
424
425/* List of all protocols */
426static GList *protocols;
427
428/* Structure stored for deregistered g_slice */
429struct g_slice_data {
430 size_t block_size;
431 void *mem_block;
432};
433
434/* Deregistered fields */
435static GPtrArray *deregistered_fields;
436static GPtrArray *deregistered_data;
437static GPtrArray *deregistered_slice;
438
439/* indexed by prefix, contains initializers */
440static GHashTable* prefixes;
441
442/* Contains information about a field when a dissector calls
443 * proto_tree_add_item. */
444#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
445#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
446
447/* Contains the space for proto_nodes. */
448#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
449 node->first_child = NULL((void*)0); \
450 node->last_child = NULL((void*)0); \
451 node->next = NULL((void*)0);
452
453#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
454 wmem_free(pool, node)
455
456/* String space for protocol and field items for the GUI */
457#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
458 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
459 il->value_pos = 0; \
460 il->value_len = 0;
461#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
462 wmem_free(pool, il);
463
464#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 464, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 464, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
465 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
466 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 466
, __func__, "Unregistered hf! index=%d", hfindex)
; \
467 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf.")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 467, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf."))))
; \
468 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf.")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 468, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf."))))
; \
469 hfinfo = gpa_hfinfo.hfi[hfindex];
470
471#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
472
473/* List which stores protocols and fields that have been registered */
474typedef struct _gpa_hfinfo_t {
475 uint32_t len;
476 uint32_t allocated_len;
477 header_field_info **hfi;
478} gpa_hfinfo_t;
479
480static gpa_hfinfo_t gpa_hfinfo;
481
482/* Hash table of abbreviations and IDs */
483static wmem_map_t *gpa_name_map;
484static header_field_info *same_name_hfinfo;
485
486/* Hash table protocol aliases. const char * -> const char * */
487static GHashTable *gpa_protocol_aliases;
488
489/*
490 * We're called repeatedly with the same field name when sorting a column.
491 * Cache our last gpa_name_map hit for faster lookups.
492 */
493static char *last_field_name;
494static header_field_info *last_hfinfo;
495
496/* Points to the first element of an array of bits, indexed by
497 a subtree item type; that array element is true if subtrees of
498 an item of that type are to be expanded. */
499static uint32_t *tree_is_expanded;
500
501/* Number of elements in that array. The entry with index 0 is not used. */
502int num_tree_types = 1;
503
504/* Name hashtables for fast detection of duplicate names */
505static GHashTable* proto_names;
506static GHashTable* proto_short_names;
507static GHashTable* proto_filter_names;
508
509static const char * const reserved_filter_names[] = {
510 /* Display filter keywords. */
511 "eq",
512 "ne",
513 "all_eq",
514 "any_eq",
515 "all_ne",
516 "any_ne",
517 "gt",
518 "ge",
519 "lt",
520 "le",
521 "bitand",
522 "bitwise_and",
523 "contains",
524 "matches",
525 "not",
526 "and",
527 "or",
528 "xor",
529 "in",
530 "any",
531 "all",
532 "true",
533 "false",
534 "nan",
535 "inf",
536 "infinity",
537 NULL((void*)0)
538};
539
540static GHashTable *proto_reserved_filter_names;
541static GQueue* saved_dir_queue;
542
543static gboolean
544proto_strcase_equal(const void* name1, const void* name2)
545{
546 const char* s1 = (const char*)name1;
547 const char* s2 = (const char*)name2;
548
549 return g_ascii_strcasecmp(s1, s2) == 0 ? TRUE(!(0)) : FALSE(0);
550}
551
552static int
553proto_compare_name(const void *p1_arg, const void *p2_arg)
554{
555 const protocol_t *p1 = (const protocol_t *)p1_arg;
556 const protocol_t *p2 = (const protocol_t *)p2_arg;
557
558 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
559}
560
561static GSList *dissector_plugins;
562
563#ifdef HAVE_PLUGINS1
564void
565proto_register_plugin(const proto_plugin *plug)
566{
567 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
568}
569#else /* HAVE_PLUGINS */
570void
571proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
572{
573 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 573, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
574}
575#endif /* HAVE_PLUGINS */
576
577static void
578call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
579{
580 proto_plugin *plug = (proto_plugin *)data;
581
582 if (plug->register_protoinfo) {
583 plug->register_protoinfo();
584 }
585}
586
587static void
588call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
589{
590 proto_plugin *plug = (proto_plugin *)data;
591
592 if (plug->register_handoff) {
593 plug->register_handoff();
594 }
595}
596
597void proto_pre_init(void)
598{
599 saved_dir_queue = g_queue_new();
600
601 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
602 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
603 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
604
605 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, proto_strcase_equal);
606 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
607 /* GHashTable has no key destructor so the cast is safe. */
608 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
609 }
610
611 gpa_hfinfo.len = 0;
612 gpa_hfinfo.allocated_len = 0;
613 gpa_hfinfo.hfi = NULL((void*)0);
614 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
615 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
616 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
617 deregistered_fields = g_ptr_array_new();
618 deregistered_data = g_ptr_array_new();
619 deregistered_slice = g_ptr_array_new();
620}
621
622/* initialize data structures and register protocols and fields */
623void
624proto_init(GSList *register_all_plugin_protocols_list,
625 GSList *register_all_plugin_handoffs_list,
626 register_entity_func register_func, register_entity_func handoff_func,
627 register_cb cb,
628 void *client_data)
629{
630 /* Initialize the ftype subsystem */
631 ftypes_initialize();
632
633 /* Initialize the address type subsystem */
634 address_types_initialize();
635
636 /* Register one special-case FT_TEXT_ONLY field for use when
637 converting wireshark to new-style proto_tree. These fields
638 are merely strings on the GUI tree; they are not filterable */
639 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
640
641 /* Register the pseudo-protocols used for exceptions. */
642 register_show_exception();
643 register_type_length_mismatch();
644 register_byte_array_string_decodinws_error();
645 register_date_time_string_decodinws_error();
646 register_string_errors();
647 register_varint_errors();
648 ftypes_register_pseudofields();
649 col_register_protocol();
650
651 /* Have each built-in dissector register its protocols, fields,
652 dissector tables, and dissectors to be called through a
653 handle, and do whatever one-time initialization it needs to
654 do. */
655 if (register_func != NULL((void*)0))
656 register_func(cb, client_data);
657
658 /* Now call the registration routines for all epan plugins. */
659 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
660 ((void (*)(register_cb, void *))l->data)(cb, client_data);
661 }
662
663 /* Now call the registration routines for all dissector plugins. */
664 if (cb)
665 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
666 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
667
668 /* Now call the "handoff registration" routines of all built-in
669 dissectors; those routines register the dissector in other
670 dissectors' handoff tables, and fetch any dissector handles
671 they need. */
672 if (handoff_func != NULL((void*)0))
673 handoff_func(cb, client_data);
674
675 /* Now do the same with epan plugins. */
676 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
677 ((void (*)(register_cb, void *))l->data)(cb, client_data);
678 }
679
680 /* Now do the same with dissector plugins. */
681 if (cb)
682 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
683 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
684
685 /* sort the protocols by protocol name */
686 protocols = g_list_sort(protocols, proto_compare_name);
687
688 /* sort the dissector handles in dissector tables (for -G reports
689 * and -d error messages. The GUI sorts the handles itself.) */
690 packet_all_tables_sort_handles();
691
692 /* We've assigned all the subtree type values; allocate the array
693 for them, and zero it out. */
694 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
695}
696
697static void
698proto_cleanup_base(void)
699{
700 protocol_t *protocol;
701 header_field_info *hfinfo;
702
703 /* Free the abbrev/ID hash table */
704 if (gpa_name_map) {
705 // XXX - We don't have a wmem_map_destroy, but
706 // it does get cleaned up when epan scope is
707 // destroyed
708 //g_hash_table_destroy(gpa_name_map);
709 gpa_name_map = NULL((void*)0);
710 }
711 if (gpa_protocol_aliases) {
712 g_hash_table_destroy(gpa_protocol_aliases);
713 gpa_protocol_aliases = NULL((void*)0);
714 }
715 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
716 last_field_name = NULL((void*)0);
717
718 while (protocols) {
719 protocol = (protocol_t *)protocols->data;
720 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 720
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 720, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 720, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
721 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 721, "protocol->proto_id == hfinfo->id"
))))
;
722
723 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
724 if (protocol->parent_proto_id != -1) {
725 // pino protocol
726 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 726, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
727 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 727, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
728 } else {
729 if (protocol->fields) {
730 g_ptr_array_free(protocol->fields, true1);
731 }
732 g_list_free(protocol->heur_list);
733 }
734 protocols = g_list_remove(protocols, protocol);
735 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
736 }
737
738 if (proto_names) {
739 g_hash_table_destroy(proto_names);
740 proto_names = NULL((void*)0);
741 }
742
743 if (proto_short_names) {
744 g_hash_table_destroy(proto_short_names);
745 proto_short_names = NULL((void*)0);
746 }
747
748 if (proto_filter_names) {
749 g_hash_table_destroy(proto_filter_names);
750 proto_filter_names = NULL((void*)0);
751 }
752
753 if (proto_reserved_filter_names) {
754 g_hash_table_destroy(proto_reserved_filter_names);
755 proto_reserved_filter_names = NULL((void*)0);
756 }
757
758 if (gpa_hfinfo.allocated_len) {
759 gpa_hfinfo.len = 0;
760 gpa_hfinfo.allocated_len = 0;
761 g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1
)) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo
.hfi), 0)) : (g_free) (gpa_hfinfo.hfi)
;
762 gpa_hfinfo.hfi = NULL((void*)0);
763 }
764
765 if (deregistered_fields) {
766 g_ptr_array_free(deregistered_fields, true1);
767 deregistered_fields = NULL((void*)0);
768 }
769
770 if (deregistered_data) {
771 g_ptr_array_free(deregistered_data, true1);
772 deregistered_data = NULL((void*)0);
773 }
774
775 if (deregistered_slice) {
776 g_ptr_array_free(deregistered_slice, true1);
777 deregistered_slice = NULL((void*)0);
778 }
779
780 g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) -
1)) ? g_free_sized (tree_is_expanded, __builtin_object_size (
(tree_is_expanded), 0)) : (g_free) (tree_is_expanded)
;
781 tree_is_expanded = NULL((void*)0);
782
783 if (prefixes)
784 g_hash_table_destroy(prefixes);
785
786 if (saved_dir_queue != NULL((void*)0)) {
787 g_queue_clear_full(saved_dir_queue, g_free);
788 g_queue_free(saved_dir_queue);
789 saved_dir_queue = NULL((void*)0);
790 }
791}
792
793void
794proto_cleanup(void)
795{
796 proto_free_deregistered_fields();
797 proto_cleanup_base();
798
799 g_slist_free(dissector_plugins);
800 dissector_plugins = NULL((void*)0);
801}
802
803static bool_Bool
804ws_pushd(const char* dir)
805{
806 //Save the current working directory
807 const char* save_wd = get_current_working_dir();
808 if (save_wd != NULL((void*)0))
809 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
810
811 //Change to the new one
812#ifdef _WIN32
813 SetCurrentDirectory(utf_8to16(dir));
814 return true1;
815#else
816 return (chdir(dir) == 0);
817#endif
818}
819
820static bool_Bool
821ws_popd(void)
822{
823 int ret = 0;
824 char* saved_wd = g_queue_pop_head(saved_dir_queue);
825 if (saved_wd == NULL((void*)0))
826 return false0;
827
828 //Restore the previous one
829#ifdef _WIN32
830 SetCurrentDirectory(utf_8to16(saved_wd));
831#else
832 ret = chdir(saved_wd);
833#endif
834 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
835 return (ret == 0);
836}
837
838void
839proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
840{
841 if (ws_pushd(dir))
842 {
843 func(param);
844 ws_popd();
845 }
846}
847
848static bool_Bool
849// NOLINTNEXTLINE(misc-no-recursion)
850proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
851 void *data)
852{
853 proto_node *pnode = tree;
854 proto_node *child;
855 proto_node *current;
856
857 if (func(pnode, data))
858 return true1;
859
860 child = pnode->first_child;
861 while (child != NULL((void*)0)) {
862 /*
863 * The routine we call might modify the child, e.g. by
864 * freeing it, so we get the child's successor before
865 * calling that routine.
866 */
867 current = child;
868 child = current->next;
869 // We recurse here, but we're limited by prefs.gui_max_tree_depth
870 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
871 return true1;
872 }
873
874 return false0;
875}
876
877void
878proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
879 void *data)
880{
881 proto_node *node = tree;
882 proto_node *current;
883
884 if (!node)
885 return;
886
887 node = node->first_child;
888 while (node != NULL((void*)0)) {
889 current = node;
890 node = current->next;
891 func((proto_tree *)current, data);
892 }
893}
894
895static void
896free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
897{
898 GPtrArray *ptrs = (GPtrArray *)value;
899 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
900 header_field_info *hfinfo;
901
902 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 902, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 902, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 902, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
903 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
904 /* when a field is referenced by a filter this also
905 affects the refcount for the parent protocol so we need
906 to adjust the refcount for the parent as well
907 */
908 if (hfinfo->parent != -1) {
909 header_field_info *parent_hfinfo;
910 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 910
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 910, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 910, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf.")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
911 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
912 }
913 hfinfo->ref_type = HF_REF_TYPE_NONE;
914 }
915
916 g_ptr_array_free(ptrs, true1);
917}
918
919static void
920proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
921{
922 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
923
924 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
925
926 if (finfo) {
927 // The fvalue_t structure was allocated using fvalue_new_pool()
928 // (see new_field_info()) and will be reclaimed when the pool is
929 // freed, so we only release the type-specific data it owns here.
930 fvalue_cleanup(finfo->value);
931 finfo->value = NULL((void*)0);
932 }
933}
934
935void
936proto_tree_reset(proto_tree *tree)
937{
938 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
939
940 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
941
942 /* free tree data */
943 if (tree_data->interesting_hfids) {
944 /* Free all the GPtrArray's in the interesting_hfids hash. */
945 g_hash_table_foreach(tree_data->interesting_hfids,
946 free_GPtrArray_value, NULL((void*)0));
947
948 /* And then remove all values. */
949 g_hash_table_remove_all(tree_data->interesting_hfids);
950 }
951
952 /* Reset track of the number of children */
953 tree_data->count = 0;
954
955 /* Reset our loop checks */
956 tree_data->idle_count_ds_tvb = NULL((void*)0);
957 tree_data->max_start = 0;
958 tree_data->start_idle_count = 0;
959
960 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
961}
962
963/* frees the resources that the dissection a proto_tree uses */
964void
965proto_tree_free(proto_tree *tree)
966{
967 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
968
969 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
970
971 /* free tree data */
972 if (tree_data->interesting_hfids) {
973 /* Free all the GPtrArray's in the interesting_hfids hash. */
974 g_hash_table_foreach(tree_data->interesting_hfids,
975 free_GPtrArray_value, NULL((void*)0));
976
977 /* And then destroy the hash. */
978 g_hash_table_destroy(tree_data->interesting_hfids);
979 }
980
981 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
982
983 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
984}
985
986/* Is the parsing being done for a visible proto_tree or an invisible one?
987 * By setting this correctly, the proto_tree creation is sped up by not
988 * having to call vsnprintf and copy strings around.
989 */
990bool_Bool
991proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
992{
993 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
994
995 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
996
997 return old_visible;
998}
999
1000void
1001proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
1002{
1003 if (tree)
1004 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
1005}
1006
1007/* Assume dissector set only its protocol fields.
1008 This function is called by dissectors and allows the speeding up of filtering
1009 in wireshark; if this function returns false it is safe to reset tree to NULL
1010 and thus skip calling most of the expensive proto_tree_add_...()
1011 functions.
1012 If the tree is visible we implicitly assume the field is referenced.
1013*/
1014bool_Bool
1015proto_field_is_referenced(proto_tree *tree, int proto_id)
1016{
1017 register header_field_info *hfinfo;
1018
1019
1020 if (!tree)
1021 return false0;
1022
1023 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1024 return true1;
1025
1026 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1026, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1026,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1026, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1027 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1028 return true1;
1029
1030 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1031 return true1;
1032
1033 return false0;
1034}
1035
1036
1037/* Finds a record in the hfinfo array by id. */
1038header_field_info *
1039proto_registrar_get_nth(unsigned hfindex)
1040{
1041 register header_field_info *hfinfo;
1042
1043 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1043, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1043,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1043, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1044 return hfinfo;
1045}
1046
1047
1048/* Prefix initialization
1049 * this allows for a dissector to register a display filter name prefix
1050 * so that it can delay the initialization of the hf array as long as
1051 * possible.
1052 */
1053
1054/* compute a hash for the part before the dot of a display filter */
1055static unsigned
1056prefix_hash (const void *key) {
1057 /* end the string at the dot and compute its hash */
1058 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1059 char* c = copy;
1060 unsigned tmp;
1061
1062 for (; *c; c++) {
1063 if (*c == '.') {
1064 *c = 0;
1065 break;
1066 }
1067 }
1068
1069 tmp = wmem_str_hash(copy);
1070 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1071 return tmp;
1072}
1073
1074/* are both strings equal up to the end or the dot? */
1075static gboolean
1076prefix_equal (const void *ap, const void *bp) {
1077 const char* a = (const char *)ap;
1078 const char* b = (const char *)bp;
1079
1080 do {
1081 char ac = *a++;
1082 char bc = *b++;
1083
1084 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1085
1086 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1087 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1088
1089 if (ac != bc) return FALSE(0);
1090 } while (1);
1091
1092 return FALSE(0);
1093}
1094
1095/* Register a new prefix for "delayed" initialization of field arrays */
1096void
1097proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1098 if (! prefixes ) {
1099 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1100 }
1101
1102 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1103}
1104
1105/* helper to call all prefix initializers */
1106static gboolean
1107initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1108 ((prefix_initializer_t)v)((const char *)k);
1109 return TRUE(!(0));
1110}
1111
1112/** Initialize every remaining uninitialized prefix. */
1113void
1114proto_initialize_all_prefixes(void) {
1115 if (!prefixes) {
1116 return;
1117 }
1118 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1119}
1120
1121/* Finds a record in the hfinfo array by name.
1122 * If it fails to find it in the already registered fields,
1123 * it tries to find and call an initializer in the prefixes
1124 * table and if so it looks again.
1125 */
1126
1127header_field_info *
1128proto_registrar_get_byname(const char *field_name)
1129{
1130 header_field_info *hfinfo;
1131 prefix_initializer_t pi;
1132
1133 if (!field_name)
1134 return NULL((void*)0);
1135
1136 if (g_strcmp0(field_name, last_field_name) == 0) {
1137 return last_hfinfo;
1138 }
1139
1140 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1141
1142 if (hfinfo) {
1143 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)
;
1144 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1145 last_hfinfo = hfinfo;
1146 return hfinfo;
1147 }
1148
1149 if (!prefixes)
1150 return NULL((void*)0);
1151
1152 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1153 pi(field_name);
1154 g_hash_table_remove(prefixes, field_name);
1155 } else {
1156 return NULL((void*)0);
1157 }
1158
1159 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1160
1161 if (hfinfo) {
1162 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)
;
1163 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1164 last_hfinfo = hfinfo;
1165 }
1166 return hfinfo;
1167}
1168
1169header_field_info*
1170proto_registrar_get_byalias(const char *alias_name)
1171{
1172 if (!alias_name) {
1173 return NULL((void*)0);
1174 }
1175
1176 /* Find our aliased protocol. */
1177 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1178 char *dot = strchr(an_copy, '.');
1179 if (dot) {
1180 *dot = '\0';
1181 }
1182 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1183 if (!proto_pfx) {
1184 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)
;
1185 return NULL((void*)0);
1186 }
1187
1188 /* Construct our aliased field and look it up. */
1189 GString *filter_name = g_string_new(proto_pfx);
1190 if (dot) {
1191 g_string_append_printf(filter_name, ".%s", dot+1);
1192 }
1193 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1194 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)
;
1195 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)))))
;
1196
1197 return hfinfo;
1198}
1199
1200int
1201proto_registrar_get_id_byname(const char *field_name)
1202{
1203 header_field_info *hfinfo;
1204
1205 hfinfo = proto_registrar_get_byname(field_name);
1206
1207 if (!hfinfo)
1208 return -1;
1209
1210 return hfinfo->id;
1211}
1212
1213static int
1214label_strcat_flags(const header_field_info *hfinfo)
1215{
1216 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1217 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1218
1219 return 0;
1220}
1221
1222static char *
1223format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1224 const uint8_t *bytes, unsigned length, size_t max_str_len)
1225{
1226 char *str = NULL((void*)0);
1227 const uint8_t *p;
1228 bool_Bool is_printable;
1229
1230 if (bytes) {
1231 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1232 /*
1233 * If all bytes are valid and printable UTF-8, show the
1234 * bytes as a string - in quotes to indicate that it's
1235 * a string.
1236 */
1237 if (isprint_utf8_string((const char*)bytes, length)) {
1238 str = wmem_strdup_printf(scope, "\"%.*s\"",
1239 (int)length, bytes);
1240 return str;
1241 }
1242 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1243 /*
1244 * Check whether all bytes are printable.
1245 */
1246 is_printable = true1;
1247 for (p = bytes; p < bytes+length; p++) {
1248 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1249 /* Not printable. */
1250 is_printable = false0;
1251 break;
1252 }
1253 }
1254
1255 /*
1256 * If all bytes are printable ASCII, show the bytes
1257 * as a string - in quotes to indicate that it's
1258 * a string.
1259 */
1260 if (is_printable) {
1261 str = wmem_strdup_printf(scope, "\"%.*s\"",
1262 (int)length, bytes);
1263 return str;
1264 }
1265 }
1266
1267 /*
1268 * Either it's not printable ASCII, or we don't care whether
1269 * it's printable ASCII; show it as hex bytes.
1270 */
1271 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1272 case SEP_DOT:
1273 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1274 break;
1275 case SEP_DASH:
1276 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1277 break;
1278 case SEP_COLON:
1279 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1280 break;
1281 case SEP_SPACE:
1282 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1283 break;
1284 case BASE_NONE:
1285 default:
1286 if (prefs.display_byte_fields_with_spaces) {
1287 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1288 } else {
1289 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1290 }
1291 break;
1292 }
1293 }
1294 else {
1295 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1296 str = wmem_strdup(scope, "<none>");
1297 } else {
1298 str = wmem_strdup(scope, "<MISSING>");
1299 }
1300 }
1301 return str;
1302}
1303
1304static char *
1305format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1306 const uint8_t *bytes, unsigned length)
1307{
1308 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1309}
1310
1311static void
1312ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1313{
1314 subtree_lvl *pushed_tree;
1315
1316 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"
, 1316, "ptvc->pushed_tree_max <= 256-8"))))
;
1317 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1318
1319 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1320 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1320, "pushed_tree != ((void*)0)"
))))
;
1321 ptvc->pushed_tree = pushed_tree;
1322}
1323
1324static void
1325ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1326{
1327 ptvc->pushed_tree = NULL((void*)0);
1328 ptvc->pushed_tree_max = 0;
1329 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", 1329, "ptvc->pushed_tree_index == 0"
))))
;
1330 ptvc->pushed_tree_index = 0;
1331}
1332
1333/* Allocates an initializes a ptvcursor_t with 3 variables:
1334 * proto_tree, tvbuff, and offset. */
1335ptvcursor_t *
1336ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1337{
1338 ptvcursor_t *ptvc;
1339
1340 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1341 ptvc->scope = scope;
1342 ptvc->tree = tree;
1343 ptvc->tvb = tvb;
1344 ptvc->offset = offset;
1345 ptvc->pushed_tree = NULL((void*)0);
1346 ptvc->pushed_tree_max = 0;
1347 ptvc->pushed_tree_index = 0;
1348 return ptvc;
1349}
1350
1351
1352/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1353void
1354ptvcursor_free(ptvcursor_t *ptvc)
1355{
1356 ptvcursor_free_subtree_levels(ptvc);
1357 wmem_free(ptvc->scope, ptvc);
1358}
1359
1360/* Returns tvbuff. */
1361tvbuff_t *
1362ptvcursor_tvbuff(ptvcursor_t *ptvc)
1363{
1364 return ptvc->tvb;
1365}
1366
1367/* Returns current offset. */
1368unsigned
1369ptvcursor_current_offset(ptvcursor_t *ptvc)
1370{
1371 return ptvc->offset;
1372}
1373
1374proto_tree *
1375ptvcursor_tree(ptvcursor_t *ptvc)
1376{
1377 if (!ptvc)
1378 return NULL((void*)0);
1379
1380 return ptvc->tree;
1381}
1382
1383void
1384ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1385{
1386 ptvc->tree = tree;
1387}
1388
1389/* creates a subtree, sets it as the working tree and pushes the old working tree */
1390proto_tree *
1391ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1392{
1393 subtree_lvl *subtree;
1394 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1395 ptvcursor_new_subtree_levels(ptvc);
1396
1397 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1398 subtree->tree = ptvc->tree;
1399 subtree->it= NULL((void*)0);
1400 ptvc->pushed_tree_index++;
1401 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1402}
1403
1404/* pops a subtree */
1405void
1406ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1407{
1408 subtree_lvl *subtree;
1409
1410 if (ptvc->pushed_tree_index <= 0)
1411 return;
1412
1413 ptvc->pushed_tree_index--;
1414 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1415 if (subtree->it != NULL((void*)0))
1416 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1417
1418 ptvc->tree = subtree->tree;
1419}
1420
1421/* saves the current tvb offset and the item in the current subtree level */
1422static void
1423ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1424{
1425 subtree_lvl *subtree;
1426
1427 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", 1427, "ptvc->pushed_tree_index > 0"
))))
;
1428
1429 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1430 subtree->it = it;
1431 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1432}
1433
1434/* Creates a subtree and adds it to the cursor as the working tree but does not
1435 * save the old working tree */
1436proto_tree *
1437ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1438{
1439 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1440 return ptvc->tree;
1441}
1442
1443static proto_tree *
1444ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1445{
1446 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1447 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1448 ptvcursor_subtree_set_item(ptvc, it);
1449 return ptvcursor_tree(ptvc);
1450}
1451
1452/* Add an item to the tree and create a subtree
1453 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1454 * In this case, when the subtree will be closed, the parent item length will
1455 * be equal to the advancement of the cursor since the creation of the subtree.
1456 */
1457proto_tree *
1458ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1459 const unsigned encoding, int ett_subtree)
1460{
1461 proto_item *it;
1462
1463 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1464 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1465}
1466
1467static proto_item *
1468proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1469
1470/* Add a text node to the tree and create a subtree
1471 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1472 * In this case, when the subtree will be closed, the item length will be equal
1473 * to the advancement of the cursor since the creation of the subtree.
1474 */
1475proto_tree *
1476ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1477 int ett_subtree, const char *format, ...)
1478{
1479 proto_item *pi;
1480 va_list ap;
1481 header_field_info *hfinfo;
1482 proto_tree *tree;
1483
1484 tree = ptvcursor_tree(ptvc);
1485
1486 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1487
1488 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", 1488
, __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", 1488, "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", 1488, "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", 1488, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1489
1490 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1491 ptvcursor_current_offset(ptvc), length);
1492
1493 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1493, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1494
1495 va_start(ap, format)__builtin_va_start(ap, format);
1496 proto_tree_set_representation(pi, format, ap);
1497 va_end(ap)__builtin_va_end(ap);
1498
1499 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1500}
1501
1502/* Add a text-only node, leaving it to our caller to fill the text in */
1503static proto_item *
1504proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1505{
1506 proto_item *pi;
1507
1508 if (tree == NULL((void*)0))
1509 return NULL((void*)0);
1510
1511 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1512
1513 return pi;
1514}
1515
1516/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1517proto_item *
1518proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1519 const char *format, ...)
1520{
1521 proto_item *pi;
1522 va_list ap;
1523 header_field_info *hfinfo;
1524
1525 tvb_ensure_bytes_exist(tvb, start, length);
1526
1527 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1528
1529 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", 1529
, __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", 1529, "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", 1529, "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", 1529, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1530
1531 pi = proto_tree_add_text_node(tree, tvb, start, length);
1532
1533 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1533, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1534
1535 va_start(ap, format)__builtin_va_start(ap, format);
1536 proto_tree_set_representation(pi, format, ap);
1537 va_end(ap)__builtin_va_end(ap);
1538
1539 return pi;
1540}
1541
1542/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1543proto_item *
1544proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1545 unsigned length, const char *format, va_list ap)
1546{
1547 proto_item *pi;
1548 header_field_info *hfinfo;
1549
1550 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1551 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1552 * the length to be what's in the tvbuff if length is -1, and the
1553 * minimum of length and what's in the tvbuff if not.
1554 */
1555
1556 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1557
1558 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", 1558
, __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", 1558, "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", 1558, "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", 1558, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1559
1560 pi = proto_tree_add_text_node(tree, tvb, start, length);
1561
1562 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1562, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1563
1564 proto_tree_set_representation(pi, format, ap);
1565
1566 return pi;
1567}
1568
1569/* Add a text-only node that creates a subtree underneath.
1570 */
1571proto_tree *
1572proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1573{
1574 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1575}
1576
1577/* Add a text-only node that creates a subtree underneath.
1578 */
1579proto_tree *
1580proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1581{
1582 proto_tree *pt;
1583 proto_item *pi;
1584 va_list ap;
1585
1586 if (length == -1) {
1587 length = tvb_captured_length_remaining(tvb, start);
1588 }
1589
1590 va_start(ap, format)__builtin_va_start(ap, format);
1591 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1592 va_end(ap)__builtin_va_end(ap);
1593
1594 if (tree_item != NULL((void*)0))
1595 *tree_item = pi;
1596
1597 pt = proto_item_add_subtree(pi, idx);
1598
1599 return pt;
1600}
1601
1602/* Add a text-only node for debugging purposes. The caller doesn't need
1603 * to worry about tvbuff, start, or length. Debug message gets sent to
1604 * STDOUT, too */
1605proto_item *
1606proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1607{
1608 proto_item *pi;
1609 va_list ap;
1610
1611 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1612
1613 if (pi) {
1614 va_start(ap, format)__builtin_va_start(ap, format);
1615 proto_tree_set_representation(pi, format, ap);
1616 va_end(ap)__builtin_va_end(ap);
1617 }
1618 va_start(ap, format)__builtin_va_start(ap, format);
1619 vprintf(format, ap);
1620 va_end(ap)__builtin_va_end(ap);
1621 printf("\n");
1622
1623 return pi;
1624}
1625
1626proto_item *
1627proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1628{
1629 proto_item *pi;
1630 header_field_info *hfinfo;
1631
1632 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1633
1634 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", 1634
, __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", 1634, "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", 1634, "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", 1634, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1635
1636 pi = proto_tree_add_text_node(tree, tvb, start, length);
1637
1638 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1638, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1639
1640 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1641
1642 return pi;
1643}
1644
1645proto_item *
1646proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1647{
1648 proto_item *pi;
1649 header_field_info *hfinfo;
1650 char *str;
1651
1652 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1653
1654 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", 1654
, __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", 1654, "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", 1654, "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", 1654, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1655
1656 pi = proto_tree_add_text_node(tree, tvb, start, length);
1657
1658 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1658, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1659
1660 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1661 proto_item_set_text(pi, "%s", str);
1662 wmem_free(NULL((void*)0), str);
1663
1664 return pi;
1665}
1666
1667void proto_report_dissector_bug(const char *format, ...)
1668{
1669 va_list args;
1670
1671 if (wireshark_abort_on_dissector_bug) {
1672 /*
1673 * Try to have the error message show up in the crash
1674 * information.
1675 */
1676 va_start(args, format)__builtin_va_start(args, format);
1677 ws_vadd_crash_info(format, args);
1678 va_end(args)__builtin_va_end(args);
1679
1680 /*
1681 * Print the error message.
1682 */
1683 va_start(args, format)__builtin_va_start(args, format);
1684 vfprintf(stderrstderr, format, args);
1685 va_end(args)__builtin_va_end(args);
1686 putc('\n', stderrstderr);
1687
1688 /*
1689 * And crash.
1690 */
1691 abort();
1692 } else {
1693 va_start(args, format)__builtin_va_start(args, format);
1694 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1695 va_end(args)__builtin_va_end(args);
1696 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1696
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1697 }
1698}
1699
1700/* We could probably get away with changing is_error to a minimum length value. */
1701static void
1702report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1703{
1704 if (is_error) {
1705 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1706 } else {
1707 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1708 }
1709
1710 if (is_error) {
1711 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1712 }
1713}
1714
1715static uint32_t
1716get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1717{
1718 uint32_t value;
1719 bool_Bool length_error;
1720
1721 switch (length) {
1722
1723 case 1:
1724 value = tvb_get_uint8(tvb, offset);
1725 if (encoding & ENC_ZIGBEE0x40000000) {
1726 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1727 value = 0;
1728 }
1729 }
1730 break;
1731
1732 case 2:
1733 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1734 : tvb_get_ntohs(tvb, offset);
1735 if (encoding & ENC_ZIGBEE0x40000000) {
1736 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1737 value = 0;
1738 }
1739 }
1740 break;
1741
1742 case 3:
1743 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1744 : tvb_get_ntoh24(tvb, offset);
1745 break;
1746
1747 case 4:
1748 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1749 : tvb_get_ntohl(tvb, offset);
1750 break;
1751
1752 default:
1753 if (length < 1) {
1754 length_error = true1;
1755 value = 0;
1756 } else {
1757 length_error = false0;
1758 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1759 : tvb_get_ntohl(tvb, offset);
1760 }
1761 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1762 break;
1763 }
1764 return value;
1765}
1766
1767static inline uint64_t
1768get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1769{
1770 uint64_t value;
1771
1772 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1773
1774 if (length < 1 || length > 8) {
1775 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1776 }
1777
1778 return value;
1779}
1780
1781static int32_t
1782get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1783{
1784 int32_t value;
1785 bool_Bool length_error;
1786
1787 switch (length) {
1788
1789 case 1:
1790 value = tvb_get_int8(tvb, offset);
1791 break;
1792
1793 case 2:
1794 value = encoding ? tvb_get_letohis(tvb, offset)
1795 : tvb_get_ntohis(tvb, offset);
1796 break;
1797
1798 case 3:
1799 value = encoding ? tvb_get_letohi24(tvb, offset)
1800 : tvb_get_ntohi24(tvb, offset);
1801 break;
1802
1803 case 4:
1804 value = encoding ? tvb_get_letohil(tvb, offset)
1805 : tvb_get_ntohil(tvb, offset);
1806 break;
1807
1808 default:
1809 if (length < 1) {
1810 length_error = true1;
1811 value = 0;
1812 } else {
1813 length_error = false0;
1814 value = encoding ? tvb_get_letohil(tvb, offset)
1815 : tvb_get_ntohil(tvb, offset);
1816 }
1817 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1818 break;
1819 }
1820 return value;
1821}
1822
1823/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1824 * be cast-able as a int64_t. This is weird, but what the code has always done.
1825 */
1826static inline uint64_t
1827get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1828{
1829 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1830
1831 switch (length) {
1832 case 7:
1833 value = ws_sign_ext64(value, 56);
1834 break;
1835 case 6:
1836 value = ws_sign_ext64(value, 48);
1837 break;
1838 case 5:
1839 value = ws_sign_ext64(value, 40);
1840 break;
1841 case 4:
1842 value = ws_sign_ext64(value, 32);
1843 break;
1844 case 3:
1845 value = ws_sign_ext64(value, 24);
1846 break;
1847 case 2:
1848 value = ws_sign_ext64(value, 16);
1849 break;
1850 case 1:
1851 value = ws_sign_ext64(value, 8);
1852 break;
1853 }
1854
1855 return value;
1856}
1857
1858/* For FT_STRING */
1859static inline const uint8_t *
1860get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1861 int length, unsigned *ret_length, const unsigned encoding)
1862{
1863 if (length == -1) {
1864 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1865 } else {
1866 *ret_length = length;
1867 }
1868 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1869}
1870
1871/* For FT_STRINGZ */
1872static inline const uint8_t *
1873get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1874 unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1875{
1876 const uint8_t *value;
1877
1878 if (length < -1) {
1879 report_type_length_mismatch(tree, "a string", length, true1);
1880 }
1881
1882 /* XXX - Ideally, every "null-terminated string which fits into a
1883 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1884 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1885 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1886 * as unknown length as well (since there is a trailing '\0', the real
1887 * length is never zero), allowing switching to unsigned lengths.
1888 */
1889 if (length == -1) {
1890 /* This can throw an exception */
1891 value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1892 } else {
1893 /* In this case, length signifies the length of the string.
1894 *
1895 * This could either be a null-padded string, which doesn't
1896 * necessarily have a '\0' at the end, or a null-terminated
1897 * string, with a trailing '\0'. (Yes, there are cases
1898 * where you have a string that's both counted and null-
1899 * terminated.)
1900 *
1901 * In the first case, we must allocate a buffer of length
1902 * "length+1", to make room for a trailing '\0'.
1903 *
1904 * In the second case, we don't assume that there is a
1905 * trailing '\0' there, as the packet might be malformed.
1906 * (XXX - should we throw an exception if there's no
1907 * trailing '\0'?) Therefore, we allocate a buffer of
1908 * length "length+1", and put in a trailing '\0', just to
1909 * be safe.
1910 *
1911 * (XXX - this would change if we made string values counted
1912 * rather than null-terminated.)
1913 */
1914 *ret_length = length;
1915 value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1916 }
1917 return value;
1918}
1919
1920/* For FT_UINT_STRING */
1921static inline const uint8_t *
1922get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1923 tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1924 const unsigned encoding)
1925{
1926 uint32_t n;
1927 const uint8_t *value;
1928
1929 /* I believe it's ok if this is called with a NULL tree */
1930 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1931 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1932 *ret_length = length + n;
1933 return value;
1934}
1935
1936/* For FT_STRINGZPAD */
1937static inline const uint8_t *
1938get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1939 int length, unsigned *ret_length, const unsigned encoding)
1940{
1941 /*
1942 * XXX - currently, string values are null-
1943 * terminated, so a "zero-padded" string
1944 * isn't special. If we represent string
1945 * values as something that includes a counted
1946 * array of bytes, we'll need to strip the
1947 * trailing NULs.
1948 */
1949 if (length == -1) {
1950 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1951 } else {
1952 *ret_length = length;
1953 }
1954 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1955}
1956
1957/* For FT_STRINGZTRUNC */
1958static inline const uint8_t *
1959get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1960 int length, unsigned *ret_length, const unsigned encoding)
1961{
1962 /*
1963 * XXX - currently, string values are null-
1964 * terminated, so a "zero-truncated" string
1965 * isn't special. If we represent string
1966 * values as something that includes a counted
1967 * array of bytes, we'll need to strip everything
1968 * starting with the terminating NUL.
1969 */
1970 if (length == -1) {
1971 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1972 } else {
1973 *ret_length = length;
1974 }
1975 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1976}
1977
1978/*
1979 * Deltas between the epochs for various non-UN*X time stamp formats and
1980 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1981 * stamp format.
1982 */
1983
1984/*
1985 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1986 * XXX - if it's OK if this is unsigned, can we just use
1987 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1988 */
1989#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1990
1991/*
1992 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1993 */
1994#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1995
1996/* this can be called when there is no tree, so tree may be null */
1997static void
1998get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1999 const int length, const unsigned encoding, nstime_t *time_stamp,
2000 const bool_Bool is_relative)
2001{
2002 uint32_t tmpsecs;
2003 uint64_t tmp64secs;
2004 uint64_t todusecs;
2005
2006 switch (encoding) {
2007
2008 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
2009 /*
2010 * If the length is 16, 8-byte seconds, followed
2011 * by 8-byte fractional time in nanoseconds,
2012 * both big-endian.
2013 *
2014 * If the length is 12, 8-byte seconds, followed
2015 * by 4-byte fractional time in nanoseconds,
2016 * both big-endian.
2017 *
2018 * If the length is 8, 4-byte seconds, followed
2019 * by 4-byte fractional time in nanoseconds,
2020 * both big-endian.
2021 *
2022 * For absolute times, the seconds are seconds
2023 * since the UN*X epoch.
2024 */
2025 if (length == 16) {
2026 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2027 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2028 } else if (length == 12) {
2029 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2030 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2031 } else if (length == 8) {
2032 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2033 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2034 } else if (length == 4) {
2035 /*
2036 * Backwards compatibility.
2037 * ENC_TIME_SECS_NSECS is 0; using
2038 * ENC_BIG_ENDIAN by itself with a 4-byte
2039 * time-in-seconds value was done in the
2040 * past.
2041 */
2042 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2043 time_stamp->nsecs = 0;
2044 } else {
2045 time_stamp->secs = 0;
2046 time_stamp->nsecs = 0;
2047 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2048 }
2049 break;
2050
2051 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2052 /*
2053 * If the length is 16, 8-byte seconds, followed
2054 * by 8-byte fractional time in nanoseconds,
2055 * both little-endian.
2056 *
2057 * If the length is 12, 8-byte seconds, followed
2058 * by 4-byte fractional time in nanoseconds,
2059 * both little-endian.
2060 *
2061 * If the length is 8, 4-byte seconds, followed
2062 * by 4-byte fractional time in nanoseconds,
2063 * both little-endian.
2064 *
2065 * For absolute times, the seconds are seconds
2066 * since the UN*X epoch.
2067 */
2068 if (length == 16) {
2069 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2070 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2071 } else if (length == 12) {
2072 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2073 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2074 } else if (length == 8) {
2075 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2076 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2077 } else if (length == 4) {
2078 /*
2079 * Backwards compatibility.
2080 * ENC_TIME_SECS_NSECS is 0; using
2081 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2082 * time-in-seconds value was done in the
2083 * past.
2084 */
2085 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2086 time_stamp->nsecs = 0;
2087 } else {
2088 time_stamp->secs = 0;
2089 time_stamp->nsecs = 0;
2090 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2091 }
2092 break;
2093
2094 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2095 /*
2096 * NTP time stamp, big-endian.
2097 * Only supported for absolute times.
2098 */
2099 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2099, "!is_relative"
))))
;
2100
2101 /* We need a temporary variable here so the unsigned math
2102 * works correctly (for years > 2036 according to RFC 2030
2103 * chapter 3).
2104 *
2105 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2106 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2107 * If bit 0 is not set, the time is in the range 2036-2104 and
2108 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2109 */
2110 tmpsecs = tvb_get_ntohl(tvb, start);
2111 if ((tmpsecs & 0x80000000) != 0)
2112 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2113 else
2114 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2115
2116 if (length == 8) {
2117 tmp64secs = tvb_get_ntoh64(tvb, start);
2118 if (tmp64secs == 0) {
2119 //This is "NULL" time
2120 time_stamp->secs = 0;
2121 time_stamp->nsecs = 0;
2122 } else {
2123 /*
2124 * Convert 1/2^32s of a second to
2125 * nanoseconds.
2126 */
2127 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2128 }
2129 } else if (length == 4) {
2130 /*
2131 * Backwards compatibility.
2132 */
2133 if (tmpsecs == 0) {
2134 //This is "NULL" time
2135 time_stamp->secs = 0;
2136 }
2137 time_stamp->nsecs = 0;
2138 } else {
2139 time_stamp->secs = 0;
2140 time_stamp->nsecs = 0;
2141 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2142 }
2143 break;
2144
2145 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2146 /*
2147 * NTP time stamp, little-endian.
2148 * Only supported for absolute times.
2149 *
2150 * NTP doesn't use this, because it's an Internet format
2151 * and hence big-endian. Any implementation must decide
2152 * whether the NTP timestamp is a 64-bit unsigned fixed
2153 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2154 * with a 32-bit unsigned seconds field followed by a
2155 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2156 * the previous two).
2157 *
2158 * XXX: We do the latter, but no dissector uses this format.
2159 * OTOH, ERF timestamps do the former, so perhaps we
2160 * should switch the interpretation so that packet-erf.c
2161 * could use this directly? (ENC_TIME_RTPS is this 64-bit
2162 * struct with two 32-bit fields, but with the UN*X epoch.)
2163 */
2164 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2164, "!is_relative"
))))
;
2165
2166 /* We need a temporary variable here so the unsigned math
2167 * works correctly (for years > 2036 according to RFC 2030
2168 * chapter 3).
2169 *
2170 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2171 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2172 * If bit 0 is not set, the time is in the range 2036-2104 and
2173 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2174 */
2175 tmpsecs = tvb_get_letohl(tvb, start);
2176 if ((tmpsecs & 0x80000000) != 0)
2177 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2178 else
2179 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2180
2181 if (length == 8) {
2182 tmp64secs = tvb_get_letoh64(tvb, start);
2183 if (tmp64secs == 0) {
2184 //This is "NULL" time
2185 time_stamp->secs = 0;
2186 time_stamp->nsecs = 0;
2187 } else {
2188 /*
2189 * Convert 1/2^32s of a second to
2190 * nanoseconds.
2191 */
2192 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2193 }
2194 } else if (length == 4) {
2195 /*
2196 * Backwards compatibility.
2197 */
2198 if (tmpsecs == 0) {
2199 //This is "NULL" time
2200 time_stamp->secs = 0;
2201 }
2202 time_stamp->nsecs = 0;
2203 } else {
2204 time_stamp->secs = 0;
2205 time_stamp->nsecs = 0;
2206 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2207 }
2208 break;
2209
2210 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2211 /*
2212 * S/3x0 and z/Architecture TOD clock time stamp,
2213 * big-endian. The epoch is January 1, 1900,
2214 * 00:00:00 (proleptic?) UTC.
2215 *
2216 * Only supported for absolute times.
2217 */
2218 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2218, "!is_relative"
))))
;
2219 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2219, "length == 8"
))))
;
2220
2221 if (length == 8) {
2222 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2223 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2224 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2225 } else {
2226 time_stamp->secs = 0;
2227 time_stamp->nsecs = 0;
2228 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2229 }
2230 break;
2231
2232 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2233 /*
2234 * S/3x0 and z/Architecture TOD clock time stamp,
2235 * little-endian. The epoch is January 1, 1900,
2236 * 00:00:00 (proleptic?) UTC.
2237 *
2238 * Only supported for absolute times.
2239 */
2240 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2240, "!is_relative"
))))
;
2241
2242 if (length == 8) {
2243 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2244 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2245 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2246 } else {
2247 time_stamp->secs = 0;
2248 time_stamp->nsecs = 0;
2249 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2250 }
2251 break;
2252
2253 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
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; big-
2258 * endian.
2259 *
2260 * Only supported for absolute times.
2261 */
2262 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2262, "!is_relative"
))))
;
2263
2264 if (length == 8) {
2265 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2266 /*
2267 * Convert 1/2^32s of a second to nanoseconds.
2268 */
2269 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2270 } else {
2271 time_stamp->secs = 0;
2272 time_stamp->nsecs = 0;
2273 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2274 }
2275 break;
2276
2277 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2278 /*
2279 * Time stamp using the same seconds/fraction format
2280 * as NTP, but with the origin of the time stamp being
2281 * the UNIX epoch rather than the NTP epoch; little-
2282 * endian.
2283 *
2284 * Only supported for absolute times.
2285 *
2286 * The RTPS specification explicitly supports Little
2287 * Endian encoding. In one place, it states that its
2288 * Time_t representation "is the one defined by ...
2289 * RFC 1305", but in another explicitly defines it as
2290 * a struct consisting of an 32 bit unsigned seconds
2291 * field and a 32 bit unsigned fraction field, not a 64
2292 * bit fixed point, so we do that here.
2293 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2294 */
2295 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2295, "!is_relative"
))))
;
2296
2297 if (length == 8) {
2298 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2299 /*
2300 * Convert 1/2^32s of a second to nanoseconds.
2301 */
2302 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2303 } else {
2304 time_stamp->secs = 0;
2305 time_stamp->nsecs = 0;
2306 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2307 }
2308 break;
2309
2310 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2311 /*
2312 * MIP6 time stamp, big-endian.
2313 * A 64-bit unsigned integer field containing a timestamp. The
2314 * value indicates the number of seconds since January 1, 1970,
2315 * 00:00 UTC, by using a fixed point format. In this format, the
2316 * integer number of seconds is contained in the first 48 bits of
2317 * the field, and the remaining 16 bits indicate the number of
2318 * 1/65536 fractions of a second.
2319
2320 * Only supported for absolute times.
2321 */
2322 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2322, "!is_relative"
))))
;
2323
2324 if (length == 8) {
2325 /* We need a temporary variable here so the casting and fractions
2326 * of a second work correctly.
2327 */
2328 tmp64secs = tvb_get_ntoh48(tvb, start);
2329 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2330 tmpsecs <<= 16;
2331
2332 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2333 //This is "NULL" time
2334 time_stamp->secs = 0;
2335 time_stamp->nsecs = 0;
2336 } else {
2337 time_stamp->secs = (time_t)tmp64secs;
2338 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2339 }
2340 } else {
2341 time_stamp->secs = 0;
2342 time_stamp->nsecs = 0;
2343 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2344 }
2345 break;
2346
2347 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2348 /*
2349 * If the length is 16, 8-byte seconds, followed
2350 * by 8-byte fractional time in microseconds,
2351 * both big-endian.
2352 *
2353 * If the length is 12, 8-byte seconds, followed
2354 * by 4-byte fractional time in microseconds,
2355 * both big-endian.
2356 *
2357 * If the length is 8, 4-byte seconds, followed
2358 * by 4-byte fractional time in microseconds,
2359 * both big-endian.
2360 *
2361 * For absolute times, the seconds are seconds
2362 * since the UN*X epoch.
2363 */
2364 if (length == 16) {
2365 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2366 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2367 } else if (length == 12) {
2368 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2369 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2370 } else if (length == 8) {
2371 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2372 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2373 } else {
2374 time_stamp->secs = 0;
2375 time_stamp->nsecs = 0;
2376 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2377 }
2378 break;
2379
2380 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2381 /*
2382 * If the length is 16, 8-byte seconds, followed
2383 * by 8-byte fractional time in microseconds,
2384 * both little-endian.
2385 *
2386 * If the length is 12, 8-byte seconds, followed
2387 * by 4-byte fractional time in microseconds,
2388 * both little-endian.
2389 *
2390 * If the length is 8, 4-byte seconds, followed
2391 * by 4-byte fractional time in microseconds,
2392 * both little-endian.
2393 *
2394 * For absolute times, the seconds are seconds
2395 * since the UN*X epoch.
2396 */
2397 if (length == 16) {
2398 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2399 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2400 } else if (length == 12) {
2401 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2402 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2403 } else if (length == 8) {
2404 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2405 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2406 } else {
2407 time_stamp->secs = 0;
2408 time_stamp->nsecs = 0;
2409 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2410 }
2411 break;
2412
2413 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2414 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2415 /*
2416 * Seconds, 1 to 8 bytes.
2417 * For absolute times, it's seconds since the
2418 * UN*X epoch.
2419 */
2420 if (length >= 1 && length <= 8) {
2421 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2422 time_stamp->nsecs = 0;
2423 } else {
2424 time_stamp->secs = 0;
2425 time_stamp->nsecs = 0;
2426 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2427 }
2428 break;
2429
2430 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2431 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2432 /*
2433 * Milliseconds, 1 to 8 bytes.
2434 * For absolute times, it's milliseconds since the
2435 * UN*X epoch.
2436 */
2437 if (length >= 1 && length <= 8) {
2438 uint64_t msecs;
2439
2440 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2441 time_stamp->secs = (time_t)(msecs / 1000);
2442 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2443 } else {
2444 time_stamp->secs = 0;
2445 time_stamp->nsecs = 0;
2446 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2447 }
2448 break;
2449
2450 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2451 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2452 /*
2453 * Microseconds, 1 to 8 bytes.
2454 * For absolute times, it's microseconds since the
2455 * UN*X epoch.
2456 */
2457 if (length >= 1 && length <= 8) {
2458 uint64_t usecs;
2459
2460 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2461 time_stamp->secs = (time_t)(usecs / 1000000);
2462 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2463 } else {
2464 time_stamp->secs = 0;
2465 time_stamp->nsecs = 0;
2466 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2467 }
2468 break;
2469
2470 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2471 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2472 /*
2473 * nanoseconds, 1 to 8 bytes.
2474 * For absolute times, it's nanoseconds since the
2475 * UN*X epoch.
2476 */
2477
2478 if (length >= 1 && length <= 8) {
2479 uint64_t nsecs;
2480
2481 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2482 time_stamp->secs = (time_t)(nsecs / 1000000000);
2483 time_stamp->nsecs = (int)(nsecs % 1000000000);
2484 } else {
2485 time_stamp->secs = 0;
2486 time_stamp->nsecs = 0;
2487 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2488 }
2489 break;
2490
2491 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2492 /*
2493 * 1/64ths of a second since the UN*X epoch,
2494 * big-endian.
2495 *
2496 * Only supported for absolute times.
2497 */
2498 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2498, "!is_relative"
))))
;
2499
2500 if (length == 8) {
2501 /*
2502 * The upper 48 bits are seconds since the
2503 * UN*X epoch.
2504 */
2505 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2506 /*
2507 * The lower 16 bits are 1/2^16s of a second;
2508 * convert them to nanoseconds.
2509 *
2510 * XXX - this may give the impression of higher
2511 * precision than you actually get.
2512 */
2513 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2514 } else {
2515 time_stamp->secs = 0;
2516 time_stamp->nsecs = 0;
2517 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2518 }
2519 break;
2520
2521 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2522 /*
2523 * 1/64ths of a second since the UN*X epoch,
2524 * little-endian.
2525 *
2526 * Only supported for absolute times.
2527 */
2528 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2528, "!is_relative"
))))
;
2529
2530 if (length == 8) {
2531 /*
2532 * XXX - this is assuming that, if anybody
2533 * were ever to use this format - RFC 3971
2534 * doesn't, because that's an Internet
2535 * protocol, and those use network byte
2536 * order, i.e. big-endian - they'd treat it
2537 * as a 64-bit count of 1/2^16s of a second,
2538 * putting the upper 48 bits at the end.
2539 *
2540 * The lower 48 bits are seconds since the
2541 * UN*X epoch.
2542 */
2543 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2544 /*
2545 * The upper 16 bits are 1/2^16s of a second;
2546 * convert them to nanoseconds.
2547 *
2548 * XXX - this may give the impression of higher
2549 * precision than you actually get.
2550 */
2551 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2552 } else {
2553 time_stamp->secs = 0;
2554 time_stamp->nsecs = 0;
2555 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2556 }
2557 break;
2558
2559 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2560 /*
2561 * NTP time stamp, with 1-second resolution (i.e.,
2562 * seconds since the NTP epoch), big-endian.
2563 * Only supported for absolute times.
2564 */
2565 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2565, "!is_relative"
))))
;
2566
2567 if (length == 4) {
2568 /*
2569 * We need a temporary variable here so the unsigned math
2570 * works correctly (for years > 2036 according to RFC 2030
2571 * chapter 3).
2572 *
2573 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2574 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2575 * If bit 0 is not set, the time is in the range 2036-2104 and
2576 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2577 */
2578 tmpsecs = tvb_get_ntohl(tvb, start);
2579 if ((tmpsecs & 0x80000000) != 0)
2580 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2581 else
2582 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2583 time_stamp->nsecs = 0;
2584 } else {
2585 time_stamp->secs = 0;
2586 time_stamp->nsecs = 0;
2587 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2588 }
2589 break;
2590
2591 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2592 /*
2593 * NTP time stamp, with 1-second resolution (i.e.,
2594 * seconds since the NTP epoch), little-endian.
2595 * Only supported for absolute times.
2596 */
2597 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2597, "!is_relative"
))))
;
2598
2599 /*
2600 * We need a temporary variable here so the unsigned math
2601 * works correctly (for years > 2036 according to RFC 2030
2602 * chapter 3).
2603 *
2604 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2605 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2606 * If bit 0 is not set, the time is in the range 2036-2104 and
2607 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2608 */
2609 if (length == 4) {
2610 tmpsecs = tvb_get_letohl(tvb, start);
2611 if ((tmpsecs & 0x80000000) != 0)
2612 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2613 else
2614 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2615 time_stamp->nsecs = 0;
2616 } else {
2617 time_stamp->secs = 0;
2618 time_stamp->nsecs = 0;
2619 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2620 }
2621 break;
2622
2623 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2624 /*
2625 * Milliseconds, 6 to 8 bytes.
2626 * For absolute times, it's milliseconds since the
2627 * NTP epoch.
2628 *
2629 * ETSI TS 129.274 8.119 defines this as:
2630 * "a 48 bit unsigned integer in network order format
2631 * ...encoded as the number of milliseconds since
2632 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2633 * rounded value of 1000 x the value of the 64-bit
2634 * timestamp (Seconds + (Fraction / (1<<32))) defined
2635 * in clause 6 of IETF RFC 5905."
2636 *
2637 * Taken literally, the part after "i.e." would
2638 * mean that the value rolls over before reaching
2639 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2640 * when the 64 bit timestamp rolls over, and we have
2641 * to pick an NTP Era equivalence class to support
2642 * (such as 1968-01-20 to 2104-02-06).
2643 *
2644 * OTOH, the extra room might be used to store Era
2645 * information instead, in which case times until
2646 * 10819-08-03 can be represented with 6 bytes without
2647 * ambiguity. We handle both implementations, and assume
2648 * that times before 1968-01-20 are not represented.
2649 *
2650 * Only 6 bytes or more makes sense as an absolute
2651 * time. 5 bytes or fewer could express a span of
2652 * less than 35 years, either 1900-1934 or 2036-2070.
2653 */
2654 if (length >= 6 && length <= 8) {
2655 uint64_t msecs;
2656
2657 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2658 tmp64secs = (msecs / 1000);
2659 /*
2660 * Assume that times in the first half of NTP
2661 * Era 0 really represent times in the NTP
2662 * Era 1.
2663 */
2664 if (tmp64secs >= 0x80000000)
2665 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2666 else
2667 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2668 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2669 }
2670 else {
2671 time_stamp->secs = 0;
2672 time_stamp->nsecs = 0;
2673 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2674 }
2675 break;
2676
2677 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2678 /*
2679 * MP4 file time stamps, big-endian.
2680 * Only supported for absolute times.
2681 */
2682 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2682, "!is_relative"
))))
;
2683
2684 if (length == 8) {
2685 tmp64secs = tvb_get_ntoh64(tvb, start);
2686 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2687 time_stamp->nsecs = 0;
2688 } else if (length == 4) {
2689 tmpsecs = tvb_get_ntohl(tvb, start);
2690 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2691 time_stamp->nsecs = 0;
2692 } else {
2693 time_stamp->secs = 0;
2694 time_stamp->nsecs = 0;
2695 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2696 }
2697 break;
2698
2699 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2700 /*
2701 * Zigbee ZCL time stamps, big-endian.
2702 * Only supported for absolute times.
2703 */
2704 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2704, "!is_relative"
))))
;
2705
2706 if (length == 8) {
2707 tmp64secs = tvb_get_ntoh64(tvb, start);
2708 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))
) {
2709 /* There are several other possible choices for what to do
2710 * with overflow; make sure to coordinate with whatever
2711 * packet-zbee-zcl.h does. */
2712 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))))))
;
2713 }
2714 time_stamp->nsecs = 0;
2715 } else if (length == 4) {
2716 tmpsecs = tvb_get_ntohl(tvb, start);
2717 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))
) {
2718 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))))))
;
2719 }
2720 time_stamp->nsecs = 0;
2721 } else {
2722 time_stamp->secs = 0;
2723 time_stamp->nsecs = 0;
2724 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2725 }
2726 break;
2727
2728 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2729 /*
2730 * Zigbee ZCL time stamps, little-endian.
2731 * Only supported for absolute times.
2732 */
2733 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2733, "!is_relative"
))))
;
2734
2735 if (length == 8) {
2736 tmp64secs = tvb_get_letoh64(tvb, start);
2737 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))
) {
2738 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))))))
;
2739 }
2740 time_stamp->nsecs = 0;
2741 } else if (length == 4) {
2742 tmpsecs = tvb_get_letohl(tvb, start);
2743 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))
) {
2744 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))))))
;
2745 }
2746 time_stamp->nsecs = 0;
2747 } else {
2748 time_stamp->secs = 0;
2749 time_stamp->nsecs = 0;
2750 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2751 }
2752 break;
2753
2754 case ENC_TIME_WINDOWS0x00000034 | ENC_BIG_ENDIAN0x00000000:
2755 /*
2756 * WINDOWS FILETIME, big-endian.
2757 * Only supported for absolute times.
2758 * A FILETIME is a struct with the low 32-bits followed
2759 * by the high 32-bits:
2760 * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2761 * There exist cases where the value is stored in a
2762 * 64-bit integer:
2763 * (See epan/dissectors/pidl/samr/samr.idl "NTTIME_hyper last_password_change;"
2764 * which is confirmed as "LARGE_INTEGER PasswordLastSet;" in
2765 * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1cd138b9-cc1b-4706-b115-49e53189e32e
2766 * That doesn't make a difference when retrieving little-endian,
2767 * because tvb_get_letoh64 handles unaligned accesses and it's
2768 * otherwise the same. However, for big-endian, it does matter,
2769 * analogous to the ENC_TIME_NTP little-endian case. We use the
2770 * struct version, but that means that this MUST NOT be used
2771 * for dissect_nttime_hyper in packet-windows-common.h, at
2772 * least
2773 */
2774 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2774, "!is_relative"
))))
;
2775
2776 if (length == 8) {
2777 tmp64secs = tvb_get_ntoh64(tvb, start); // Really 100-ns units
2778 if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2779 // With 32-bit time_t, this could overflow in
2780 // either direction. We should probably add some
2781 // kind of time overflow expert item to all
2782 // encodings.
2783 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))))))
;
2784 time_stamp->nsecs = 0;
2785 }
2786 } else {
2787 time_stamp->secs = 0;
2788 time_stamp->nsecs = 0;
2789 report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2790 }
2791 break;
2792
2793 case ENC_TIME_WINDOWS0x00000034 | ENC_LITTLE_ENDIAN0x80000000:
2794 /*
2795 * WINDOWS FILETIME, big-endian.
2796 * Only supported for absolute times.
2797 * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2798 */
2799 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2799, "!is_relative"
))))
;
2800
2801 if (length == 8) {
2802 tmp64secs = tvb_get_letoh64(tvb, start); // Really 100-ns units
2803 if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2804 // With 32-bit time_t, this could overflow in
2805 // either direction. We should probably add some
2806 // kind of time overflow expert item to all
2807 // encodings.
2808 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))))))
;
2809 time_stamp->nsecs = 0;
2810 }
2811 } else {
2812 time_stamp->secs = 0;
2813 time_stamp->nsecs = 0;
2814 report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2815 }
2816 break;
2817 default:
2818 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2818))
;
2819 break;
2820 }
2821}
2822
2823static void
2824tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2825{
2826 const header_field_info *hfinfo = fi->hfinfo;
2827
2828 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2829 GPtrArray *ptrs = NULL((void*)0);
2830
2831 if (tree_data->interesting_hfids == NULL((void*)0)) {
2832 /* Initialize the hash because we now know that it is needed */
2833 tree_data->interesting_hfids =
2834 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2835 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2836 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2837 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2838 }
2839
2840 if (!ptrs) {
2841 /* First element triggers the creation of pointer array */
2842 ptrs = g_ptr_array_new();
2843 g_hash_table_insert(tree_data->interesting_hfids,
2844 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2845 }
2846
2847 g_ptr_array_add(ptrs, fi);
2848 }
2849}
2850
2851
2852/*
2853 * Validates that field length bytes are available starting from
2854 * start (pos/neg). Throws an exception if they aren't.
2855 */
2856static void
2857test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2858 unsigned start, int length, const unsigned encoding)
2859{
2860 int size = length;
2861
2862 if (!tvb)
2863 return;
2864
2865 if ((hfinfo->type == FT_STRINGZ) ||
2866 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2867 (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
))
))) {
2868 /* If we're fetching until the end of the TVB, only validate
2869 * that the offset is within range.
2870 */
2871 if (length == -1)
2872 size = 0;
2873 }
2874
2875 tvb_ensure_bytes_exist(tvb, start, size);
2876}
2877
2878static void
2879detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2880{
2881 bool_Bool found_stray_character = false0;
2882
2883 if (!string)
2884 return;
2885
2886 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2887 case ENC_ASCII0x00000000:
2888 case ENC_UTF_80x00000002:
2889 for (int i = (int)strlen(string); i < length; i++) {
2890 if (string[i] != '\0') {
2891 found_stray_character = true1;
2892 break;
2893 }
2894 }
2895 break;
2896
2897 default:
2898 break;
2899 }
2900
2901 if (found_stray_character) {
2902 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2903 }
2904}
2905
2906/* Add an item to a proto_tree, using the text label registered to that item;
2907 the item is extracted from the tvbuff handed to it. */
2908static proto_item *
2909proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2910 tvbuff_t *tvb, unsigned start, int length,
2911 unsigned encoding)
2912{
2913 proto_item *pi;
2914 uint32_t value, n;
2915 uint64_t value64;
2916 ws_in4_addr ipv4_value;
2917 float floatval;
2918 double doubleval;
2919 const char *stringval = NULL((void*)0);
2920 nstime_t time_stamp;
2921 bool_Bool length_error;
2922 unsigned item_length;
2923
2924 // new_fi->value is allocated from the packet-scoped pool (see
2925 // new_field_info()), so if a tvbuff accessor below throws before the
2926 // node is added to the tree the fvalue_t structure is still reclaimed
2927 // when the pool is freed; no explicit cleanup handler is needed. This
2928 // relies on the invariant that the type-specific data an fvalue owns
2929 // (byte arrays, string buffers, ...) is only allocated *after* the
2930 // throwing tvbuff read that produced it succeeds, so nothing that would
2931 // need fvalue_cleanup() is ever leaked on the exception path.
2932 switch (new_fi->hfinfo->type) {
2933 case FT_NONE:
2934 /* no value to set for FT_NONE */
2935 break;
2936
2937 case FT_PROTOCOL:
2938 /* Set the protocol_tvb via the start offset, but include
2939 * rest of the ds_tvb so that if finfo_set_len is called
2940 * later it can be lengthened as much as possible. */
2941 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);
2942 break;
2943
2944 case FT_BYTES:
2945 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2946 break;
2947
2948 case FT_UINT_BYTES:
2949 n = get_uint_value(tree, tvb, start, length, encoding);
2950 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2951
2952 /* Instead of calling proto_item_set_len(), since we don't yet
2953 * have a proto_item, we set the field_info's length ourselves. */
2954 new_fi->length = n + length;
2955 break;
2956
2957 case FT_BOOLEAN:
2958 /*
2959 * Map all non-zero values to little-endian for
2960 * backwards compatibility.
2961 */
2962 if (encoding)
2963 encoding = ENC_LITTLE_ENDIAN0x80000000;
2964 proto_tree_set_boolean(new_fi,
2965 get_uint64_value(tree, tvb, start, length, encoding));
2966 break;
2967
2968 case FT_CHAR:
2969 /* XXX - make these just FT_UINT? */
2970 case FT_UINT8:
2971 case FT_UINT16:
2972 case FT_UINT24:
2973 case FT_UINT32:
2974 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2975 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2976 value = (uint32_t)value64;
2977 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2978 new_fi->flags |= FI_VARINT0x00040000;
2979 }
2980 }
2981 else {
2982 /*
2983 * Map all non-zero values to little-endian for
2984 * backwards compatibility.
2985 */
2986 if (encoding)
2987 encoding = ENC_LITTLE_ENDIAN0x80000000;
2988
2989 value = get_uint_value(tree, tvb, start, length, encoding);
2990 }
2991 proto_tree_set_uint(new_fi, value);
2992 break;
2993
2994 case FT_UINT40:
2995 case FT_UINT48:
2996 case FT_UINT56:
2997 case FT_UINT64:
2998 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2999 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
3000 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
3001 new_fi->flags |= FI_VARINT0x00040000;
3002 }
3003 }
3004 else {
3005 /*
3006 * Map all other non-zero values to little-endian for
3007 * backwards compatibility.
3008 */
3009 if (encoding)
3010 encoding = ENC_LITTLE_ENDIAN0x80000000;
3011
3012 value64 = get_uint64_value(tree, tvb, start, length, encoding);
3013 }
3014 proto_tree_set_uint64(new_fi, value64);
3015 break;
3016
3017 /* XXX - make these just FT_INT? */
3018 case FT_INT8:
3019 case FT_INT16:
3020 case FT_INT24:
3021 case FT_INT32:
3022 /*
3023 * Map all non-zero values to little-endian for
3024 * backwards compatibility.
3025 */
3026 if (encoding)
3027 encoding = ENC_LITTLE_ENDIAN0x80000000;
3028 proto_tree_set_int(new_fi,
3029 get_int_value(tree, tvb, start, length, encoding));
3030 break;
3031
3032 case FT_INT40:
3033 case FT_INT48:
3034 case FT_INT56:
3035 case FT_INT64:
3036 /*
3037 * Map all non-zero values to little-endian for
3038 * backwards compatibility.
3039 */
3040 if (encoding)
3041 encoding = ENC_LITTLE_ENDIAN0x80000000;
3042 proto_tree_set_int64(new_fi,
3043 get_int64_value(tree, tvb, start, length, encoding));
3044 break;
3045
3046 case FT_IPv4:
3047 /*
3048 * Map all non-zero values to little-endian for
3049 * backwards compatibility.
3050 */
3051 if (encoding)
3052 encoding = ENC_LITTLE_ENDIAN0x80000000;
3053 if (length != FT_IPv4_LEN4) {
3054 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
3055 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
3056 }
3057 ipv4_value = tvb_get_ipv4(tvb, start);
3058 /*
3059 * NOTE: to support code written when
3060 * proto_tree_add_item() took a bool as its
3061 * last argument, with false meaning "big-endian"
3062 * and true meaning "little-endian", we treat any
3063 * non-zero value of "encoding" as meaning
3064 * "little-endian".
3065 */
3066 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);
3067 break;
3068
3069 case FT_IPXNET:
3070 if (length != FT_IPXNET_LEN4) {
3071 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
3072 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
3073 }
3074 proto_tree_set_ipxnet(new_fi,
3075 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
3076 break;
3077
3078 case FT_IPv6:
3079 if (length != FT_IPv6_LEN16) {
3080 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
3081 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3082 }
3083 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3084 break;
3085
3086 case FT_FCWWN:
3087 if (length != FT_FCWWN_LEN8) {
3088 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3089 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3090 }
3091 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3092 break;
3093
3094 case FT_AX25:
3095 if (length != 7) {
3096 length_error = length < 7 ? true1 : false0;
3097 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3098 }
3099 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3100 break;
3101
3102 case FT_VINES:
3103 if (length != VINES_ADDR_LEN6) {
3104 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3105 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3106 }
3107 proto_tree_set_vines_tvb(new_fi, tvb, start);
3108 break;
3109
3110 case FT_ETHER:
3111 if (length != FT_ETHER_LEN6) {
3112 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3113 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3114 }
3115 proto_tree_set_ether_tvb(new_fi, tvb, start);
3116 break;
3117
3118 case FT_EUI64:
3119 /*
3120 * Map all non-zero values to little-endian for
3121 * backwards compatibility.
3122 */
3123 if (encoding)
3124 encoding = ENC_LITTLE_ENDIAN0x80000000;
3125 if (length != FT_EUI64_LEN8) {
3126 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3127 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3128 }
3129 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3130 break;
3131 case FT_GUID:
3132 /*
3133 * Map all non-zero values to little-endian for
3134 * backwards compatibility.
3135 */
3136 if (encoding)
3137 encoding = ENC_LITTLE_ENDIAN0x80000000;
3138 if (length != FT_GUID_LEN16) {
3139 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3140 report_type_length_mismatch(tree, "a GUID", length, length_error);
3141 }
3142 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3143 break;
3144
3145 case FT_OID:
3146 case FT_REL_OID:
3147 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3148 break;
3149
3150 case FT_SYSTEM_ID:
3151 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3152 break;
3153
3154 case FT_FLOAT:
3155 /*
3156 * NOTE: to support code written when
3157 * proto_tree_add_item() took a bool as its
3158 * last argument, with false meaning "big-endian"
3159 * and true meaning "little-endian", we treat any
3160 * non-zero value of "encoding" as meaning
3161 * "little-endian".
3162 *
3163 * At some point in the future, we might
3164 * support non-IEEE-binary floating-point
3165 * formats in the encoding as well
3166 * (IEEE decimal, System/3x0, VAX).
3167 */
3168 if (encoding)
3169 encoding = ENC_LITTLE_ENDIAN0x80000000;
3170 if (length != 4) {
3171 length_error = length < 4 ? true1 : false0;
3172 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3173 }
3174 if (encoding)
3175 floatval = tvb_get_letohieee_float(tvb, start);
3176 else
3177 floatval = tvb_get_ntohieee_float(tvb, start);
3178 proto_tree_set_float(new_fi, floatval);
3179 break;
3180
3181 case FT_DOUBLE:
3182 /*
3183 * NOTE: to support code written when
3184 * proto_tree_add_item() took a bool as its
3185 * last argument, with false meaning "big-endian"
3186 * and true meaning "little-endian", we treat any
3187 * non-zero value of "encoding" as meaning
3188 * "little-endian".
3189 *
3190 * At some point in the future, we might
3191 * support non-IEEE-binary floating-point
3192 * formats in the encoding as well
3193 * (IEEE decimal, System/3x0, VAX).
3194 */
3195 if (encoding == true1)
3196 encoding = ENC_LITTLE_ENDIAN0x80000000;
3197 if (length != 8) {
3198 length_error = length < 8 ? true1 : false0;
3199 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3200 }
3201 if (encoding)
3202 doubleval = tvb_get_letohieee_double(tvb, start);
3203 else
3204 doubleval = tvb_get_ntohieee_double(tvb, start);
3205 proto_tree_set_double(new_fi, doubleval);
3206 break;
3207
3208 case FT_STRING:
3209 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3210 tvb, start, length, &item_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 = item_length;
3223 break;
3224
3225 case FT_STRINGZ:
3226 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3227 tree, tvb, start, length, &item_length, encoding);
3228 proto_tree_set_string(new_fi, stringval);
3229
3230 /* Instead of calling proto_item_set_len(),
3231 * since we don't yet have a proto_item, we
3232 * set the field_info's length ourselves.
3233 *
3234 * XXX - our caller can't use that length to
3235 * advance an offset unless they arrange that
3236 * there always be a protocol tree into which
3237 * we're putting this item.
3238 */
3239 new_fi->length = item_length;
3240 break;
3241
3242 case FT_UINT_STRING:
3243 /*
3244 * NOTE: to support code written when
3245 * proto_tree_add_item() took a bool as its
3246 * last argument, with false meaning "big-endian"
3247 * and true meaning "little-endian", if the
3248 * encoding value is true, treat that as
3249 * ASCII with a little-endian length.
3250 *
3251 * This won't work for code that passes
3252 * arbitrary non-zero values; that code
3253 * will need to be fixed.
3254 */
3255 if (encoding == true1)
3256 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3257 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3258 tree, tvb, start, length, &item_length, encoding);
3259 proto_tree_set_string(new_fi, stringval);
3260
3261 /* Instead of calling proto_item_set_len(), since we
3262 * don't yet have a proto_item, we set the
3263 * field_info's length ourselves.
3264 *
3265 * XXX - our caller can't use that length to
3266 * advance an offset unless they arrange that
3267 * there always be a protocol tree into which
3268 * we're putting this item.
3269 */
3270 new_fi->length = item_length;
3271 break;
3272
3273 case FT_STRINGZPAD:
3274 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3275 tvb, start, length, &item_length, encoding);
3276 proto_tree_set_string(new_fi, stringval);
3277
3278 /* Instead of calling proto_item_set_len(), since we
3279 * don't yet have a proto_item, we set the
3280 * field_info's length ourselves.
3281 *
3282 * XXX - our caller can't use that length to
3283 * advance an offset unless they arrange that
3284 * there always be a protocol tree into which
3285 * we're putting this item.
3286 */
3287 new_fi->length = item_length;
3288 break;
3289
3290 case FT_STRINGZTRUNC:
3291 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3292 tvb, start, length, &item_length, encoding);
3293 proto_tree_set_string(new_fi, stringval);
3294
3295 /* Instead of calling proto_item_set_len(), since we
3296 * don't yet have a proto_item, we set the
3297 * field_info's length ourselves.
3298 *
3299 * XXX - our caller can't use that length to
3300 * advance an offset unless they arrange that
3301 * there always be a protocol tree into which
3302 * we're putting this item.
3303 */
3304 new_fi->length = item_length;
3305 break;
3306
3307 case FT_ABSOLUTE_TIME:
3308 /*
3309 * Absolute times can be in any of a number of
3310 * formats, and they can be big-endian or
3311 * little-endian.
3312 *
3313 * Historically FT_TIMEs were only timespecs;
3314 * the only question was whether they were stored
3315 * in big- or little-endian format.
3316 *
3317 * For backwards compatibility, we interpret an
3318 * encoding of 1 as meaning "little-endian timespec",
3319 * so that passing true is interpreted as that.
3320 */
3321 if (encoding == true1)
3322 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3323
3324 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3325
3326 proto_tree_set_time(new_fi, &time_stamp);
3327 break;
3328
3329 case FT_RELATIVE_TIME:
3330 /*
3331 * Relative times can be in any of a number of
3332 * formats, and they can be big-endian or
3333 * little-endian.
3334 *
3335 * Historically FT_TIMEs were only timespecs;
3336 * the only question was whether they were stored
3337 * in big- or little-endian format.
3338 *
3339 * For backwards compatibility, we interpret an
3340 * encoding of 1 as meaning "little-endian timespec",
3341 * so that passing true is interpreted as that.
3342 */
3343 if (encoding == true1)
3344 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3345
3346 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3347
3348 proto_tree_set_time(new_fi, &time_stamp);
3349 break;
3350 case FT_IEEE_11073_SFLOAT:
3351 if (encoding)
3352 encoding = ENC_LITTLE_ENDIAN0x80000000;
3353 if (length != 2) {
3354 length_error = length < 2 ? true1 : false0;
3355 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3356 }
3357
3358 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3359
3360 break;
3361 case FT_IEEE_11073_FLOAT:
3362 if (encoding)
3363 encoding = ENC_LITTLE_ENDIAN0x80000000;
3364 if (length != 4) {
3365 length_error = length < 4 ? true1 : false0;
3366 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3367 }
3368 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3369
3370 break;
3371 default:
3372 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))
3373 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))
3374 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))
3375 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))
;
3376 break;
3377 }
3378 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)
;
3379
3380 /* Don't add new node to proto_tree until now so that any exceptions
3381 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3382 /* XXX. wouldn't be better to add this item to tree, with some special
3383 * flag (FI_EXCEPTION?) to know which item caused exception? For
3384 * strings and bytes, we would have to set new_fi->value to something
3385 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3386 * could handle NULL values. */
3387 pi = proto_tree_add_node(tree, new_fi);
3388
3389 switch (new_fi->hfinfo->type) {
3390
3391 case FT_STRING:
3392 /* XXX: trailing stray character detection should be done
3393 * _before_ conversion to UTF-8, because conversion can change
3394 * the length, or else get_string_length should return a value
3395 * for the "length in bytes of the string after conversion
3396 * including internal nulls." (Noting that we do, for other
3397 * reasons, still need the "length in bytes in the field",
3398 * especially for FT_STRINGZ.)
3399 *
3400 * This is true even for ASCII and UTF-8, because
3401 * substituting REPLACEMENT CHARACTERS for illegal characters
3402 * can also do so (and for UTF-8 possibly even make the
3403 * string _shorter_).
3404 */
3405 detect_trailing_stray_characters(encoding, stringval, item_length, pi);
3406 break;
3407
3408 default:
3409 break;
3410 }
3411
3412 return pi;
3413}
3414
3415proto_item *
3416proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3417 const unsigned start, unsigned length,
3418 const unsigned encoding, int32_t *retval)
3419{
3420 header_field_info *hfinfo;
3421 field_info *new_fi;
3422 int32_t value;
3423
3424 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", 3424, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3424,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3424, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3425
3426 switch (hfinfo->type) {
3427 case FT_INT8:
3428 case FT_INT16:
3429 case FT_INT24:
3430 case FT_INT32:
3431 break;
3432 case FT_INT64:
3433 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)
3434 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3435 default:
3436 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)
3437 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3438 }
3439
3440 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3441 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3442 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3443 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3444 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3445 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3446 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3447
3448 if (encoding & ENC_STRING0x07000000) {
3449 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3450 }
3451 /* I believe it's ok if this is called with a NULL tree */
3452 value = get_int_value(tree, tvb, start, length, encoding);
3453
3454 if (retval) {
3455 int no_of_bits;
3456 *retval = value;
3457 if (hfinfo->bitmask) {
3458 /* Mask out irrelevant portions */
3459 *retval &= (uint32_t)(hfinfo->bitmask);
3460 /* Shift bits */
3461 *retval >>= hfinfo_bitshift(hfinfo);
3462 }
3463 no_of_bits = ws_count_ones(hfinfo->bitmask);
3464 *retval = ws_sign_ext32(*retval, no_of_bits);
3465 }
3466
3467 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3468
3469 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", 3469
, __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", 3469, "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", 3469, "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", 3469, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3470
3471 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3472
3473 proto_tree_set_int(new_fi, value);
3474
3475 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3476
3477 return proto_tree_add_node(tree, new_fi);
3478}
3479
3480proto_item *
3481proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3482 const unsigned start, unsigned length,
3483 const unsigned encoding, uint32_t *retval)
3484{
3485 header_field_info *hfinfo;
3486 field_info *new_fi;
3487 uint32_t value;
3488
3489 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", 3489, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3489,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3489, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3490
3491 switch (hfinfo->type) {
3492 case FT_CHAR:
3493 case FT_UINT8:
3494 case FT_UINT16:
3495 case FT_UINT24:
3496 case FT_UINT32:
3497 break;
3498 default:
3499 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)
3500 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)
;
3501 }
3502
3503 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3504 {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3505 if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3506 *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3507 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3508 return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3509 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3510 )if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
;
3511
3512 if (encoding & ENC_STRING0x07000000) {
3513 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3514 }
3515 /* I believe it's ok if this is called with a NULL tree */
3516 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3517 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3518 uint64_t temp64;
3519 tvb_get_varint(tvb, start, length, &temp64, encoding);
3520 value = (uint32_t)temp64;
3521 } else {
3522 value = get_uint_value(tree, tvb, start, length, encoding);
3523 }
3524
3525 if (retval) {
3526 *retval = value;
3527 if (hfinfo->bitmask) {
3528 /* Mask out irrelevant portions */
3529 *retval &= (uint32_t)(hfinfo->bitmask);
3530 /* Shift bits */
3531 *retval >>= hfinfo_bitshift(hfinfo);
3532 }
3533 }
3534
3535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3536
3537 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", 3537
, __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", 3537, "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", 3537, "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", 3537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3538
3539 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3540
3541 proto_tree_set_uint(new_fi, value);
3542
3543 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3544 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3545 new_fi->flags |= FI_VARINT0x00040000;
3546 }
3547 return proto_tree_add_node(tree, new_fi);
3548}
3549
3550proto_item *
3551proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3552 const unsigned start, unsigned length,
3553 const unsigned encoding, uint32_t *retval)
3554{
3555 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3556}
3557
3558proto_item *
3559proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3560 const unsigned start, unsigned length,
3561 const unsigned encoding, uint8_t *retval)
3562{
3563 /* TODO: further restrict by hfinfo->type ? */
3564 uint32_t val32;
3565 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3566 *retval = (uint8_t)val32;
3567 return item;
3568}
3569
3570proto_item *
3571proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3572 const unsigned start, unsigned length,
3573 const unsigned encoding, uint16_t *retval)
3574{
3575 /* TODO: further restrict by hfinfo->type ? */
3576 uint32_t val32;
3577 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3578 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3579 return item;
3580}
3581
3582
3583/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3584 * and returns proto_item* and uint value retrieved*/
3585proto_item *
3586ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3587 const unsigned encoding, uint32_t *retval)
3588{
3589 field_info *new_fi;
3590 header_field_info *hfinfo;
3591 unsigned item_length;
3592 unsigned offset;
3593 uint32_t value;
3594
3595 offset = ptvc->offset;
3596 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", 3596, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3596,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3596, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3597
3598 switch (hfinfo->type) {
3599 case FT_CHAR:
3600 case FT_UINT8:
3601 case FT_UINT16:
3602 case FT_UINT24:
3603 case FT_UINT32:
3604 break;
3605 default:
3606 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)
3607 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)
;
3608 }
3609
3610 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3611 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3612
3613 /* I believe it's ok if this is called with a NULL tree */
3614 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3615 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3616
3617 if (retval) {
3618 *retval = value;
3619 if (hfinfo->bitmask) {
3620 /* Mask out irrelevant portions */
3621 *retval &= (uint32_t)(hfinfo->bitmask);
3622 /* Shift bits */
3623 *retval >>= hfinfo_bitshift(hfinfo);
3624 }
3625 }
3626
3627 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3628
3629 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3630
3631 /* Coast clear. Try and fake it */
3632 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", 3632
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3632, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3632, "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", 3632, __func__, "Adding %s would put more than %d 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); } } }
;
3633
3634 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3635
3636 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3637 offset, length, encoding);
3638}
3639
3640/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3641 * and returns proto_item* and int value retrieved*/
3642proto_item *
3643ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3644 const unsigned encoding, int32_t *retval)
3645{
3646 field_info *new_fi;
3647 header_field_info *hfinfo;
3648 unsigned item_length;
3649 unsigned offset;
3650 uint32_t value;
3651
3652 offset = ptvc->offset;
3653 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", 3653, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3653,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3653, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3654
3655 switch (hfinfo->type) {
3656 case FT_INT8:
3657 case FT_INT16:
3658 case FT_INT24:
3659 case FT_INT32:
3660 break;
3661 default:
3662 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)
3663 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3664 }
3665
3666 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3667 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3668
3669 /* I believe it's ok if this is called with a NULL tree */
3670 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3671 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3672
3673 if (retval) {
3674 int no_of_bits;
3675 *retval = value;
3676 if (hfinfo->bitmask) {
3677 /* Mask out irrelevant portions */
3678 *retval &= (uint32_t)(hfinfo->bitmask);
3679 /* Shift bits */
3680 *retval >>= hfinfo_bitshift(hfinfo);
3681 }
3682 no_of_bits = ws_count_ones(hfinfo->bitmask);
3683 *retval = ws_sign_ext32(*retval, no_of_bits);
3684 }
3685
3686 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3687
3688 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3689
3690 /* Coast clear. Try and fake it */
3691 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", 3691
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3691, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3691, "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", 3691, __func__, "Adding %s would put more than %d 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); } } }
;
3692
3693 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3694
3695 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3696 offset, length, encoding);
3697}
3698
3699/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3700 * and returns proto_item* and string value retrieved */
3701proto_item*
3702ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3703{
3704 header_field_info *hfinfo;
3705 field_info *new_fi;
3706 const uint8_t *value;
3707 unsigned item_length;
3708 unsigned offset;
3709
3710 offset = ptvc->offset;
3711
3712 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", 3712
, __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", 3712, "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", 3712, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3713
3714 switch (hfinfo->type) {
3715 case FT_STRING:
3716 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3717 break;
3718 case FT_STRINGZ:
3719 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3720 break;
3721 case FT_UINT_STRING:
3722 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3723 break;
3724 case FT_STRINGZPAD:
3725 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3726 break;
3727 case FT_STRINGZTRUNC:
3728 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3729 break;
3730 default:
3731 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)
3732 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)
;
3733 }
3734
3735 if (retval)
3736 *retval = value;
3737
3738 ptvcursor_advance(ptvc, item_length);
3739
3740 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3741
3742 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", 3742, __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", 3742,
"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", 3742, "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", 3742
, __func__, "Adding %s would put more than %d 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); } } }
;
3743
3744 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3745
3746 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3747 offset, length, encoding);
3748}
3749
3750/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3751 * and returns proto_item* and boolean value retrieved */
3752proto_item*
3753ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3754{
3755 header_field_info *hfinfo;
3756 field_info *new_fi;
3757 unsigned item_length;
3758 unsigned offset;
3759 uint64_t value, bitval;
3760
3761 offset = ptvc->offset;
3762 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", 3762, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3762,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3762, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3763
3764 if (hfinfo->type != FT_BOOLEAN) {
3765 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)
3766 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3767 }
3768
3769 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3770 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3771 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3772 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3773 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3774 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3775 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3776
3777 if (encoding & ENC_STRING0x07000000) {
3778 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3779 }
3780
3781 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3782 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3783
3784 /* I believe it's ok if this is called with a NULL tree */
3785 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3786
3787 if (retval) {
3788 bitval = value;
3789 if (hfinfo->bitmask) {
3790 /* Mask out irrelevant portions */
3791 bitval &= hfinfo->bitmask;
3792 }
3793 *retval = (bitval != 0);
3794 }
3795
3796 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3797
3798 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3799
3800 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", 3800, __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", 3800,
"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", 3800, "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", 3800
, __func__, "Adding %s would put more than %d 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); } } }
;
3801
3802 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3803
3804 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3805 offset, length, encoding);
3806}
3807
3808proto_item *
3809proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3810 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3811{
3812 header_field_info *hfinfo;
3813 field_info *new_fi;
3814 uint64_t value;
3815
3816 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", 3816, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3816,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3816, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3817
3818 switch (hfinfo->type) {
3819 case FT_UINT40:
3820 case FT_UINT48:
3821 case FT_UINT56:
3822 case FT_UINT64:
3823 break;
3824 default:
3825 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)
3826 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3827 }
3828
3829 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3830 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3831 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3832 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3833 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3834 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3835 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3836
3837 if (encoding & ENC_STRING0x07000000) {
3838 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3839 }
3840 /* I believe it's ok if this is called with a NULL tree */
3841 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3842 tvb_get_varint(tvb, start, length, &value, encoding);
3843 } else {
3844 value = get_uint64_value(tree, tvb, start, length, encoding);
3845 }
3846
3847 if (retval) {
3848 *retval = value;
3849 if (hfinfo->bitmask) {
3850 /* Mask out irrelevant portions */
3851 *retval &= hfinfo->bitmask;
3852 /* Shift bits */
3853 *retval >>= hfinfo_bitshift(hfinfo);
3854 }
3855 }
3856
3857 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3858
3859 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", 3859
, __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", 3859, "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", 3859, "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", 3859, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3860
3861 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3862
3863 proto_tree_set_uint64(new_fi, value);
3864
3865 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3866 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3867 new_fi->flags |= FI_VARINT0x00040000;
3868 }
3869
3870 return proto_tree_add_node(tree, new_fi);
3871}
3872
3873proto_item *
3874proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3875 const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3876{
3877 header_field_info *hfinfo;
3878 field_info *new_fi;
3879 int64_t value;
3880
3881 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", 3881, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3881,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3881, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3882
3883 switch (hfinfo->type) {
3884 case FT_INT40:
3885 case FT_INT48:
3886 case FT_INT56:
3887 case FT_INT64:
3888 break;
3889 default:
3890 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)
3891 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3892 }
3893
3894 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3895 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3896 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3897 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3898 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3899 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3900 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3901
3902 if (encoding & ENC_STRING0x07000000) {
3903 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3904 }
3905 /* I believe it's ok if this is called with a NULL tree */
3906 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3907 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3908 }
3909 else {
3910 value = get_int64_value(tree, tvb, start, length, encoding);
3911 }
3912
3913 if (retval) {
3914 *retval = value;
3915 }
3916
3917 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3918
3919 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", 3919
, __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", 3919, "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", 3919, "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", 3919, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3920
3921 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3922
3923 proto_tree_set_int64(new_fi, value);
3924
3925 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3926 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3927 new_fi->flags |= FI_VARINT0x00040000;
3928 }
3929
3930 return proto_tree_add_node(tree, new_fi);
3931}
3932
3933proto_item *
3934proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3935 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3936{
3937 header_field_info *hfinfo;
3938 field_info *new_fi;
3939 uint64_t value;
3940
3941 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", 3941, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3941,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3941, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3942
3943 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
))
)) {
3944 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)
3945 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3946 }
3947
3948 if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3949 REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3950 }
3951
3952 if (encoding & ENC_STRING0x07000000) {
3953 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3954 }
3955
3956 /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3957 * It also handles length 0, setting both return values to 0.
3958 * XXX - Should the max length be affected by the field type and/or
3959 * encoding, e.g. 5 for FT_[U]INT32?
3960 * XXX - Should there be separate _varint and _varuint versions to
3961 * avoid the changing the sign when casting the return value?
3962 * XXX - Do we even need the length parameter? Every user of this
3963 * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3964 * separate function, but unlike some field types, variable length
3965 * is the typical case here, not the exception, and the typical
3966 * case should have the shorter, more convenient function name.
3967 * Having the length makes the signature more similar to other
3968 * functions, though. */
3969 length = tvb_get_varint(tvb, start, length, &value, encoding);
3970
3971 if (length == 0) {
3972 expert_add_info(NULL((void*)0), tree, &ei_varint_decoding_failed_error);
3973 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3974 }
3975
3976 if (retval) {
3977 *retval = value;
3978 if (hfinfo->bitmask) {
3979 /* Mask out irrelevant portions */
3980 *retval &= hfinfo->bitmask;
3981 /* Shift bits */
3982 *retval >>= hfinfo_bitshift(hfinfo);
3983 }
3984 }
3985
3986 if (lenretval) {
3987 *lenretval = length;
3988 }
3989
3990 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3991
3992 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", 3992
, __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", 3992, "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", 3992, "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", 3992, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3993
3994 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3995
3996 proto_tree_set_uint64(new_fi, value);
3997
3998 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3999 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
4000 new_fi->flags |= FI_VARINT0x00040000;
4001 }
4002
4003 return proto_tree_add_node(tree, new_fi);
4004
4005}
4006
4007proto_item *
4008proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4009 const unsigned start, unsigned length,
4010 const unsigned encoding, bool_Bool *retval)
4011{
4012 header_field_info *hfinfo;
4013 field_info *new_fi;
4014 uint64_t value, bitval;
4015
4016 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", 4016, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4016,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4016, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4017
4018 if (hfinfo->type != FT_BOOLEAN) {
4019 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)
4020 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
4021 }
4022
4023 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4024 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4025 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4026 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4027 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4028 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4029 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
4030
4031 if (encoding & ENC_STRING0x07000000) {
4032 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4033 }
4034 /* I believe it's ok if this is called with a NULL tree */
4035 value = get_uint64_value(tree, tvb, start, length, encoding);
4036
4037 if (retval) {
4038 bitval = value;
4039 if (hfinfo->bitmask) {
4040 /* Mask out irrelevant portions */
4041 bitval &= hfinfo->bitmask;
4042 }
4043 *retval = (bitval != 0);
4044 }
4045
4046 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4047
4048 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", 4048
, __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", 4048, "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", 4048, "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", 4048, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4049
4050 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4051
4052 proto_tree_set_boolean(new_fi, value);
4053
4054 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4055
4056 return proto_tree_add_node(tree, new_fi);
4057}
4058
4059proto_item *
4060proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4061 const unsigned start, unsigned length,
4062 const unsigned encoding, float *retval)
4063{
4064 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4065 field_info *new_fi;
4066 float value;
4067
4068 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", 4068,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4069
4070 if (hfinfo->type != FT_FLOAT) {
4071 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)
;
4072 }
4073
4074 if (length != 4) {
4075 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
4076 }
4077
4078 /* treat any nonzero encoding as little endian for backwards compatibility */
4079 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
4080 if (retval) {
4081 *retval = value;
4082 }
4083
4084 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4085
4086 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", 4086
, __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", 4086, "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", 4086, "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", 4086, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4087
4088 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4089 if (encoding) {
4090 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4091 }
4092
4093 proto_tree_set_float(new_fi, value);
4094
4095 return proto_tree_add_node(tree, new_fi);
4096}
4097
4098proto_item *
4099proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4100 const unsigned start, unsigned length,
4101 const unsigned encoding, double *retval)
4102{
4103 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4104 field_info *new_fi;
4105 double value;
4106
4107 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", 4107,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4108
4109 if (hfinfo->type != FT_DOUBLE) {
4110 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)
;
4111 }
4112
4113 if (length != 8) {
4114 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4115 }
4116
4117 /* treat any nonzero encoding as little endian for backwards compatibility */
4118 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4119 if (retval) {
4120 *retval = value;
4121 }
4122
4123 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4124
4125 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", 4125
, __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", 4125, "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", 4125, "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", 4125, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4126
4127 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4128 if (encoding) {
4129 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4130 }
4131
4132 proto_tree_set_double(new_fi, value);
4133
4134 return proto_tree_add_node(tree, new_fi);
4135}
4136
4137proto_item *
4138proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4139 const unsigned start, unsigned length,
4140 const unsigned encoding, ws_in4_addr *retval)
4141{
4142 header_field_info *hfinfo;
4143 field_info *new_fi;
4144 ws_in4_addr value;
4145
4146 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", 4146, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4146,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4146, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4147
4148 switch (hfinfo->type) {
4149 case FT_IPv4:
4150 break;
4151 default:
4152 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)
4153 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4154 }
4155
4156 if (length != FT_IPv4_LEN4)
4157 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)
4158 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4159
4160 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4161 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4162 }
4163
4164 /*
4165 * NOTE: to support code written when proto_tree_add_item() took
4166 * a bool as its last argument, with false meaning "big-endian"
4167 * and true meaning "little-endian", we treat any non-zero value
4168 * of "encoding" as meaning "little-endian".
4169 */
4170 value = tvb_get_ipv4(tvb, start);
4171 if (encoding)
4172 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))))
;
4173
4174 if (retval) {
4175 *retval = value;
4176 }
4177
4178 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4179
4180 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", 4180
, __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", 4180, "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", 4180, "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", 4180, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4181
4182 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4183
4184 proto_tree_set_ipv4(new_fi, value);
4185
4186 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4187 return proto_tree_add_node(tree, new_fi);
4188}
4189
4190proto_item *
4191proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4192 const unsigned start, unsigned length,
4193 const unsigned encoding, ws_in6_addr *addr)
4194{
4195 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4196 field_info *new_fi;
4197
4198 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", 4198,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4199
4200 switch (hfinfo->type) {
4201 case FT_IPv6:
4202 break;
4203 default:
4204 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)
4205 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4206 }
4207
4208 if (length != FT_IPv6_LEN16)
4209 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)
4210 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4211
4212 if (encoding) {
4213 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"
)
;
4214 }
4215
4216 tvb_get_ipv6(tvb, start, addr);
4217
4218 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4219
4220 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", 4220
, __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", 4220, "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", 4220, "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", 4220, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4221
4222 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4223
4224 proto_tree_set_ipv6(new_fi, addr);
4225
4226 return proto_tree_add_node(tree, new_fi);
4227}
4228
4229proto_item *
4230proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4231 const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4232
4233 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4234 field_info *new_fi;
4235
4236 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", 4236,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4237
4238 switch (hfinfo->type) {
4239 case FT_ETHER:
4240 break;
4241 default:
4242 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)
4243 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4244 }
4245
4246 if (length != FT_ETHER_LEN6)
4247 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)
4248 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4249
4250 if (encoding) {
4251 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"
)
;
4252 }
4253
4254 tvb_memcpy(tvb, retval, start, length);
4255
4256 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4257
4258 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", 4258
, __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", 4258, "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", 4258, "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", 4258, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4259
4260 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4261
4262 proto_tree_set_ether(new_fi, retval);
4263
4264 return proto_tree_add_node(tree, new_fi);
4265}
4266
4267
4268proto_item *
4269proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4270 tvbuff_t *tvb,
4271 const unsigned start, int length,
4272 const unsigned encoding,
4273 wmem_allocator_t *scope,
4274 const uint8_t **retval,
4275 unsigned *lenretval)
4276{
4277 proto_item *pi;
4278 header_field_info *hfinfo;
4279 field_info *new_fi;
4280 const uint8_t *value;
4281
4282 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", 4282, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4282,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4282, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4283
4284 switch (hfinfo->type) {
4285 case FT_STRING:
4286 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4287 break;
4288 case FT_STRINGZ:
4289 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4290 break;
4291 case FT_UINT_STRING:
4292 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4293 break;
4294 case FT_STRINGZPAD:
4295 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4296 break;
4297 case FT_STRINGZTRUNC:
4298 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4299 break;
4300 default:
4301 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)
4302 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)
;
4303 }
4304
4305 if (retval)
4306 *retval = value;
4307
4308 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4309
4310 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", 4310
, __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", 4310, "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", 4310, "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", 4310, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4311
4312 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4313
4314 proto_tree_set_string(new_fi, (const char*)value);
4315
4316 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4317
4318 pi = proto_tree_add_node(tree, new_fi);
4319
4320 switch (hfinfo->type) {
4321
4322 case FT_STRINGZ:
4323 case FT_STRINGZPAD:
4324 case FT_STRINGZTRUNC:
4325 case FT_UINT_STRING:
4326 break;
4327
4328 case FT_STRING:
4329 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4330 break;
4331
4332 default:
4333 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4333
, __func__, "assertion \"not reached\" failed")
;
4334 }
4335
4336 return pi;
4337}
4338
4339proto_item *
4340proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4341 const unsigned start, int length,
4342 const unsigned encoding, wmem_allocator_t *scope,
4343 const uint8_t **retval)
4344{
4345 unsigned item_length; // Param cannot be NULL in function below
4346 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4347 tvb, start, length, encoding, scope, retval, &item_length);
4348}
4349
4350proto_item *
4351proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4352 tvbuff_t *tvb,
4353 const unsigned start, int length,
4354 const unsigned encoding,
4355 wmem_allocator_t *scope,
4356 char **retval,
4357 unsigned *lenretval)
4358{
4359 proto_item *pi;
4360 header_field_info *hfinfo;
4361 field_info *new_fi;
4362 const uint8_t *value;
4363 uint32_t n = 0;
4364
4365 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", 4365, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4365,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4365, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4366
4367 switch (hfinfo->type) {
4368 case FT_STRING:
4369 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4370 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4371 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4372 break;
4373 case FT_STRINGZ:
4374 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4375 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4376 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4377 break;
4378 case FT_UINT_STRING:
4379 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4380 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4381 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4382 break;
4383 case FT_STRINGZPAD:
4384 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4385 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4386 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4387 break;
4388 case FT_STRINGZTRUNC:
4389 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4390 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4391 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4392 break;
4393 case FT_BYTES:
4394 tvb_ensure_bytes_exist(tvb, start, length);
4395 value = tvb_get_ptr(tvb, start, length);
4396 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4397 *lenretval = length;
4398 break;
4399 case FT_UINT_BYTES:
4400 n = get_uint_value(tree, tvb, start, length, encoding);
4401 tvb_ensure_bytes_exist(tvb, start + length, n);
4402 value = tvb_get_ptr(tvb, start + length, n);
4403 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4404 *lenretval = length + n;
4405 break;
4406 default:
4407 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)
4408 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)
;
4409 }
4410
4411 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4412
4413 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", 4413
, __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", 4413, "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", 4413, "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", 4413, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4414
4415 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4416
4417 switch (hfinfo->type) {
4418
4419 case FT_STRING:
4420 case FT_STRINGZ:
4421 case FT_UINT_STRING:
4422 case FT_STRINGZPAD:
4423 case FT_STRINGZTRUNC:
4424 proto_tree_set_string(new_fi, (const char*)value);
4425 break;
4426
4427 case FT_BYTES:
4428 proto_tree_set_bytes(new_fi, value, length);
4429 break;
4430
4431 case FT_UINT_BYTES:
4432 proto_tree_set_bytes(new_fi, value, n);
4433 break;
4434
4435 default:
4436 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4436
, __func__, "assertion \"not reached\" failed")
;
4437 }
4438
4439 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4440
4441 pi = proto_tree_add_node(tree, new_fi);
4442
4443 switch (hfinfo->type) {
4444
4445 case FT_STRINGZ:
4446 case FT_STRINGZPAD:
4447 case FT_STRINGZTRUNC:
4448 case FT_UINT_STRING:
4449 break;
4450
4451 case FT_STRING:
4452 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4453 break;
4454
4455 case FT_BYTES:
4456 case FT_UINT_BYTES:
4457 break;
4458
4459 default:
4460 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4460
, __func__, "assertion \"not reached\" failed")
;
4461 }
4462
4463 return pi;
4464}
4465
4466proto_item *
4467proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4468 tvbuff_t *tvb,
4469 const unsigned start, int length,
4470 const unsigned encoding,
4471 wmem_allocator_t *scope,
4472 char **retval)
4473{
4474 unsigned item_length; // Param cannot be NULL in function below
4475 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4476 tvb, start, length, encoding, scope, retval, &item_length);
4477}
4478
4479proto_item *
4480proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4481 tvbuff_t *tvb,
4482 const unsigned start, int length, const unsigned encoding,
4483 wmem_allocator_t *scope, char **retval)
4484{
4485 header_field_info *hfinfo;
4486 field_info *new_fi;
4487 nstime_t time_stamp;
4488 int flags;
4489
4490 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", 4490, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4490,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4490, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4491
4492 switch (hfinfo->type) {
4493 case FT_ABSOLUTE_TIME:
4494 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4495 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4496 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4497 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4498 }
4499 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4500 break;
4501 case FT_RELATIVE_TIME:
4502 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4503 *retval = rel_time_to_secs_str(scope, &time_stamp);
4504 break;
4505 default:
4506 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)
4507 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4508 }
4509
4510 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4511
4512 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", 4512
, __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", 4512, "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", 4512, "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", 4512, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4513
4514 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4515
4516 switch (hfinfo->type) {
4517
4518 case FT_ABSOLUTE_TIME:
4519 case FT_RELATIVE_TIME:
4520 proto_tree_set_time(new_fi, &time_stamp);
4521 break;
4522 default:
4523 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4523
, __func__, "assertion \"not reached\" failed")
;
4524 }
4525
4526 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4527
4528 return proto_tree_add_node(tree, new_fi);
4529}
4530
4531/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4532 and returns proto_item* */
4533proto_item *
4534ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4535 const unsigned encoding)
4536{
4537 field_info *new_fi;
4538 header_field_info *hfinfo;
4539 int item_length;
4540 unsigned offset;
4541
4542 offset = ptvc->offset;
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 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4545 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4546
4547 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4548
4549 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4550
4551 /* Coast clear. Try and fake it */
4552 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", 4552
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4552, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4552, "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", 4552, __func__, "Adding %s would put more than %d 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); } } }
;
4553
4554 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4555
4556 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4557 offset, length, encoding);
4558}
4559
4560/* Add an item to a proto_tree, using the text label registered to that item;
4561 the item is extracted from the tvbuff handed to it. */
4562proto_item *
4563proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4564 const unsigned start, int length, const unsigned encoding)
4565{
4566 field_info *new_fi;
4567 int item_length;
4568
4569 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", 4569,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4570
4571 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4572 test_length(hfinfo, tvb, start, item_length, encoding);
4573
4574 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4575
4576 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", 4576
, __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", 4576, "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", 4576, "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", 4576, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4577
4578 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4579
4580 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4581}
4582
4583proto_item *
4584proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4585 const unsigned start, int length, const unsigned encoding)
4586{
4587 register header_field_info *hfinfo;
4588
4589 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", 4589, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4589,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4589, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4590 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4591}
4592
4593/* Add an item to a proto_tree, using the text label registered to that item;
4594 the item is extracted from the tvbuff handed to it.
4595
4596 Return the length of the item through the pointer. */
4597proto_item *
4598proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4599 tvbuff_t *tvb, const unsigned start,
4600 int length, const unsigned encoding,
4601 unsigned *lenretval)
4602{
4603 field_info *new_fi;
4604 int item_length;
4605 proto_item *item;
4606
4607 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", 4607,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4608
4609 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4610 test_length(hfinfo, tvb, start, item_length, encoding);
4611
4612 if (!tree) {
4613 /*
4614 * We need to get the correct item length here.
4615 * That's normally done by proto_tree_new_item(),
4616 * but we won't be calling it.
4617 */
4618 *lenretval = get_full_length(hfinfo, tvb, start, length,
4619 item_length, encoding);
4620 return NULL((void*)0);
4621 }
4622
4623 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", 4630
, __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", 4630, "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", 4630, "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", 4630
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4624 /*((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4630
, __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", 4630, "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", 4630, "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", 4630
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4625 * 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", 4630
, __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", 4630, "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", 4630, "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", 4630
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4626 * 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", 4630
, __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", 4630, "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", 4630, "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", 4630
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4627 */((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4630
, __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", 4630, "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", 4630, "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", 4630
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4628 *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", 4630
, __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", 4630, "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", 4630, "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", 4630
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4629 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", 4630
, __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", 4630, "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", 4630, "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", 4630
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4630 })((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", 4630
, __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", 4630, "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", 4630, "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", 4630
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
;
4631
4632 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4633
4634 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4635 *lenretval = new_fi->length;
4636 return item;
4637}
4638
4639proto_item *
4640proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4641 const unsigned start, int length,
4642 const unsigned encoding, unsigned *lenretval)
4643{
4644 register header_field_info *hfinfo;
4645
4646 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", 4646, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4646,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4646, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4647 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4648}
4649
4650/* which FT_ types can use proto_tree_add_bytes_item() */
4651static inline bool_Bool
4652validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4653{
4654 return (type == FT_BYTES ||
4655 type == FT_UINT_BYTES ||
4656 type == FT_OID ||
4657 type == FT_REL_OID ||
4658 type == FT_SYSTEM_ID );
4659}
4660
4661/* Note: this does no validation that the byte array of an FT_OID or
4662 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4663 so I think it's ok to continue not validating it?
4664 */
4665proto_item *
4666proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4667 const unsigned start, unsigned length,
4668 const unsigned encoding,
4669 GByteArray *retval, unsigned *endoff, int *err)
4670{
4671 field_info *new_fi;
4672 GByteArray *bytes = retval;
4673 GByteArray *created_bytes = NULL((void*)0);
4674 bool_Bool failed = false0;
4675 uint32_t n = 0;
4676 header_field_info *hfinfo;
4677 bool_Bool generate = (bytes || tree) ? true1 : false0;
4678
4679 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", 4679, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4679,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4679, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4680
4681 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", 4681,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4682
4683 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", 4684, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4684 "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", 4684, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4685
4686 if (length == 0) {
4687 return NULL((void*)0);
4688 }
4689
4690 if (encoding & ENC_STR_NUM0x01000000) {
4691 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"
)
;
4692 }
4693
4694 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4695 if (hfinfo->type == FT_UINT_BYTES) {
4696 /* can't decode FT_UINT_BYTES from strings */
4697 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")
4698 "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")
;
4699 }
4700
4701 unsigned hex_encoding = encoding;
4702 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4703 /* If none of the separator values are used,
4704 * assume no separator (the common case). */
4705 hex_encoding |= ENC_SEP_NONE0x00010000;
4706#if 0
4707 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")
4708 "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")
;
4709#endif
4710 }
4711
4712 if (!bytes) {
4713 /* caller doesn't care about return value, but we need it to
4714 call tvb_get_string_bytes() and set the tree later */
4715 bytes = created_bytes = g_byte_array_new();
4716 }
4717
4718 /*
4719 * bytes might be NULL after this, but can't add expert
4720 * error until later; if it's NULL, just note that
4721 * it failed.
4722 */
4723 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4724 if (bytes == NULL((void*)0))
4725 failed = true1;
4726 }
4727 else if (generate) {
4728 tvb_ensure_bytes_exist(tvb, start, length);
4729
4730 if (hfinfo->type == FT_UINT_BYTES) {
4731 n = length; /* n is now the "header" length */
4732 length = get_uint_value(tree, tvb, start, n, encoding);
4733 /* length is now the value's length; only store the value in the array */
4734 tvb_ensure_bytes_exist(tvb, start + n, length);
4735 if (!bytes) {
4736 /* caller doesn't care about return value, but
4737 * we may need it to set the tree later */
4738 bytes = created_bytes = g_byte_array_new();
4739 }
4740 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4741 }
4742 else if (length > 0) {
4743 if (!bytes) {
4744 /* caller doesn't care about return value, but
4745 * we may need it to set the tree later */
4746 bytes = created_bytes = g_byte_array_new();
4747 }
4748 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4749 }
4750
4751 if (endoff)
4752 *endoff = start + n + length;
4753 }
4754
4755 if (err)
4756 *err = failed ? EINVAL22 : 0;
4757
4758 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); }
4759 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4760 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); }
4761 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); }
4762 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); }
4763 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4764 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4765
4766 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", 4772
, __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", 4772, "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", 4772, "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", 4772
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4767 {((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", 4772
, __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", 4772, "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", 4772, "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", 4772
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4768 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", 4772
, __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", 4772, "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", 4772, "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", 4772
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4769 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", 4772
, __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", 4772, "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", 4772, "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", 4772
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4770 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", 4772
, __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", 4772, "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", 4772, "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", 4772
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4771 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", 4772
, __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", 4772, "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", 4772, "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", 4772
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4772 } )((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", 4772
, __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", 4772, "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", 4772, "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", 4772
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4773
4774 /* n will be zero except when it's a FT_UINT_BYTES */
4775 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4776
4777 if (encoding & ENC_STRING0x07000000) {
4778 if (failed)
4779 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4780
4781 if (bytes)
4782 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4783 else
4784 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4785
4786 if (created_bytes)
4787 g_byte_array_free(created_bytes, true1);
4788 }
4789 else {
4790 /* n will be zero except when it's a FT_UINT_BYTES */
4791 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4792
4793 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4794 * use the byte array created above in this case.
4795 */
4796 if (created_bytes)
4797 g_byte_array_free(created_bytes, true1);
4798
4799 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4800 (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)
;
4801 }
4802
4803 return proto_tree_add_node(tree, new_fi);
4804}
4805
4806
4807proto_item *
4808proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4809 const unsigned start, const unsigned length,
4810 const unsigned encoding,
4811 nstime_t *retval, unsigned *endoff, int *err)
4812{
4813 field_info *new_fi;
4814 nstime_t time_stamp;
4815 int saved_err = 0;
4816 header_field_info *hfinfo;
4817
4818 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", 4818, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4818,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4818, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4819
4820 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", 4820,
"hfinfo != ((void*)0)", "Not passed hfi."))))
;
4821
4822 if (length == 0) {
4823 if(retval) {
4824 nstime_set_zero(retval);
4825 }
4826 return NULL((void*)0);
4827 }
4828
4829 nstime_set_zero(&time_stamp);
4830
4831 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4832 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", 4832, ((hfinfo))->abbrev))))
;
4833 /* The only string format that could be a relative time is
4834 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4835 * relative to "now" currently.
4836 */
4837 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4838 saved_err = EINVAL22;
4839 }
4840 else {
4841 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", 4841, ((hfinfo))->abbrev))))
;
4842 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4843
4844 tvb_ensure_bytes_exist(tvb, start, length);
4845 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4846 if (endoff) *endoff = start + length;
4847 }
4848
4849 if (err) *err = saved_err;
4850
4851 if (retval) {
4852 retval->secs = time_stamp.secs;
4853 retval->nsecs = time_stamp.nsecs;
4854 }
4855
4856 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4857
4858 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", 4858
, __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", 4858, "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", 4858, "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", 4858, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4859
4860 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4861
4862 proto_tree_set_time(new_fi, &time_stamp);
4863
4864 if (encoding & ENC_STRING0x07000000) {
4865 if (saved_err)
4866 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4867 }
4868 else {
4869 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4870 (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)
;
4871 }
4872
4873 return proto_tree_add_node(tree, new_fi);
4874}
4875
4876/* Add a FT_NONE to a proto_tree */
4877proto_item *
4878proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4879 const unsigned start, int length, const char *format,
4880 ...)
4881{
4882 proto_item *pi;
4883 va_list ap;
4884 header_field_info *hfinfo;
4885
4886 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4887
4888 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", 4888
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4888, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4888, "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", 4888, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4889
4890 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", 4890
, ((hfinfo))->abbrev))))
;
4891
4892 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4893
4894 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4894, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4895
4896 va_start(ap, format)__builtin_va_start(ap, format);
4897 proto_tree_set_representation(pi, format, ap);
4898 va_end(ap)__builtin_va_end(ap);
4899
4900 /* no value to set for FT_NONE */
4901 return pi;
4902}
4903
4904/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4905 * offset, and returns proto_item* */
4906proto_item *
4907ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4908 const unsigned encoding)
4909{
4910 proto_item *item;
4911
4912 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4913 length, encoding);
4914
4915 return item;
4916}
4917
4918/* Advance the ptvcursor's offset within its tvbuff without
4919 * adding anything to the proto_tree. */
4920void
4921ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4922{
4923 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4924 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4925 }
4926}
4927
4928
4929static void
4930proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4931{
4932 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4932, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4933 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4934}
4935
4936/* Add a FT_PROTOCOL to a proto_tree */
4937proto_item *
4938proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4939 unsigned start, int length, const char *format, ...)
4940{
4941 proto_item *pi;
4942 field_info *new_fi;
4943 tvbuff_t *protocol_tvb;
4944 va_list ap;
4945 header_field_info *hfinfo;
4946 char* protocol_rep;
4947
4948 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4949
4950 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", 4950
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4950, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4950, "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", 4950, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4951
4952 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"
, 4952, ((hfinfo))->abbrev))))
;
4953
4954 /*
4955 * This can throw an exception when it calls get_hfi_length before
4956 * it allocates anything, if length is nonzero and start is past
4957 * the end of the tvb. Afterwards it can't throw an exception,
4958 * as length is clamped to the captured length remaining.
4959 */
4960 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4961 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4962 /* Start the protocol_tvb at the correct start offset, but allow it
4963 * to be lengthened later via finfo_set_len. */
4964 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4965
4966 va_start(ap, format)__builtin_va_start(ap, format);
4967 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4968 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4969 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)
;
4970 va_end(ap)__builtin_va_end(ap);
4971
4972 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4972, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4973
4974 va_start(ap, format)__builtin_va_start(ap, format);
4975 proto_tree_set_representation(pi, format, ap);
4976 va_end(ap)__builtin_va_end(ap);
4977
4978 return pi;
4979}
4980
4981/* Add a FT_BYTES to a proto_tree */
4982proto_item *
4983proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4984 int length, const uint8_t *start_ptr)
4985{
4986 proto_item *pi;
4987 header_field_info *hfinfo;
4988 int item_length;
4989
4990 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", 4990, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4990,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4990, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4991 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4992 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4993
4994 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4995
4996 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", 4996
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4996, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4996, "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", 4996, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4997
4998 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",
4998, ((hfinfo))->abbrev))))
;
4999
5000 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
5001 start_ptr = tvb_get_ptr(tvb, start, length);
5002
5003 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5004 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
5005
5006 return pi;
5007}
5008
5009/* Add a FT_BYTES to a proto_tree */
5010proto_item *
5011proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5012 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
5013{
5014 proto_item *pi;
5015 header_field_info *hfinfo;
5016 int item_length;
5017
5018 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", 5018, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5018,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5018, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5019 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
5020 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5021
5022 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5023
5024 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", 5024
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5024, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5024, "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", 5024, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5025
5026 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",
5026, ((hfinfo))->abbrev))))
;
5027
5028 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
5029 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
5030
5031 return pi;
5032}
5033
5034proto_item *
5035proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5036 unsigned start, int length,
5037 const uint8_t *start_ptr,
5038 const char *format, ...)
5039{
5040 proto_item *pi;
5041 va_list ap;
5042
5043 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5044
5045 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; }
;
5046
5047 va_start(ap, format)__builtin_va_start(ap, format);
5048 proto_tree_set_representation_value(pi, format, ap);
5049 va_end(ap)__builtin_va_end(ap);
5050
5051 return pi;
5052}
5053
5054proto_item *
5055proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5056 unsigned start, int length, const uint8_t *start_ptr,
5057 const char *format, ...)
5058{
5059 proto_item *pi;
5060 va_list ap;
5061
5062 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5063
5064 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; }
;
5065
5066 va_start(ap, format)__builtin_va_start(ap, format);
5067 proto_tree_set_representation(pi, format, ap);
5068 va_end(ap)__builtin_va_end(ap);
5069
5070 return pi;
5071}
5072
5073static void
5074proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
5075{
5076 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5076, "length >= 0"
))))
;
5077 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", 5077, "start_ptr != ((void*)0) || length == 0"
))))
;
5078
5079 fvalue_set_bytes_data(fi->value, start_ptr, length);
5080}
5081
5082
5083static void
5084proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5085{
5086 tvb_ensure_bytes_exist(tvb, offset, length);
5087 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5088}
5089
5090static void
5091proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5092{
5093 GByteArray *bytes;
5094
5095 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5095, "value != ((void*)0)"
))))
;
5096
5097 bytes = byte_array_dup(value);
5098
5099 fvalue_set_byte_array(fi->value, bytes);
5100}
5101
5102/* Add a FT_*TIME to a proto_tree */
5103proto_item *
5104proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5105 unsigned length, const nstime_t *value_ptr)
5106{
5107 proto_item *pi;
5108 header_field_info *hfinfo;
5109
5110 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5111
5112 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", 5112
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5112, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5112, "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", 5112, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5113
5114 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", 5114, ((hfinfo))->abbrev))))
;
5115
5116 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5117 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5118
5119 return pi;
5120}
5121
5122proto_item *
5123proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5124 unsigned start, unsigned length, nstime_t *value_ptr,
5125 const char *format, ...)
5126{
5127 proto_item *pi;
5128 va_list ap;
5129
5130 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5131 if (pi != tree) {
5132 va_start(ap, format)__builtin_va_start(ap, format);
5133 proto_tree_set_representation_value(pi, format, ap);
5134 va_end(ap)__builtin_va_end(ap);
5135 }
5136
5137 return pi;
5138}
5139
5140proto_item *
5141proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5142 unsigned start, unsigned length, nstime_t *value_ptr,
5143 const char *format, ...)
5144{
5145 proto_item *pi;
5146 va_list ap;
5147
5148 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5149 if (pi != tree) {
5150 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5150, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5151
5152 va_start(ap, format)__builtin_va_start(ap, format);
5153 proto_tree_set_representation(pi, format, ap);
5154 va_end(ap)__builtin_va_end(ap);
5155 }
5156
5157 return pi;
5158}
5159
5160/* Set the FT_*TIME value */
5161static void
5162proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5163{
5164 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5164, "value_ptr != ((void*)0)"
))))
;
5165
5166 fvalue_set_time(fi->value, value_ptr);
5167}
5168
5169/* Add a FT_IPXNET to a proto_tree */
5170proto_item *
5171proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5172 unsigned length, uint32_t value)
5173{
5174 proto_item *pi;
5175 header_field_info *hfinfo;
5176
5177 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5178
5179 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", 5179
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5179, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5179, "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", 5179, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5180
5181 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"
, 5181, ((hfinfo))->abbrev))))
;
5182
5183 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5184 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5185
5186 return pi;
5187}
5188
5189proto_item *
5190proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5191 unsigned start, unsigned length, uint32_t value,
5192 const char *format, ...)
5193{
5194 proto_item *pi;
5195 va_list ap;
5196
5197 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5198 if (pi != tree) {
5199 va_start(ap, format)__builtin_va_start(ap, format);
5200 proto_tree_set_representation_value(pi, format, ap);
5201 va_end(ap)__builtin_va_end(ap);
5202 }
5203
5204 return pi;
5205}
5206
5207proto_item *
5208proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5209 unsigned start, unsigned length, uint32_t value,
5210 const char *format, ...)
5211{
5212 proto_item *pi;
5213 va_list ap;
5214
5215 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5216 if (pi != tree) {
5217 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5217, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5218
5219 va_start(ap, format)__builtin_va_start(ap, format);
5220 proto_tree_set_representation(pi, format, ap);
5221 va_end(ap)__builtin_va_end(ap);
5222 }
5223
5224 return pi;
5225}
5226
5227/* Set the FT_IPXNET value */
5228static void
5229proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5230{
5231 fvalue_set_uinteger(fi->value, value);
5232}
5233
5234/* Add a FT_IPv4 to a proto_tree */
5235proto_item *
5236proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5237 unsigned length, ws_in4_addr value)
5238{
5239 proto_item *pi;
5240 header_field_info *hfinfo;
5241
5242 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5243
5244 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", 5244
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5244, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5244, "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", 5244, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5245
5246 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", 5246
, ((hfinfo))->abbrev))))
;
5247
5248 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5249 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5250
5251 return pi;
5252}
5253
5254proto_item *
5255proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5256 unsigned start, unsigned length, ws_in4_addr value,
5257 const char *format, ...)
5258{
5259 proto_item *pi;
5260 va_list ap;
5261
5262 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5263 if (pi != tree) {
5264 va_start(ap, format)__builtin_va_start(ap, format);
5265 proto_tree_set_representation_value(pi, format, ap);
5266 va_end(ap)__builtin_va_end(ap);
5267 }
5268
5269 return pi;
5270}
5271
5272proto_item *
5273proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5274 unsigned start, unsigned length, ws_in4_addr value,
5275 const char *format, ...)
5276{
5277 proto_item *pi;
5278 va_list ap;
5279
5280 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5281 if (pi != tree) {
5282 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5282, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5283
5284 va_start(ap, format)__builtin_va_start(ap, format);
5285 proto_tree_set_representation(pi, format, ap);
5286 va_end(ap)__builtin_va_end(ap);
5287 }
5288
5289 return pi;
5290}
5291
5292/* Set the FT_IPv4 value */
5293static void
5294proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5295{
5296 ipv4_addr_and_mask ipv4;
5297 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5298 fvalue_set_ipv4(fi->value, &ipv4);
5299}
5300
5301/* Add a FT_IPv6 to a proto_tree */
5302proto_item *
5303proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5304 unsigned length, const ws_in6_addr *value)
5305{
5306 proto_item *pi;
5307 header_field_info *hfinfo;
5308
5309 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5310
5311 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", 5311
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5311, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5311, "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", 5311, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5312
5313 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", 5313
, ((hfinfo))->abbrev))))
;
5314
5315 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5316 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5317
5318 return pi;
5319}
5320
5321proto_item *
5322proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5323 unsigned start, unsigned length,
5324 const ws_in6_addr *value_ptr,
5325 const char *format, ...)
5326{
5327 proto_item *pi;
5328 va_list ap;
5329
5330 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5331 if (pi != tree) {
5332 va_start(ap, format)__builtin_va_start(ap, format);
5333 proto_tree_set_representation_value(pi, format, ap);
5334 va_end(ap)__builtin_va_end(ap);
5335 }
5336
5337 return pi;
5338}
5339
5340proto_item *
5341proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5342 unsigned start, unsigned length,
5343 const ws_in6_addr *value_ptr,
5344 const char *format, ...)
5345{
5346 proto_item *pi;
5347 va_list ap;
5348
5349 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5350 if (pi != tree) {
5351 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5351, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5352
5353 va_start(ap, format)__builtin_va_start(ap, format);
5354 proto_tree_set_representation(pi, format, ap);
5355 va_end(ap)__builtin_va_end(ap);
5356 }
5357
5358 return pi;
5359}
5360
5361/* Set the FT_IPv6 value */
5362static void
5363proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5364{
5365 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5365, "value != ((void*)0)"
))))
;
5366 ipv6_addr_and_prefix ipv6;
5367 ipv6.addr = *value;
5368 ipv6.prefix = 128;
5369 fvalue_set_ipv6(fi->value, &ipv6);
5370}
5371
5372static void
5373proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5374{
5375 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5376}
5377
5378/* Set the FT_FCWWN value */
5379static void
5380proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5381{
5382 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5382, "value_ptr != ((void*)0)"
))))
;
5383 fvalue_set_fcwwn(fi->value, value_ptr);
5384}
5385
5386static void
5387proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5388{
5389 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5390}
5391
5392/* Add a FT_GUID to a proto_tree */
5393proto_item *
5394proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5395 unsigned length, const e_guid_t *value_ptr)
5396{
5397 proto_item *pi;
5398 header_field_info *hfinfo;
5399
5400 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5401
5402 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", 5402
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5402, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5402, "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", 5402, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5403
5404 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", 5404
, ((hfinfo))->abbrev))))
;
5405
5406 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5407 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5408
5409 return pi;
5410}
5411
5412proto_item *
5413proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5414 unsigned start, unsigned length,
5415 const e_guid_t *value_ptr,
5416 const char *format, ...)
5417{
5418 proto_item *pi;
5419 va_list ap;
5420
5421 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5422 if (pi != tree) {
5423 va_start(ap, format)__builtin_va_start(ap, format);
5424 proto_tree_set_representation_value(pi, format, ap);
5425 va_end(ap)__builtin_va_end(ap);
5426 }
5427
5428 return pi;
5429}
5430
5431proto_item *
5432proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5433 unsigned start, unsigned length, const e_guid_t *value_ptr,
5434 const char *format, ...)
5435{
5436 proto_item *pi;
5437 va_list ap;
5438
5439 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5440 if (pi != tree) {
5441 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5441, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5442
5443 va_start(ap, format)__builtin_va_start(ap, format);
5444 proto_tree_set_representation(pi, format, ap);
5445 va_end(ap)__builtin_va_end(ap);
5446 }
5447
5448 return pi;
5449}
5450
5451/* Set the FT_GUID value */
5452static void
5453proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5454{
5455 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5455, "value_ptr != ((void*)0)"
))))
;
5456 fvalue_set_guid(fi->value, value_ptr);
5457}
5458
5459static void
5460proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5461 const unsigned encoding)
5462{
5463 e_guid_t guid;
5464
5465 tvb_get_guid(tvb, start, &guid, encoding);
5466 proto_tree_set_guid(fi, &guid);
5467}
5468
5469/* Add a FT_OID to a proto_tree */
5470proto_item *
5471proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5472 unsigned length, const uint8_t* value_ptr)
5473{
5474 proto_item *pi;
5475 header_field_info *hfinfo;
5476
5477 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5478
5479 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", 5479
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5479, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5479, "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", 5479, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5480
5481 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", 5481
, ((hfinfo))->abbrev))))
;
5482
5483 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5484 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5485
5486 return pi;
5487}
5488
5489proto_item *
5490proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5491 unsigned start, unsigned length,
5492 const uint8_t* value_ptr,
5493 const char *format, ...)
5494{
5495 proto_item *pi;
5496 va_list ap;
5497
5498 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5499 if (pi != tree) {
5500 va_start(ap, format)__builtin_va_start(ap, format);
5501 proto_tree_set_representation_value(pi, format, ap);
5502 va_end(ap)__builtin_va_end(ap);
5503 }
5504
5505 return pi;
5506}
5507
5508proto_item *
5509proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5510 unsigned start, unsigned length, const uint8_t* value_ptr,
5511 const char *format, ...)
5512{
5513 proto_item *pi;
5514 va_list ap;
5515
5516 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5517 if (pi != tree) {
5518 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5518, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5519
5520 va_start(ap, format)__builtin_va_start(ap, format);
5521 proto_tree_set_representation(pi, format, ap);
5522 va_end(ap)__builtin_va_end(ap);
5523 }
5524
5525 return pi;
5526}
5527
5528/* Set the FT_OID value */
5529static void
5530proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5531{
5532 GByteArray *bytes;
5533
5534 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", 5534, "value_ptr != ((void*)0) || length == 0"
))))
;
5535
5536 bytes = g_byte_array_new();
5537 if (length > 0) {
5538 g_byte_array_append(bytes, value_ptr, length);
5539 }
5540 fvalue_set_byte_array(fi->value, bytes);
5541}
5542
5543static void
5544proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5545{
5546 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5547}
5548
5549/* Set the FT_SYSTEM_ID value */
5550static void
5551proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5552{
5553 GByteArray *bytes;
5554
5555 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", 5555, "value_ptr != ((void*)0) || length == 0"
))))
;
5556
5557 bytes = g_byte_array_new();
5558 if (length > 0) {
5559 g_byte_array_append(bytes, value_ptr, length);
5560 }
5561 fvalue_set_byte_array(fi->value, bytes);
5562}
5563
5564static void
5565proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5566{
5567 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5568}
5569
5570/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5571 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5572 * is destroyed. */
5573proto_item *
5574proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5575 int length, const char* value)
5576{
5577 proto_item *pi;
5578 header_field_info *hfinfo;
5579 int item_length;
5580
5581 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", 5581, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5581,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5581, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5582 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5583 /*
5584 * Special case - if the length is 0, skip the test, so that
5585 * we can have an empty string right after the end of the
5586 * packet. (This handles URL-encoded forms where the last field
5587 * has no value so the form ends right after the =.)
5588 *
5589 * XXX - length zero makes sense for FT_STRING, and more or less
5590 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5591 * for FT_STRINGZ (except that a number of fields that should be
5592 * one of the others are actually registered as FT_STRINGZ.)
5593 */
5594 if (item_length != 0)
5595 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
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_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", 5601, ((hfinfo))->abbrev))))
;
5602
5603 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5604 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5604, "length >= 0"
))))
;
5605
5606 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", 5606, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5607 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5608
5609 return pi;
5610}
5611
5612proto_item *
5613proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5614 unsigned start, int length, const char* value,
5615 const char *format,
5616 ...)
5617{
5618 proto_item *pi;
5619 va_list ap;
5620
5621 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5622 if (pi != tree) {
5623 va_start(ap, format)__builtin_va_start(ap, format);
5624 proto_tree_set_representation_value(pi, format, ap);
5625 va_end(ap)__builtin_va_end(ap);
5626 }
5627
5628 return pi;
5629}
5630
5631proto_item *
5632proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5633 unsigned start, int length, const char* value,
5634 const char *format, ...)
5635{
5636 proto_item *pi;
5637 va_list ap;
5638
5639 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5640 if (pi != tree) {
5641 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5641, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5642
5643 va_start(ap, format)__builtin_va_start(ap, format);
5644 proto_tree_set_representation(pi, format, ap);
5645 va_end(ap)__builtin_va_end(ap);
5646 }
5647
5648 return pi;
5649}
5650
5651/* Set the FT_STRING value */
5652static void
5653proto_tree_set_string(field_info *fi, const char* value)
5654{
5655 if (value) {
5656 fvalue_set_string(fi->value, value);
5657 } else {
5658 /*
5659 * XXX - why is a null value for a string field
5660 * considered valid?
5661 */
5662 fvalue_set_string(fi->value, "[ Null ]");
5663 }
5664}
5665
5666/* Set the FT_AX25 value */
5667static void
5668proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5669{
5670 fvalue_set_ax25(fi->value, value);
5671}
5672
5673static void
5674proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5675{
5676 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5677}
5678
5679/* Set the FT_VINES value */
5680static void
5681proto_tree_set_vines(field_info *fi, const uint8_t* value)
5682{
5683 fvalue_set_vines(fi->value, value);
5684}
5685
5686static void
5687proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5688{
5689 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5690}
5691
5692/* Add a FT_ETHER to a proto_tree */
5693proto_item *
5694proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5695 unsigned length, const uint8_t* value)
5696{
5697 proto_item *pi;
5698 header_field_info *hfinfo;
5699
5700 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5701
5702 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", 5702
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5702, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5702, "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", 5702, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5703
5704 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",
5704, ((hfinfo))->abbrev))))
;
5705
5706 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5707 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5708
5709 return pi;
5710}
5711
5712proto_item *
5713proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5714 unsigned start, unsigned length, const uint8_t* value,
5715 const char *format, ...)
5716{
5717 proto_item *pi;
5718 va_list ap;
5719
5720 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5721 if (pi != tree) {
5722 va_start(ap, format)__builtin_va_start(ap, format);
5723 proto_tree_set_representation_value(pi, format, ap);
5724 va_end(ap)__builtin_va_end(ap);
5725 }
5726
5727 return pi;
5728}
5729
5730proto_item *
5731proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5732 unsigned start, unsigned length, const uint8_t* value,
5733 const char *format, ...)
5734{
5735 proto_item *pi;
5736 va_list ap;
5737
5738 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5739 if (pi != tree) {
5740 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5740, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5741
5742 va_start(ap, format)__builtin_va_start(ap, format);
5743 proto_tree_set_representation(pi, format, ap);
5744 va_end(ap)__builtin_va_end(ap);
5745 }
5746
5747 return pi;
5748}
5749
5750/* Set the FT_ETHER value */
5751static void
5752proto_tree_set_ether(field_info *fi, const uint8_t* value)
5753{
5754 fvalue_set_ether(fi->value, value);
5755}
5756
5757static void
5758proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5759{
5760 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5761}
5762
5763/* Add a FT_BOOLEAN to a proto_tree */
5764proto_item *
5765proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5766 unsigned length, uint64_t value)
5767{
5768 proto_item *pi;
5769 header_field_info *hfinfo;
5770
5771 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5772
5773 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", 5773
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5773, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5773, "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", 5773, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5774
5775 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"
, 5775, ((hfinfo))->abbrev))))
;
5776
5777 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5778 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5779
5780 return pi;
5781}
5782
5783proto_item *
5784proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5785 tvbuff_t *tvb, unsigned start, unsigned length,
5786 uint64_t value, const char *format, ...)
5787{
5788 proto_item *pi;
5789 va_list ap;
5790
5791 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5792 if (pi != tree) {
5793 va_start(ap, format)__builtin_va_start(ap, format);
5794 proto_tree_set_representation_value(pi, format, ap);
5795 va_end(ap)__builtin_va_end(ap);
5796 }
5797
5798 return pi;
5799}
5800
5801proto_item *
5802proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5803 unsigned start, unsigned length, uint64_t value,
5804 const char *format, ...)
5805{
5806 proto_item *pi;
5807 va_list ap;
5808
5809 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5810 if (pi != tree) {
5811 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5811, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5812
5813 va_start(ap, format)__builtin_va_start(ap, format);
5814 proto_tree_set_representation(pi, format, ap);
5815 va_end(ap)__builtin_va_end(ap);
5816 }
5817
5818 return pi;
5819}
5820
5821/* Set the FT_BOOLEAN value */
5822static void
5823proto_tree_set_boolean(field_info *fi, uint64_t value)
5824{
5825 proto_tree_set_uint64(fi, value);
5826}
5827
5828/* Generate, into "buf", a string showing the bits of a bitfield.
5829 Return a pointer to the character after that string. */
5830static char *
5831other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5832{
5833 int i = 0;
5834 uint64_t bit;
5835 char *p;
5836
5837 p = buf;
5838
5839 /* This is a devel error. It is safer to stop here. */
5840 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5840, "width >= 1"
))))
;
5841
5842 bit = UINT64_C(1)1UL << (width - 1);
5843 for (;;) {
5844 if (mask & bit) {
5845 /* This bit is part of the field. Show its value. */
5846 if (val & bit)
5847 *p++ = '1';
5848 else
5849 *p++ = '0';
5850 } else {
5851 /* This bit is not part of the field. */
5852 *p++ = '.';
5853 }
5854 bit >>= 1;
5855 i++;
5856 if (i >= width)
5857 break;
5858 if (i % 4 == 0)
5859 *p++ = ' ';
5860 }
5861 *p = '\0';
5862 return p;
5863}
5864
5865static char *
5866decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5867{
5868 char *p;
5869
5870 p = other_decode_bitfield_value(buf, val, mask, width);
5871 p = g_stpcpy(p, " = ");
5872
5873 return p;
5874}
5875
5876static char *
5877other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5878{
5879 int i = 0;
5880 uint64_t bit;
5881 char *p;
5882
5883 p = buf;
5884
5885 /* This is a devel error. It is safer to stop here. */
5886 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5886, "width >= 1"
))))
;
5887
5888 bit = UINT64_C(1)1UL << (width - 1);
5889 for (;;) {
5890 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5891 (mask & bit)) {
5892 /* This bit is part of the field. Show its value. */
5893 if (val & bit)
5894 *p++ = '1';
5895 else
5896 *p++ = '0';
5897 } else {
5898 /* This bit is not part of the field. */
5899 *p++ = '.';
5900 }
5901 bit >>= 1;
5902 i++;
5903 if (i >= width)
5904 break;
5905 if (i % 4 == 0)
5906 *p++ = ' ';
5907 }
5908
5909 *p = '\0';
5910 return p;
5911}
5912
5913static char *
5914decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5915{
5916 char *p;
5917
5918 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5919 p = g_stpcpy(p, " = ");
5920
5921 return p;
5922}
5923
5924/* Add a FT_FLOAT to a proto_tree */
5925proto_item *
5926proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5927 unsigned length, float value)
5928{
5929 proto_item *pi;
5930 header_field_info *hfinfo;
5931
5932 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5933
5934 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", 5934
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5934, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5934, "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", 5934, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5935
5936 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",
5936, ((hfinfo))->abbrev))))
;
5937
5938 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5939 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5940
5941 return pi;
5942}
5943
5944proto_item *
5945proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5946 unsigned start, unsigned length, float value,
5947 const char *format, ...)
5948{
5949 proto_item *pi;
5950 va_list ap;
5951
5952 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5953 if (pi != tree) {
5954 va_start(ap, format)__builtin_va_start(ap, format);
5955 proto_tree_set_representation_value(pi, format, ap);
5956 va_end(ap)__builtin_va_end(ap);
5957 }
5958
5959 return pi;
5960}
5961
5962proto_item *
5963proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5964 unsigned start, unsigned length, float value,
5965 const char *format, ...)
5966{
5967 proto_item *pi;
5968 va_list ap;
5969
5970 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5971 if (pi != tree) {
5972 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5972, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5973
5974 va_start(ap, format)__builtin_va_start(ap, format);
5975 proto_tree_set_representation(pi, format, ap);
5976 va_end(ap)__builtin_va_end(ap);
5977 }
5978
5979 return pi;
5980}
5981
5982/* Set the FT_FLOAT value */
5983static void
5984proto_tree_set_float(field_info *fi, float value)
5985{
5986 fvalue_set_floating(fi->value, value);
5987}
5988
5989/* Add a FT_DOUBLE to a proto_tree */
5990proto_item *
5991proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5992 unsigned length, double value)
5993{
5994 proto_item *pi;
5995 header_field_info *hfinfo;
5996
5997 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5998
5999 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", 5999
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5999, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5999, "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", 5999, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6000
6001 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"
, 6001, ((hfinfo))->abbrev))))
;
6002
6003 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6004 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
6005
6006 return pi;
6007}
6008
6009proto_item *
6010proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6011 unsigned start, unsigned length, double value,
6012 const char *format, ...)
6013{
6014 proto_item *pi;
6015 va_list ap;
6016
6017 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6018 if (pi != tree) {
6019 va_start(ap, format)__builtin_va_start(ap, format);
6020 proto_tree_set_representation_value(pi, format, ap);
6021 va_end(ap)__builtin_va_end(ap);
6022 }
6023
6024 return pi;
6025}
6026
6027proto_item *
6028proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6029 unsigned start, unsigned length, double value,
6030 const char *format, ...)
6031{
6032 proto_item *pi;
6033 va_list ap;
6034
6035 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6036 if (pi != tree) {
6037 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6037, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6038
6039 va_start(ap, format)__builtin_va_start(ap, format);
6040 proto_tree_set_representation(pi, format, ap);
6041 va_end(ap)__builtin_va_end(ap);
6042 }
6043
6044 return pi;
6045}
6046
6047/* Set the FT_DOUBLE value */
6048static void
6049proto_tree_set_double(field_info *fi, double value)
6050{
6051 fvalue_set_floating(fi->value, value);
6052}
6053
6054/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
6055proto_item *
6056proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6057 unsigned length, uint32_t value)
6058{
6059 proto_item *pi = NULL((void*)0);
6060 header_field_info *hfinfo;
6061
6062 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6063
6064 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", 6064
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6064, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6064, "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", 6064, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6065
6066 switch (hfinfo->type) {
6067 case FT_CHAR:
6068 case FT_UINT8:
6069 case FT_UINT16:
6070 case FT_UINT24:
6071 case FT_UINT32:
6072 case FT_FRAMENUM:
6073 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6074 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
6075 break;
6076
6077 default:
6078 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)
6079 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)
;
6080 }
6081
6082 return pi;
6083}
6084
6085proto_item *
6086proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6087 unsigned start, unsigned length, uint32_t value,
6088 const char *format, ...)
6089{
6090 proto_item *pi;
6091 va_list ap;
6092
6093 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6094 if (pi != tree) {
6095 va_start(ap, format)__builtin_va_start(ap, format);
6096 proto_tree_set_representation_value(pi, format, ap);
6097 va_end(ap)__builtin_va_end(ap);
6098 }
6099
6100 return pi;
6101}
6102
6103proto_item *
6104proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6105 unsigned start, unsigned length, uint32_t value,
6106 const char *format, ...)
6107{
6108 proto_item *pi;
6109 va_list ap;
6110
6111 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6112 if (pi != tree) {
6113 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6113, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6114
6115 va_start(ap, format)__builtin_va_start(ap, format);
6116 proto_tree_set_representation(pi, format, ap);
6117 va_end(ap)__builtin_va_end(ap);
6118 }
6119
6120 return pi;
6121}
6122
6123/* Set the FT_UINT{8,16,24,32} value */
6124static void
6125proto_tree_set_uint(field_info *fi, uint32_t value)
6126{
6127 const header_field_info *hfinfo;
6128 uint32_t integer;
6129
6130 hfinfo = fi->hfinfo;
6131 integer = value;
6132
6133 if (hfinfo->bitmask) {
6134 /* Mask out irrelevant portions */
6135 integer &= (uint32_t)(hfinfo->bitmask);
6136
6137 /* Shift bits */
6138 integer >>= hfinfo_bitshift(hfinfo);
6139
6140 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6141 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)
;
6142 }
6143
6144 fvalue_set_uinteger(fi->value, integer);
6145}
6146
6147/* Add FT_UINT{40,48,56,64} to a proto_tree */
6148proto_item *
6149proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6150 unsigned length, uint64_t value)
6151{
6152 proto_item *pi = NULL((void*)0);
6153 header_field_info *hfinfo;
6154
6155 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6156
6157 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", 6157
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6157, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6157, "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", 6157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6158
6159 switch (hfinfo->type) {
6160 case FT_UINT40:
6161 case FT_UINT48:
6162 case FT_UINT56:
6163 case FT_UINT64:
6164 case FT_FRAMENUM:
6165 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6166 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6167 break;
6168
6169 default:
6170 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)
6171 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)
;
6172 }
6173
6174 return pi;
6175}
6176
6177proto_item *
6178proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6179 unsigned start, unsigned length, uint64_t value,
6180 const char *format, ...)
6181{
6182 proto_item *pi;
6183 va_list ap;
6184
6185 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6186 if (pi != tree) {
6187 va_start(ap, format)__builtin_va_start(ap, format);
6188 proto_tree_set_representation_value(pi, format, ap);
6189 va_end(ap)__builtin_va_end(ap);
6190 }
6191
6192 return pi;
6193}
6194
6195proto_item *
6196proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6197 unsigned start, unsigned length, uint64_t value,
6198 const char *format, ...)
6199{
6200 proto_item *pi;
6201 va_list ap;
6202
6203 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6204 if (pi != tree) {
6205 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6205, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6206
6207 va_start(ap, format)__builtin_va_start(ap, format);
6208 proto_tree_set_representation(pi, format, ap);
6209 va_end(ap)__builtin_va_end(ap);
6210 }
6211
6212 return pi;
6213}
6214
6215/* Set the FT_UINT{40,48,56,64} value */
6216static void
6217proto_tree_set_uint64(field_info *fi, uint64_t value)
6218{
6219 const header_field_info *hfinfo;
6220 uint64_t integer;
6221
6222 hfinfo = fi->hfinfo;
6223 integer = value;
6224
6225 if (hfinfo->bitmask) {
6226 /* Mask out irrelevant portions */
6227 integer &= hfinfo->bitmask;
6228
6229 /* Shift bits */
6230 integer >>= hfinfo_bitshift(hfinfo);
6231
6232 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6233 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)
;
6234 }
6235
6236 fvalue_set_uinteger64(fi->value, integer);
6237}
6238
6239/* Add FT_INT{8,16,24,32} to a proto_tree */
6240proto_item *
6241proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6242 unsigned length, int32_t value)
6243{
6244 proto_item *pi = NULL((void*)0);
6245 header_field_info *hfinfo;
6246
6247 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6248
6249 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", 6249
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6249, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6249, "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", 6249, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6250
6251 switch (hfinfo->type) {
6252 case FT_INT8:
6253 case FT_INT16:
6254 case FT_INT24:
6255 case FT_INT32:
6256 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6257 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6258 break;
6259
6260 default:
6261 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)
6262 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6263 }
6264
6265 return pi;
6266}
6267
6268proto_item *
6269proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6270 unsigned start, unsigned length, int32_t value,
6271 const char *format, ...)
6272{
6273 proto_item *pi;
6274 va_list ap;
6275
6276 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6277 if (pi != tree) {
6278 va_start(ap, format)__builtin_va_start(ap, format);
6279 proto_tree_set_representation_value(pi, format, ap);
6280 va_end(ap)__builtin_va_end(ap);
6281 }
6282
6283 return pi;
6284}
6285
6286proto_item *
6287proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6288 unsigned start, unsigned length, int32_t value,
6289 const char *format, ...)
6290{
6291 proto_item *pi;
6292 va_list ap;
6293
6294 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6295 if (pi != tree) {
6296 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6296, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6297
6298 va_start(ap, format)__builtin_va_start(ap, format);
6299 proto_tree_set_representation(pi, format, ap);
6300 va_end(ap)__builtin_va_end(ap);
6301 }
6302
6303 return pi;
6304}
6305
6306/* Set the FT_INT{8,16,24,32} value */
6307static void
6308proto_tree_set_int(field_info *fi, int32_t value)
6309{
6310 const header_field_info *hfinfo;
6311 uint32_t integer;
6312 int no_of_bits;
6313
6314 hfinfo = fi->hfinfo;
6315 integer = (uint32_t) value;
6316
6317 if (hfinfo->bitmask) {
6318 /* Mask out irrelevant portions */
6319 integer &= (uint32_t)(hfinfo->bitmask);
6320
6321 /* Shift bits */
6322 integer >>= hfinfo_bitshift(hfinfo);
6323
6324 no_of_bits = ws_count_ones(hfinfo->bitmask);
6325 integer = ws_sign_ext32(integer, no_of_bits);
6326
6327 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6328 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)
;
6329 }
6330
6331 fvalue_set_sinteger(fi->value, integer);
6332}
6333
6334/* Add FT_INT{40,48,56,64} to a proto_tree */
6335proto_item *
6336proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6337 unsigned length, int64_t value)
6338{
6339 proto_item *pi = NULL((void*)0);
6340 header_field_info *hfinfo;
6341
6342 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6343
6344 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", 6344
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6344, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6344, "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", 6344, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6345
6346 switch (hfinfo->type) {
6347 case FT_INT40:
6348 case FT_INT48:
6349 case FT_INT56:
6350 case FT_INT64:
6351 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6352 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6353 break;
6354
6355 default:
6356 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)
6357 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6358 }
6359
6360 return pi;
6361}
6362
6363proto_item *
6364proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6365 unsigned start, unsigned length, int64_t value,
6366 const char *format, ...)
6367{
6368 proto_item *pi;
6369 va_list ap;
6370
6371 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6372 if (pi != tree) {
6373 va_start(ap, format)__builtin_va_start(ap, format);
6374 proto_tree_set_representation_value(pi, format, ap);
6375 va_end(ap)__builtin_va_end(ap);
6376 }
6377
6378 return pi;
6379}
6380
6381/* Set the FT_INT{40,48,56,64} value */
6382static void
6383proto_tree_set_int64(field_info *fi, int64_t value)
6384{
6385 const header_field_info *hfinfo;
6386 uint64_t integer;
6387 int no_of_bits;
6388
6389 hfinfo = fi->hfinfo;
6390 integer = value;
6391
6392 if (hfinfo->bitmask) {
6393 /* Mask out irrelevant portions */
6394 integer &= hfinfo->bitmask;
6395
6396 /* Shift bits */
6397 integer >>= hfinfo_bitshift(hfinfo);
6398
6399 no_of_bits = ws_count_ones(hfinfo->bitmask);
6400 integer = ws_sign_ext64(integer, no_of_bits);
6401
6402 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6403 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)
;
6404 }
6405
6406 fvalue_set_sinteger64(fi->value, integer);
6407}
6408
6409proto_item *
6410proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6411 unsigned start, unsigned length, int64_t value,
6412 const char *format, ...)
6413{
6414 proto_item *pi;
6415 va_list ap;
6416
6417 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6418 if (pi != tree) {
6419 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6419, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6420
6421 va_start(ap, format)__builtin_va_start(ap, format);
6422 proto_tree_set_representation(pi, format, ap);
6423 va_end(ap)__builtin_va_end(ap);
6424 }
6425
6426 return pi;
6427}
6428
6429/* Add a FT_EUI64 to a proto_tree */
6430proto_item *
6431proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6432 unsigned length, const uint64_t value)
6433{
6434 proto_item *pi;
6435 header_field_info *hfinfo;
6436
6437 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6438
6439 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", 6439
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6439, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6439, "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", 6439, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6440
6441 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",
6441, ((hfinfo))->abbrev))))
;
6442
6443 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6444 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6445
6446 return pi;
6447}
6448
6449proto_item *
6450proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6451 unsigned start, unsigned length, const uint64_t value,
6452 const char *format, ...)
6453{
6454 proto_item *pi;
6455 va_list ap;
6456
6457 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6458 if (pi != tree) {
6459 va_start(ap, format)__builtin_va_start(ap, format);
6460 proto_tree_set_representation_value(pi, format, ap);
6461 va_end(ap)__builtin_va_end(ap);
6462 }
6463
6464 return pi;
6465}
6466
6467proto_item *
6468proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6469 unsigned start, unsigned length, const uint64_t value,
6470 const char *format, ...)
6471{
6472 proto_item *pi;
6473 va_list ap;
6474
6475 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6476 if (pi != tree) {
6477 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6477, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6478
6479 va_start(ap, format)__builtin_va_start(ap, format);
6480 proto_tree_set_representation(pi, format, ap);
6481 va_end(ap)__builtin_va_end(ap);
6482 }
6483
6484 return pi;
6485}
6486
6487/* Set the FT_EUI64 value */
6488static void
6489proto_tree_set_eui64(field_info *fi, const uint64_t value)
6490{
6491 uint8_t v[FT_EUI64_LEN8];
6492 phtonu64(v, value);
6493 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6494}
6495
6496static void
6497proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6498{
6499 if (encoding)
6500 {
6501 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6502 } else {
6503 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6504 }
6505}
6506
6507proto_item *
6508proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6509 const mac_hf_list_t *list_generic,
6510 int idx, tvbuff_t *tvb,
6511 proto_tree *tree, unsigned offset)
6512{
6513 uint8_t addr[6];
6514 const char *addr_name = NULL((void*)0);
6515 const char *oui_name = NULL((void*)0);
6516 proto_item *addr_item = NULL((void*)0);
6517 proto_tree *addr_tree = NULL((void*)0);
6518 proto_item *ret_val = NULL((void*)0);
6519
6520 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6521 return NULL((void*)0);
6522 }
6523
6524 /* Resolve what we can of the address */
6525 tvb_memcpy(tvb, addr, offset, sizeof addr);
6526 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6527 addr_name = get_ether_name(addr);
6528 }
6529 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6530 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6531 }
6532
6533 /* Add the item for the specific address type */
6534 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6535 if (idx >= 0) {
6536 addr_tree = proto_item_add_subtree(ret_val, idx);
6537 }
6538 else {
6539 addr_tree = tree;
6540 }
6541
6542 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6543 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6544 tvb, offset, 6, addr_name);
6545 proto_item_set_generated(addr_item);
6546 proto_item_set_hidden(addr_item);
6547 }
6548
6549 if (list_specific->hf_oui != NULL((void*)0)) {
6550 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6551 proto_item_set_generated(addr_item);
6552 proto_item_set_hidden(addr_item);
6553
6554 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6555 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6556 proto_item_set_generated(addr_item);
6557 proto_item_set_hidden(addr_item);
6558 }
6559 }
6560
6561 if (list_specific->hf_lg != NULL((void*)0)) {
6562 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6563 }
6564 if (list_specific->hf_ig != NULL((void*)0)) {
6565 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6566 }
6567
6568 /* Were we given a list for generic address fields? If not, stop here */
6569 if (list_generic == NULL((void*)0)) {
6570 return ret_val;
6571 }
6572
6573 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6574 proto_item_set_hidden(addr_item);
6575
6576 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6577 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6578 tvb, offset, 6, addr_name);
6579 proto_item_set_generated(addr_item);
6580 proto_item_set_hidden(addr_item);
6581 }
6582
6583 if (list_generic->hf_oui != NULL((void*)0)) {
6584 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6585 proto_item_set_generated(addr_item);
6586 proto_item_set_hidden(addr_item);
6587
6588 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6589 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6590 proto_item_set_generated(addr_item);
6591 proto_item_set_hidden(addr_item);
6592 }
6593 }
6594
6595 if (list_generic->hf_lg != NULL((void*)0)) {
6596 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6597 proto_item_set_hidden(addr_item);
6598 }
6599 if (list_generic->hf_ig != NULL((void*)0)) {
6600 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6601 proto_item_set_hidden(addr_item);
6602 }
6603 return ret_val;
6604}
6605
6606static proto_item *
6607proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6608{
6609 proto_node *pnode, *tnode, *sibling;
6610 field_info *tfi;
6611 unsigned depth = 1;
6612
6613 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6613, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6614
6615 /*
6616 * Restrict our depth. proto_tree_traverse_pre_order and
6617 * proto_tree_traverse_post_order (and possibly others) are recursive
6618 * so we need to be mindful of our stack size.
6619 */
6620 if (tree->first_child == NULL((void*)0)) {
6621 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6622 depth++;
6623 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6624 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__)), 6627)))
6625 "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__)), 6627)))
6626 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__)), 6627)))
6627 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__)), 6627)))
;
6628 }
6629 }
6630 }
6631
6632 /*
6633 * Make sure "tree" is ready to have subtrees under it, by
6634 * checking whether it's been given an ett_ value.
6635 *
6636 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6637 * node of the protocol tree. That node is not displayed,
6638 * so it doesn't need an ett_ value to remember whether it
6639 * was expanded.
6640 */
6641 tnode = tree;
6642 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6643 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6644 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"
, 6645)
6645 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"
, 6645)
;
6646 /* XXX - is it safe to continue here? */
6647 }
6648
6649 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6650 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6651 pnode->parent = tnode;
6652 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6653 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6654 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6655
6656 if (tnode->last_child != NULL((void*)0)) {
6657 sibling = tnode->last_child;
6658 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6658, "sibling->next == ((void*)0)"
))))
;
6659 sibling->next = pnode;
6660 } else
6661 tnode->first_child = pnode;
6662 tnode->last_child = pnode;
6663
6664 /* We should not be adding a fake node for an interesting field */
6665 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", 6665, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6666
6667 /* XXX - Should the proto_item have a header_field_info member, at least
6668 * for faked items, to know what hfi was faked? (Some dissectors look at
6669 * the tree items directly.)
6670 */
6671 return (proto_item *)pnode;
6672}
6673
6674/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6675static proto_item *
6676proto_tree_add_node(proto_tree *tree, field_info *fi)
6677{
6678 proto_node *pnode, *tnode, *sibling;
6679 field_info *tfi;
6680 unsigned depth = 1;
6681
6682 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6682, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6683
6684 /*
6685 * Restrict our depth. proto_tree_traverse_pre_order and
6686 * proto_tree_traverse_post_order (and possibly others) are recursive
6687 * so we need to be mindful of our stack size.
6688 */
6689 if (tree->first_child == NULL((void*)0)) {
6690 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6691 depth++;
6692 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6693 /* The fvalue_t is pool-allocated; just release the
6694 * type-specific data it owns (see new_field_info()). */
6695 fvalue_cleanup(fi->value);
6696 fi->value = NULL((void*)0);
6697 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__)), 6700)))
6698 "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__)), 6700)))
6699 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__)), 6700)))
6700 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__)), 6700)))
;
6701 }
6702 }
6703 }
6704
6705 /*
6706 * Make sure "tree" is ready to have subtrees under it, by
6707 * checking whether it's been given an ett_ value.
6708 *
6709 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6710 * node of the protocol tree. That node is not displayed,
6711 * so it doesn't need an ett_ value to remember whether it
6712 * was expanded.
6713 */
6714 tnode = tree;
6715 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6716 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6717 /* Since we are not adding fi to a node, its fvalue won't get
6718 * cleaned up by proto_tree_free_node(), so release the
6719 * type-specific data it owns now. The fvalue_t structure itself
6720 * is pool-allocated (see new_field_info()).
6721 */
6722 fvalue_cleanup(fi->value);
6723 fi->value = NULL((void*)0);
6724 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", 6725)
6725 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", 6725)
;
6726 /* XXX - is it safe to continue here? */
6727 }
6728
6729 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6730 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6731 pnode->parent = tnode;
6732 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6733 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6734 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6735
6736 if (tnode->last_child != NULL((void*)0)) {
6737 sibling = tnode->last_child;
6738 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6738, "sibling->next == ((void*)0)"
))))
;
6739 sibling->next = pnode;
6740 } else
6741 tnode->first_child = pnode;
6742 tnode->last_child = pnode;
6743
6744 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6745
6746 return (proto_item *)pnode;
6747}
6748
6749
6750/* Generic way to allocate field_info and add to proto_tree.
6751 * Sets *pfi to address of newly-allocated field_info struct */
6752static proto_item *
6753proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6754 int *length)
6755{
6756 proto_item *pi;
6757 field_info *fi;
6758 int item_length;
6759
6760 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6761 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6762 pi = proto_tree_add_node(tree, fi);
6763
6764 return pi;
6765}
6766
6767/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6768 * Eventually this should replace the other function.
6769 * Sets *pfi to address of newly-allocated field_info struct */
6770static proto_item *
6771proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6772 unsigned *length)
6773{
6774 proto_item *pi;
6775 field_info *fi;
6776 unsigned item_length;
6777
6778 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6779 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6780 pi = proto_tree_add_node(tree, fi);
6781
6782 return pi;
6783}
6784
6785static void
6786get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6787 int *item_length, const unsigned encoding)
6788{
6789 int length_remaining;
6790
6791 /*
6792 * We only allow a null tvbuff if the item has a zero length,
6793 * i.e. if there's no data backing it.
6794 */
6795 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", 6795, "tvb != ((void*)0) || *length == 0"
))))
;
6796
6797 /*
6798 * XXX - in some protocols, there are 32-bit unsigned length
6799 * fields, so lengths in protocol tree and tvbuff routines
6800 * should really be unsigned. We should have, for those
6801 * field types for which "to the end of the tvbuff" makes sense,
6802 * additional routines that take no length argument and
6803 * add fields that run to the end of the tvbuff.
6804 */
6805 if (*length == -1) {
6806 /*
6807 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6808 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6809 * of -1 means "set the length to what remains in the
6810 * tvbuff".
6811 *
6812 * The assumption is either that
6813 *
6814 * 1) the length of the item can only be determined
6815 * by dissection (typically true of items with
6816 * subitems, which are probably FT_NONE or
6817 * FT_PROTOCOL)
6818 *
6819 * or
6820 *
6821 * 2) if the tvbuff is "short" (either due to a short
6822 * snapshot length or due to lack of reassembly of
6823 * fragments/segments/whatever), we want to display
6824 * what's available in the field (probably FT_BYTES
6825 * or FT_STRING) and then throw an exception later
6826 *
6827 * or
6828 *
6829 * 3) the field is defined to be "what's left in the
6830 * packet"
6831 *
6832 * so we set the length to what remains in the tvbuff so
6833 * that, if we throw an exception while dissecting, it
6834 * has what is probably the right value.
6835 *
6836 * For FT_STRINGZ, it means "the string is null-terminated,
6837 * not null-padded; set the length to the actual length
6838 * of the string", and if the tvbuff if short, we just
6839 * throw an exception.
6840 *
6841 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6842 * it means "find the end of the string",
6843 * and if the tvbuff if short, we just throw an exception.
6844 *
6845 * It's not valid for any other type of field. For those
6846 * fields, we treat -1 the same way we treat other
6847 * negative values - we assume the length is a Really
6848 * Big Positive Number, and throw a ReportedBoundsError
6849 * exception, under the assumption that the Really Big
6850 * Length would run past the end of the packet.
6851 */
6852 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
))
)) {
6853 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6854 /*
6855 * Leave the length as -1, so our caller knows
6856 * it was -1.
6857 */
6858 *item_length = *length;
6859 return;
6860 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6861 switch (tvb_get_uint8(tvb, start) >> 6)
6862 {
6863 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6864 *item_length = 1;
6865 break;
6866 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6867 *item_length = 2;
6868 break;
6869 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6870 *item_length = 4;
6871 break;
6872 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6873 *item_length = 8;
6874 break;
6875 }
6876 }
6877 }
6878
6879 switch (hfinfo->type) {
6880
6881 case FT_PROTOCOL:
6882 case FT_NONE:
6883 case FT_BYTES:
6884 case FT_STRING:
6885 case FT_STRINGZPAD:
6886 case FT_STRINGZTRUNC:
6887 /*
6888 * We allow FT_PROTOCOLs to be zero-length -
6889 * for example, an ONC RPC NULL procedure has
6890 * neither arguments nor reply, so the
6891 * payload for that protocol is empty.
6892 *
6893 * We also allow the others to be zero-length -
6894 * because that's the way the code has been for a
6895 * long, long time.
6896 *
6897 * However, we want to ensure that the start
6898 * offset is not *past* the byte past the end
6899 * of the tvbuff: we throw an exception in that
6900 * case.
6901 */
6902 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6903 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6903, "*length >= 0"
))))
;
6904 break;
6905
6906 case FT_STRINGZ:
6907 /*
6908 * Leave the length as -1, so our caller knows
6909 * it was -1.
6910 */
6911 break;
6912
6913 default:
6914 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6915 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6915))
;
6916 }
6917 *item_length = *length;
6918 } else {
6919 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6920 /*
6921 * These types are for interior nodes of the
6922 * tree, and don't have data associated with
6923 * them; if the length is negative (XXX - see
6924 * above) or goes past the end of the tvbuff,
6925 * cut it short at the end of the tvbuff.
6926 * That way, if this field is selected in
6927 * Wireshark, we don't highlight stuff past
6928 * the end of the data.
6929 *
6930 * If we don't have a tvb, then length must be zero,
6931 * per the DISSECTOR_ASSERT() above.
6932 *
6933 * If we do have a tvb, and the length requested is
6934 * nonzero, we want to ensure that the start offset
6935 * is not *past* the byte past the end of the tvbuff
6936 * data: we throw an exception in that case as above.
6937 */
6938 if (tvb && *length) {
6939 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6940 if (*length < 0 ||
6941 (*length > 0 &&
6942 (length_remaining < *length)))
6943 *length = length_remaining;
6944 }
6945 }
6946 *item_length = *length;
6947 if (*item_length < 0) {
6948 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6949 }
6950 }
6951}
6952
6953static void
6954get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6955 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6956{
6957 unsigned length_remaining;
6958
6959 /*
6960 * We only allow a null tvbuff if the item has a zero length,
6961 * i.e. if there's no data backing it.
6962 */
6963 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", 6963, "tvb != ((void*)0) || *length == 0"
))))
;
6964
6965
6966 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6967 /*
6968 * These types are for interior nodes of the
6969 * tree, and don't have data associated with
6970 * them; if the length is negative (XXX - see
6971 * above) or goes past the end of the tvbuff,
6972 * cut it short at the end of the tvbuff.
6973 * That way, if this field is selected in
6974 * Wireshark, we don't highlight stuff past
6975 * the end of the data.
6976 *
6977 * If we don't have a tvb, then length must be zero,
6978 * per the DISSECTOR_ASSERT() above.
6979 *
6980 * If we do have a tvb, and the length requested is
6981 * nonzero, we want to ensure that the start offset
6982 * is not *past* the byte past the end of the tvbuff
6983 * data: we throw an exception in that case as above.
6984 * (If the length requested is zero, then it's quite
6985 * likely that the start offset is the byte past the
6986 * end, but that's ok.)
6987 */
6988 if (tvb && *length) {
6989 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6990 if (length_remaining < *length) {
6991 *length = length_remaining;
6992 }
6993 }
6994 }
6995 *item_length = *length;
6996}
6997
6998static int
6999get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
7000 int length, unsigned item_length, const int encoding)
7001{
7002 uint32_t n;
7003
7004 /*
7005 * We need to get the correct item length here.
7006 * That's normally done by proto_tree_new_item(),
7007 * but we won't be calling it.
7008 */
7009 switch (hfinfo->type) {
7010
7011 case FT_NONE:
7012 case FT_PROTOCOL:
7013 case FT_BYTES:
7014 /*
7015 * The length is the specified length.
7016 */
7017 break;
7018
7019 case FT_UINT_BYTES:
7020 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
7021 item_length += n;
7022 if ((int)item_length < length) {
7023 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7024 }
7025 break;
7026
7027 /* XXX - make these just FT_UINT? */
7028 case FT_UINT8:
7029 case FT_UINT16:
7030 case FT_UINT24:
7031 case FT_UINT32:
7032 case FT_UINT40:
7033 case FT_UINT48:
7034 case FT_UINT56:
7035 case FT_UINT64:
7036 /* XXX - make these just FT_INT? */
7037 case FT_INT8:
7038 case FT_INT16:
7039 case FT_INT24:
7040 case FT_INT32:
7041 case FT_INT40:
7042 case FT_INT48:
7043 case FT_INT56:
7044 case FT_INT64:
7045 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
7046 if (length < -1) {
7047 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
7048 }
7049 if (length == -1) {
7050 uint64_t dummy;
7051 /* This can throw an exception */
7052 /* XXX - do this without fetching the varint? */
7053 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
7054 if (length == 0) {
7055 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7056 }
7057 }
7058 item_length = length;
7059 break;
7060 }
7061
7062 /*
7063 * The length is the specified length.
7064 */
7065 break;
7066
7067 case FT_BOOLEAN:
7068 case FT_CHAR:
7069 case FT_IPv4:
7070 case FT_IPXNET:
7071 case FT_IPv6:
7072 case FT_FCWWN:
7073 case FT_AX25:
7074 case FT_VINES:
7075 case FT_ETHER:
7076 case FT_EUI64:
7077 case FT_GUID:
7078 case FT_OID:
7079 case FT_REL_OID:
7080 case FT_SYSTEM_ID:
7081 case FT_FLOAT:
7082 case FT_DOUBLE:
7083 case FT_STRING:
7084 /*
7085 * The length is the specified length.
7086 */
7087 break;
7088
7089 case FT_STRINGZ:
7090 if (length < -1) {
7091 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7092 }
7093 if (length == -1) {
7094 /* This can throw an exception */
7095 item_length = tvb_strsize_enc(tvb, start, encoding);
7096 }
7097 break;
7098
7099 case FT_UINT_STRING:
7100 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7101 item_length += n;
7102 if ((int)item_length < length) {
7103 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7104 }
7105 break;
7106
7107 case FT_STRINGZPAD:
7108 case FT_STRINGZTRUNC:
7109 case FT_ABSOLUTE_TIME:
7110 case FT_RELATIVE_TIME:
7111 case FT_IEEE_11073_SFLOAT:
7112 case FT_IEEE_11073_FLOAT:
7113 /*
7114 * The length is the specified length.
7115 */
7116 break;
7117
7118 default:
7119 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
))
7120 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
))
7121 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
))
7122 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
))
;
7123 break;
7124 }
7125 return item_length;
7126}
7127
7128// This was arbitrarily chosen, but if you're adding 50K items to the tree
7129// without advancing the offset you should probably take a long, hard look
7130// at what you're doing.
7131// We *could* make this a configurable option, but I (Gerald) would like to
7132// avoid adding yet another nerd knob.
7133# define PROTO_TREE_MAX_IDLE50000 50000
7134static field_info *
7135new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7136 const unsigned start, const int item_length)
7137{
7138 field_info *fi;
7139
7140 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7141
7142 fi->hfinfo = hfinfo;
7143 fi->start = start;
7144 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7145 /* add the data source tvbuff */
7146 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7147
7148 // If our start offset hasn't advanced after adding many items it probably
7149 // means we're in a large or infinite loop.
7150 if (fi->start > 0) {
7151 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7152 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7153 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7154 if (wireshark_abort_on_too_many_items) {
7155 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", 7156
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7156 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7156
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7157 }
7158 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7159 * but if not, we should hit the max item error earlier,
7160 * so we shouldn't need to reset the tree count to
7161 * ensure that the exception handler can add the item. */
7162 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)))
7163 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)))
7164 "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)))
7165 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)))
;
7166 }
7167 } else {
7168 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7169 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7170 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7171 }
7172 }
7173 fi->length = item_length;
7174 fi->tree_type = -1;
7175 fi->flags = 0;
7176 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7177 /* If the tree is not visible, set the item hidden, unless we
7178 * need the representation or length and can't fake them.
7179 */
7180 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7181 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7182 }
7183 }
7184 fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7185 fi->rep = NULL((void*)0);
7186
7187 fi->appendix_start = 0;
7188 fi->appendix_length = 0;
7189
7190 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7191 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7192
7193 return fi;
7194}
7195
7196static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7197{
7198 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7199 return 0;
7200 }
7201
7202 /* Search for field name */
7203 char *ptr = strstr(representation, hfinfo->name);
7204 if (!ptr) {
7205 return 0;
7206 }
7207
7208 /* Check if field name ends with the ": " delimiter */
7209 ptr += strlen(hfinfo->name);
7210 if (strncmp(ptr, ": ", 2) == 0) {
7211 ptr += 2;
7212 }
7213
7214 /* Return offset to after field name */
7215 return ptr - representation;
7216}
7217
7218static size_t label_find_name_pos(const item_label_t *rep)
7219{
7220 size_t name_pos = 0;
7221
7222 /* If the value_pos is too small or too large, we can't find the expected format */
7223 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7224 return 0;
7225 }
7226
7227 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7228 if (rep->representation[rep->value_pos-2] == ':') {
7229 name_pos = rep->value_pos - 2;
7230 }
7231
7232 return name_pos;
7233}
7234
7235/* If the protocol tree is to be visible, set the representation of a
7236 proto_tree entry with the name of the field for the item and with
7237 the value formatted with the supplied printf-style format and
7238 argument list. */
7239static void
7240proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7241{
7242 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7242, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7243
7244 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7245 * items string representation */
7246 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7247 size_t name_pos, ret = 0;
7248 char *str;
7249 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7250 const header_field_info *hf;
7251
7252 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7252, "fi"))))
;
7253
7254 hf = fi->hfinfo;
7255
7256 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;
;
7257 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))
)) {
7258 uint64_t val;
7259 char *p;
7260
7261 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)
)
7262 val = fvalue_get_uinteger(fi->value);
7263 else
7264 val = fvalue_get_uinteger64(fi->value);
7265
7266 val <<= hfinfo_bitshift(hf);
7267
7268 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7269 ret = (p - fi->rep->representation);
7270 }
7271
7272 /* put in the hf name */
7273 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)
;
7274
7275 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7276 /* If possible, Put in the value of the string */
7277 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7278 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"
, 7278, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7279 fi->rep->value_pos = ret;
7280 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7281 if (ret >= ITEM_LABEL_LENGTH240) {
7282 /* Uh oh, we don't have enough room. Tell the user
7283 * that the field is truncated.
7284 */
7285 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7286 }
7287 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7288 }
7289}
7290
7291/* If the protocol tree is to be visible, set the representation of a
7292 proto_tree entry with the representation formatted with the supplied
7293 printf-style format and argument list. */
7294static void
7295proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7296{
7297 size_t ret; /*tmp return value */
7298 char *str;
7299 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7300
7301 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7301, "fi"))))
;
7302
7303 if (!proto_item_is_hidden(pi)) {
7304 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;
;
7305
7306 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7307 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"
, 7307, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7308 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7309 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7310 if (ret >= ITEM_LABEL_LENGTH240) {
7311 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7312 size_t name_pos = label_find_name_pos(fi->rep);
7313 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7314 }
7315 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7316 }
7317}
7318
7319static int
7320proto_strlcpy(char *dest, const char *src, size_t dest_size)
7321{
7322 if (dest_size == 0) return 0;
7323
7324 size_t res = g_strlcpy(dest, src, dest_size);
7325
7326 /* At most dest_size - 1 characters will be copied
7327 * (unless dest_size is 0). */
7328 if (res >= dest_size)
7329 res = dest_size - 1;
7330 return (int) res;
7331}
7332
7333static header_field_info *
7334hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7335{
7336 header_field_info *dup_hfinfo;
7337
7338 if (hfinfo->same_name_prev_id == -1)
7339 return NULL((void*)0);
7340 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", 7340
, __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", 7340, "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", 7340,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf.")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7341 return dup_hfinfo;
7342}
7343
7344static void
7345hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7346{
7347 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)
;
7348 last_field_name = NULL((void*)0);
7349
7350 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7351 /* No hfinfo with the same name */
7352 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7353 return;
7354 }
7355
7356 if (hfinfo->same_name_next) {
7357 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7358 }
7359
7360 if (hfinfo->same_name_prev_id != -1) {
7361 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7362 same_name_prev->same_name_next = hfinfo->same_name_next;
7363 if (!hfinfo->same_name_next) {
7364 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7365 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7366 }
7367 }
7368}
7369
7370int
7371proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7372{
7373 const header_field_info *hfinfo = finfo->hfinfo;
7374 int label_len = 0;
7375 char *tmp_str;
7376 const char *str;
7377 const uint8_t *bytes;
7378 uint32_t number;
7379 uint64_t number64;
7380 const char *hf_str_val;
7381 char number_buf[NUMBER_LABEL_LENGTH80];
7382 const char *number_out;
7383 address addr;
7384 const ipv4_addr_and_mask *ipv4;
7385 const ipv6_addr_and_prefix *ipv6;
7386
7387 switch (hfinfo->type) {
7388
7389 case FT_NONE:
7390 case FT_PROTOCOL:
7391 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7392
7393 case FT_UINT_BYTES:
7394 case FT_BYTES:
7395 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7396 hfinfo,
7397 fvalue_get_bytes_data(finfo->value),
7398 (unsigned)fvalue_length2(finfo->value),
7399 label_str_size);
7400 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7401 wmem_free(NULL((void*)0), tmp_str);
7402 break;
7403
7404 case FT_ABSOLUTE_TIME:
7405 {
7406 const nstime_t *value = fvalue_get_time(finfo->value);
7407 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7408 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7409 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7410 }
7411 if (hfinfo->strings) {
7412 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7413 if (time_string != NULL((void*)0)) {
7414 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7415 break;
7416 }
7417 }
7418 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7419 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7420 wmem_free(NULL((void*)0), tmp_str);
7421 break;
7422 }
7423
7424 case FT_RELATIVE_TIME:
7425 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7426 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7427 wmem_free(NULL((void*)0), tmp_str);
7428 break;
7429
7430 case FT_BOOLEAN:
7431 number64 = fvalue_get_uinteger64(finfo->value);
7432 label_len = proto_strlcpy(display_label_str,
7433 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7434 break;
7435
7436 case FT_CHAR:
7437 number = fvalue_get_uinteger(finfo->value);
7438
7439 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7440 char tmp[ITEM_LABEL_LENGTH240];
7441 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7442
7443 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7443, "fmtfunc"))))
;
7444 fmtfunc(tmp, number);
7445
7446 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7447
7448 } else if (hfinfo->strings) {
7449 number_out = hf_try_val_to_str(number, hfinfo);
7450
7451 if (!number_out) {
7452 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7453 }
7454
7455 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7456
7457 } else {
7458 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7459
7460 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7461 }
7462
7463 break;
7464
7465 /* XXX - make these just FT_NUMBER? */
7466 case FT_INT8:
7467 case FT_INT16:
7468 case FT_INT24:
7469 case FT_INT32:
7470 case FT_UINT8:
7471 case FT_UINT16:
7472 case FT_UINT24:
7473 case FT_UINT32:
7474 case FT_FRAMENUM:
7475 hf_str_val = NULL((void*)0);
7476 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
))
?
7477 (uint32_t) fvalue_get_sinteger(finfo->value) :
7478 fvalue_get_uinteger(finfo->value);
7479
7480 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7481 char tmp[ITEM_LABEL_LENGTH240];
7482 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7483
7484 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7484, "fmtfunc"))))
;
7485 fmtfunc(tmp, number);
7486
7487 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7488
7489 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7490 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7491 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7492 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7493 hf_str_val = hf_try_val_to_str(number, hfinfo);
7494 if (hf_str_val)
7495 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7496 } else {
7497 number_out = hf_try_val_to_str(number, hfinfo);
7498
7499 if (!number_out) {
7500 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7501 }
7502
7503 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7504 }
7505 } else {
7506 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7507
7508 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7509 }
7510
7511 break;
7512
7513 case FT_INT40:
7514 case FT_INT48:
7515 case FT_INT56:
7516 case FT_INT64:
7517 case FT_UINT40:
7518 case FT_UINT48:
7519 case FT_UINT56:
7520 case FT_UINT64:
7521 hf_str_val = NULL((void*)0);
7522 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
))
?
7523 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7524 fvalue_get_uinteger64(finfo->value);
7525
7526 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7527 char tmp[ITEM_LABEL_LENGTH240];
7528 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7529
7530 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7530, "fmtfunc64"
))))
;
7531 fmtfunc64(tmp, number64);
7532
7533 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7534 } else if (hfinfo->strings) {
7535 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7536 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7537 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7538 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7539 if (hf_str_val)
7540 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7541 } else {
7542 number_out = hf_try_val64_to_str(number64, hfinfo);
7543
7544 if (!number_out)
7545 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7546
7547 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7548 }
7549 } else {
7550 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7551
7552 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7553 }
7554
7555 break;
7556
7557 case FT_EUI64:
7558 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7559 tmp_str = address_to_display(NULL((void*)0), &addr);
7560 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7561 wmem_free(NULL((void*)0), tmp_str);
7562 break;
7563
7564 case FT_IPv4:
7565 ipv4 = fvalue_get_ipv4(finfo->value);
7566 //XXX: Should we ignore the mask?
7567 set_address_ipv4(&addr, ipv4);
7568 tmp_str = address_to_display(NULL((void*)0), &addr);
7569 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7570 wmem_free(NULL((void*)0), tmp_str);
7571 free_address(&addr);
7572 break;
7573
7574 case FT_IPv6:
7575 ipv6 = fvalue_get_ipv6(finfo->value);
7576 set_address_ipv6(&addr, ipv6);
7577 tmp_str = address_to_display(NULL((void*)0), &addr);
7578 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7579 wmem_free(NULL((void*)0), tmp_str);
7580 free_address(&addr);
7581 break;
7582
7583 case FT_FCWWN:
7584 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7585 tmp_str = address_to_display(NULL((void*)0), &addr);
7586 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7587 wmem_free(NULL((void*)0), tmp_str);
7588 break;
7589
7590 case FT_ETHER:
7591 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7592 tmp_str = address_to_display(NULL((void*)0), &addr);
7593 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7594 wmem_free(NULL((void*)0), tmp_str);
7595 break;
7596
7597 case FT_GUID:
7598 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7599 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7600 wmem_free(NULL((void*)0), tmp_str);
7601 break;
7602
7603 case FT_REL_OID:
7604 bytes = fvalue_get_bytes_data(finfo->value);
7605 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7606 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7607 wmem_free(NULL((void*)0), tmp_str);
7608 break;
7609
7610 case FT_OID:
7611 bytes = fvalue_get_bytes_data(finfo->value);
7612 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7613 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7614 wmem_free(NULL((void*)0), tmp_str);
7615 break;
7616
7617 case FT_SYSTEM_ID:
7618 bytes = fvalue_get_bytes_data(finfo->value);
7619 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7620 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7621 wmem_free(NULL((void*)0), tmp_str);
7622 break;
7623
7624 case FT_FLOAT:
7625 case FT_DOUBLE:
7626 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7627 break;
7628
7629 case FT_IEEE_11073_SFLOAT:
7630 case FT_IEEE_11073_FLOAT:
7631 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7632 break;
7633
7634 case FT_STRING:
7635 case FT_STRINGZ:
7636 case FT_UINT_STRING:
7637 case FT_STRINGZPAD:
7638 case FT_STRINGZTRUNC:
7639 str = fvalue_get_string(finfo->value);
7640 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7641 if (label_len >= label_str_size) {
7642 /* Truncation occurred. Get the real length
7643 * copied (not including '\0') */
7644 label_len = label_str_size ? label_str_size - 1 : 0;
7645 }
7646 break;
7647
7648 default:
7649 /* First try ftype string representation */
7650 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7651 if (!tmp_str) {
7652 /* Default to show as bytes */
7653 bytes = fvalue_get_bytes_data(finfo->value);
7654 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7655 }
7656 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7657 wmem_free(NULL((void*)0), tmp_str);
7658 break;
7659 }
7660 return label_len;
7661}
7662
7663const char *
7664proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7665 char *result, char *expr, const int size)
7666{
7667 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7668 GPtrArray *finfos;
7669 field_info *finfo = NULL((void*)0);
7670 header_field_info* hfinfo;
7671 const char *abbrev = NULL((void*)0);
7672
7673 char *str;
7674 col_custom_t *field_idx;
7675 int field_id;
7676 int ii = 0;
7677
7678 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7678, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7679 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7680 field_id = field_idx->field_id;
7681 if (field_id == 0) {
7682 GPtrArray *fvals = NULL((void*)0);
7683 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7684 if (fvals != NULL((void*)0)) {
7685
7686 // XXX - Handling occurrences is unusual when more
7687 // than one field is involved, e.g. there's four
7688 // results for tcp.port + tcp.port. We may really
7689 // want to apply it to the operands, not the output.
7690 // Note that occurrences are not quite the same as
7691 // the layer operator (should the grammar support
7692 // both?)
7693 /* Calculate single index or set outer boundaries */
7694 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7695 if (occurrence < 0) {
7696 i = occurrence + len;
7697 last = i;
7698 } else if (occurrence > 0) {
7699 i = occurrence - 1;
7700 last = i;
7701 } else {
7702 i = 0;
7703 last = len - 1;
7704 }
7705 if (i < 0 || i >= len) {
7706 g_ptr_array_unref(fvals);
7707 continue;
7708 }
7709 for (; i <= last; i++) {
7710 /* XXX - We could have a "resolved" result
7711 * for types where the value depends only
7712 * on the type, e.g. FT_IPv4, and not on
7713 * hfinfo->strings. Supporting the latter
7714 * requires knowing which hfinfo matched
7715 * if there are multiple with the same
7716 * abbreviation. In any case, we need to
7717 * know the expected return type of the
7718 * field expression.
7719 */
7720 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7721 if (offset_r && (offset_r < (size - 1)))
7722 result[offset_r++] = ',';
7723 if (offset_e && (offset_e < (size - 1)))
7724 expr[offset_e++] = ',';
7725 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7726 // col_{add,append,set}_* calls ws_label_strcpy
7727 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7728
7729 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7730 }
7731 g_ptr_array_unref(fvals);
7732 } else if (passed) {
7733 // XXX - Occurrence doesn't make sense for a test
7734 // output, it should be applied to the operands.
7735 if (offset_r && (offset_r < (size - 1)))
7736 result[offset_r++] = ',';
7737 if (offset_e && (offset_e < (size - 1)))
7738 expr[offset_e++] = ',';
7739 /* Prevent multiple check marks */
7740 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7741 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7742 } else {
7743 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7744 }
7745 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7746 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7747 } else {
7748 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7749 }
7750 }
7751 continue;
7752 }
7753 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", 7753
, __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", 7753,
"(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", 7753,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7754
7755 /* do we need to rewind ? */
7756 if (!hfinfo)
7757 return "";
7758
7759 if (occurrence < 0) {
7760 /* Search other direction */
7761 while (hfinfo->same_name_prev_id != -1) {
7762 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", 7762
, __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", 7762, "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", 7762,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7763 }
7764 }
7765
7766 prev_len = 0; /* Reset handled occurrences */
7767
7768 while (hfinfo) {
7769 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7770
7771 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7772 if (occurrence < 0) {
7773 hfinfo = hfinfo->same_name_next;
7774 } else {
7775 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7776 }
7777 continue;
7778 }
7779
7780 /* Are there enough occurrences of the field? */
7781 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7782 if (occurrence < 0) {
7783 hfinfo = hfinfo->same_name_next;
7784 } else {
7785 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7786 }
7787 prev_len += len;
7788 continue;
7789 }
7790
7791 /* Calculate single index or set outer boundaries */
7792 if (occurrence < 0) {
7793 i = occurrence + len + prev_len;
7794 last = i;
7795 } else if (occurrence > 0) {
7796 i = occurrence - 1 - prev_len;
7797 last = i;
7798 } else {
7799 i = 0;
7800 last = len - 1;
7801 }
7802
7803 prev_len += len; /* Count handled occurrences */
7804
7805 while (i <= last) {
7806 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7807
7808 if (offset_r && (offset_r < (size - 1)))
7809 result[offset_r++] = ',';
7810
7811 if (display_details) {
7812 char representation[ITEM_LABEL_LENGTH240];
7813 size_t offset = 0;
7814
7815 if (finfo->rep && finfo->rep->value_len) {
7816 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7817 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7818 } else {
7819 proto_item_fill_label(finfo, representation, &offset);
7820 }
7821 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7822 } else {
7823 switch (hfinfo->type) {
7824
7825 case FT_NONE:
7826 case FT_PROTOCOL:
7827 /* Prevent multiple check marks */
7828 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7829 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7830 } else {
7831 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7832 }
7833 break;
7834
7835 default:
7836 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7837 break;
7838 }
7839 }
7840
7841 if (offset_e && (offset_e < (size - 1)))
7842 expr[offset_e++] = ',';
7843
7844 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
))
)) {
7845 const char *hf_str_val;
7846 /* Integer types with BASE_NONE never get the numeric value. */
7847 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7848 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7849 } 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
)
) {
7850 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7851 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7852 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7853 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7854 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7855 }
7856 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7857 offset_e = (int)strlen(expr);
7858 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7859 /* Prevent multiple check marks */
7860 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7861 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7862 } else {
7863 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7864 }
7865 } else {
7866 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7867 // col_{add,append,set}_* calls ws_label_strcpy
7868 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7869 wmem_free(NULL((void*)0), str);
7870 }
7871 i++;
7872 }
7873
7874 /* XXX: Why is only the first abbreviation returned for a multifield
7875 * custom column? */
7876 if (!abbrev) {
7877 /* Store abbrev for return value */
7878 abbrev = hfinfo->abbrev;
7879 }
7880
7881 if (occurrence == 0) {
7882 /* Fetch next hfinfo with same name (abbrev) */
7883 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7884 } else {
7885 hfinfo = NULL((void*)0);
7886 }
7887 }
7888 }
7889
7890 if (offset_r >= (size - 1)) {
7891 mark_truncated(result, 0, size, NULL((void*)0));
7892 }
7893 if (offset_e >= (size - 1)) {
7894 mark_truncated(expr, 0, size, NULL((void*)0));
7895 }
7896 return abbrev ? abbrev : "";
7897}
7898
7899char *
7900proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7901{
7902 int len, prev_len, last, i;
7903 GPtrArray *finfos;
7904 field_info *finfo = NULL((void*)0);
7905 header_field_info* hfinfo;
7906
7907 char *filter = NULL((void*)0);
7908 GPtrArray *filter_array;
7909
7910 col_custom_t *col_custom;
7911 int field_id;
7912
7913 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7913, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7914 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7915 for (GSList *iter = field_ids; iter; iter = iter->next) {
7916 col_custom = (col_custom_t*)iter->data;
7917 field_id = col_custom->field_id;
7918 if (field_id == 0) {
7919 GPtrArray *fvals = NULL((void*)0);
7920 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7921 if (fvals != NULL((void*)0)) {
7922 // XXX - Handling occurrences is unusual when more
7923 // than one field is involved, e.g. there's four
7924 // results for tcp.port + tcp.port. We really
7925 // want to apply it to the operands, not the output.
7926 /* Calculate single index or set outer boundaries */
7927 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7928 if (occurrence < 0) {
7929 i = occurrence + len;
7930 last = i;
7931 } else if (occurrence > 0) {
7932 i = occurrence - 1;
7933 last = i;
7934 } else {
7935 i = 0;
7936 last = len - 1;
7937 }
7938 if (i < 0 || i >= len) {
7939 g_ptr_array_unref(fvals);
7940 continue;
7941 }
7942 for (; i <= last; i++) {
7943 /* XXX - Should multiple values for one
7944 * field use set membership to reduce
7945 * verbosity, here and below? */
7946 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7947 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7948 wmem_free(NULL((void*)0), str);
7949 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7950 g_ptr_array_add(filter_array, filter);
7951 }
7952 }
7953 g_ptr_array_unref(fvals);
7954 } else if (passed) {
7955 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7956 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7957 g_ptr_array_add(filter_array, filter);
7958 }
7959 } else {
7960 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7961 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7962 g_ptr_array_add(filter_array, filter);
7963 }
7964 }
7965 continue;
7966 }
7967
7968 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", 7968
, __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", 7968,
"(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", 7968,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7969
7970 /* do we need to rewind ? */
7971 if (!hfinfo)
7972 return NULL((void*)0);
7973
7974 if (occurrence < 0) {
7975 /* Search other direction */
7976 while (hfinfo->same_name_prev_id != -1) {
7977 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", 7977
, __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", 7977, "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", 7977,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7978 }
7979 }
7980
7981 prev_len = 0; /* Reset handled occurrences */
7982
7983 while (hfinfo) {
7984 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7985
7986 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7987 if (occurrence < 0) {
7988 hfinfo = hfinfo->same_name_next;
7989 } else {
7990 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7991 }
7992 continue;
7993 }
7994
7995 /* Are there enough occurrences of the field? */
7996 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7997 if (occurrence < 0) {
7998 hfinfo = hfinfo->same_name_next;
7999 } else {
8000 hfinfo = hfinfo_same_name_get_prev(hfinfo);
8001 }
8002 prev_len += len;
8003 continue;
8004 }
8005
8006 /* Calculate single index or set outer boundaries */
8007 if (occurrence < 0) {
8008 i = occurrence + len + prev_len;
8009 last = i;
8010 } else if (occurrence > 0) {
8011 i = occurrence - 1 - prev_len;
8012 last = i;
8013 } else {
8014 i = 0;
8015 last = len - 1;
8016 }
8017
8018 prev_len += len; /* Count handled occurrences */
8019
8020 while (i <= last) {
8021 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
8022
8023 filter = proto_construct_match_selected_string(finfo, edt);
8024 if (filter) {
8025 /* Only add the same expression once (especially for FT_PROTOCOL).
8026 * The ptr array doesn't have NULL entries so g_str_equal is fine.
8027 */
8028 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
8029 g_ptr_array_add(filter_array, filter);
8030 }
8031 }
8032 i++;
8033 }
8034
8035 if (occurrence == 0) {
8036 /* Fetch next hfinfo with same name (abbrev) */
8037 hfinfo = hfinfo_same_name_get_prev(hfinfo);
8038 } else {
8039 hfinfo = NULL((void*)0);
8040 }
8041 }
8042 }
8043
8044 g_ptr_array_add(filter_array, NULL((void*)0));
8045
8046 /* XXX: Should this be || or && ? */
8047 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
8048
8049 g_ptr_array_free(filter_array, true1);
8050
8051 return output;
8052}
8053
8054/* Set text of proto_item after having already been created. */
8055void
8056proto_item_set_text(proto_item *pi, const char *format, ...)
8057{
8058 field_info *fi = NULL((void*)0);
8059 va_list ap;
8060
8061 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8062
8063 fi = PITEM_FINFO(pi)((pi)->finfo);
8064 if (fi == NULL((void*)0))
8065 return;
8066
8067 if (fi->rep) {
8068 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
8069 fi->rep = NULL((void*)0);
8070 }
8071
8072 va_start(ap, format)__builtin_va_start(ap, format);
8073 proto_tree_set_representation(pi, format, ap);
8074 va_end(ap)__builtin_va_end(ap);
8075}
8076
8077/* Append to text of proto_item after having already been created. */
8078void
8079proto_item_append_text(proto_item *pi, const char *format, ...)
8080{
8081 field_info *fi = NULL((void*)0);
8082 size_t curlen;
8083 char *str;
8084 va_list ap;
8085
8086 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8087
8088 fi = PITEM_FINFO(pi)((pi)->finfo);
8089 if (fi == NULL((void*)0)) {
8090 return;
8091 }
8092
8093 if (!proto_item_is_hidden(pi)) {
8094 /*
8095 * If we don't already have a representation,
8096 * generate the default representation.
8097 */
8098 if (fi->rep == NULL((void*)0)) {
8099 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;
;
8100 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8101 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8102 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8103 (strncmp(format, ": ", 2) == 0)) {
8104 fi->rep->value_pos += 2;
8105 }
8106 }
8107 if (fi->rep) {
8108 curlen = strlen(fi->rep->representation);
8109 /* curlen doesn't include the \0 byte.
8110 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8111 * the representation has already been truncated (of an up
8112 * to 4 byte UTF-8 character) or is just at the maximum length
8113 * unless we search for " [truncated]" (which may not be
8114 * at the start.)
8115 * It's safer to do nothing.
8116 */
8117 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8118 va_start(ap, format)__builtin_va_start(ap, format);
8119 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8120 va_end(ap)__builtin_va_end(ap);
8121 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"
, 8121, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8122 /* Keep fi->rep->value_pos */
8123 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8124 if (curlen >= ITEM_LABEL_LENGTH240) {
8125 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8126 size_t name_pos = label_find_name_pos(fi->rep);
8127 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8128 }
8129 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8130 }
8131 }
8132 }
8133}
8134
8135/* Prepend to text of proto_item after having already been created. */
8136void
8137proto_item_prepend_text(proto_item *pi, const char *format, ...)
8138{
8139 field_info *fi = NULL((void*)0);
8140 size_t pos;
8141 char representation[ITEM_LABEL_LENGTH240];
8142 char *str;
8143 va_list ap;
8144
8145 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8146
8147 fi = PITEM_FINFO(pi)((pi)->finfo);
8148 if (fi == NULL((void*)0)) {
8149 return;
8150 }
8151
8152 if (!proto_item_is_hidden(pi)) {
8153 /*
8154 * If we don't already have a representation,
8155 * generate the default representation.
8156 */
8157 if (fi->rep == NULL((void*)0)) {
8158 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;
;
8159 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8160 } else
8161 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8162
8163 va_start(ap, format)__builtin_va_start(ap, format);
8164 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8165 va_end(ap)__builtin_va_end(ap);
8166 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"
, 8166, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8167 fi->rep->value_pos += strlen(str);
8168 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8169 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8170 /* XXX: As above, if the old representation is close to the label
8171 * length, it might already be marked as truncated. */
8172 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8173 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8174 size_t name_pos = label_find_name_pos(fi->rep);
8175 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8176 }
8177 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8178 }
8179}
8180
8181static void
8182finfo_set_len(field_info *fi, const unsigned length)
8183{
8184 unsigned length_remaining;
8185
8186 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8187 if (length > length_remaining)
8188 fi->length = length_remaining;
8189 else
8190 fi->length = length;
8191
8192 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8193 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8194 fvalue_set_protocol_length(fi->value, fi->length);
8195 }
8196
8197 /*
8198 * You cannot just make the "len" field of a GByteArray
8199 * larger, if there's no data to back that length;
8200 * you can only make it smaller.
8201 */
8202 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8203 GBytes *bytes = fvalue_get_bytes(fi->value);
8204 size_t size;
8205 const void *data = g_bytes_get_data(bytes, &size);
8206 if ((size_t)fi->length <= size) {
8207 fvalue_set_bytes_data(fi->value, data, fi->length);
8208 }
8209 g_bytes_unref(bytes);
8210 }
8211}
8212
8213void
8214proto_item_set_len(proto_item *pi, const unsigned length)
8215{
8216 field_info *fi;
8217
8218 if (pi == NULL((void*)0))
8219 return;
8220
8221 fi = PITEM_FINFO(pi)((pi)->finfo);
8222 if (fi == NULL((void*)0))
8223 return;
8224
8225 finfo_set_len(fi, length);
8226}
8227
8228/*
8229 * Sets the length of the item based on its start and on the specified
8230 * offset, which is the offset past the end of the item; as the start
8231 * in the item is relative to the beginning of the data source tvbuff,
8232 * we need to pass in a tvbuff - the end offset is relative to the beginning
8233 * of that tvbuff.
8234 */
8235void
8236proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8237{
8238 field_info *fi;
8239 unsigned length;
8240
8241 if (pi == NULL((void*)0))
8242 return;
8243
8244 fi = PITEM_FINFO(pi)((pi)->finfo);
8245 if (fi == NULL((void*)0))
8246 return;
8247
8248 if (G_LIKELY(tvb)(tvb)) {
8249 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"
, 8249, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8250 end += tvb_raw_offset(tvb);
8251 } else {
8252 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", 8252, "((void*)0) == fi->ds_tvb"
))))
;
8253 }
8254 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8254, "end >= fi->start"
))))
;
8255 length = end - fi->start;
8256
8257 finfo_set_len(fi, length);
8258}
8259
8260unsigned
8261proto_item_get_len(const proto_item *pi)
8262{
8263 /* XXX - The only use case where this is really guaranteed to work is
8264 * increasing the length of an item (which has no effect if the item
8265 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8266 *
8267 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8268 *
8269 * Should there be a macro or function to do that, and possibly this
8270 * be deprecated? As a bonus, we could handle overflow.
8271 */
8272 field_info *fi;
8273
8274 if (!pi)
8275 return 0;
8276 fi = PITEM_FINFO(pi)((pi)->finfo);
8277 if (fi) {
8278 return fi->length;
8279 }
8280 return 0;
8281}
8282
8283void
8284proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8285 if (!ti) {
8286 return;
8287 }
8288 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)
;
8289 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)
;
8290}
8291
8292char *
8293proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8294{
8295 field_info *fi;
8296
8297 if (!pi)
8298 return wmem_strdup(scope, "");
8299 fi = PITEM_FINFO(pi)((pi)->finfo);
8300 if (!fi)
8301 return wmem_strdup(scope, "");
8302 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8302, "fi->hfinfo != ((void*)0)"
))))
;
8303 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8304}
8305
8306proto_tree *
8307proto_tree_create_root(packet_info *pinfo)
8308{
8309 proto_node *pnode;
8310
8311 /* Initialize the proto_node */
8312 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8313 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8314 pnode->parent = NULL((void*)0);
8315 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8316 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)))
;
8317
8318 /* Make sure we can access pinfo everywhere */
8319 pnode->tree_data->pinfo = pinfo;
8320
8321 /* Don't initialize the tree_data_t. Wait until we know we need it */
8322 pnode->tree_data->interesting_hfids = NULL((void*)0);
8323
8324 /* Set the default to false so it's easier to
8325 * find errors; if we expect to see the protocol tree
8326 * but for some reason the default 'visible' is not
8327 * changed, then we'll find out very quickly. */
8328 pnode->tree_data->visible = false0;
8329
8330 /* Make sure that we fake protocols (if possible) */
8331 pnode->tree_data->fake_protocols = true1;
8332
8333 /* Keep track of the number of children */
8334 pnode->tree_data->count = 0;
8335
8336 /* Initialize our loop checks */
8337 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8338 pnode->tree_data->max_start = 0;
8339 pnode->tree_data->start_idle_count = 0;
8340
8341 return (proto_tree *)pnode;
8342}
8343
8344
8345/* "prime" a proto_tree with a single hfid that a dfilter
8346 * is interested in. */
8347void
8348proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8349{
8350 header_field_info *hfinfo;
8351
8352 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", 8352, __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", 8352, "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", 8352, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8353 /* this field is referenced by a filter so increase the refcount.
8354 also increase the refcount for the parent, i.e the protocol.
8355 Don't increase the refcount if we're already printing the
8356 type, as that is a superset of direct reference.
8357 */
8358 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8359 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8360 }
8361 /* only increase the refcount if there is a parent.
8362 if this is a protocol and not a field then parent will be -1
8363 and there is no parent to add any refcounting for.
8364 */
8365 if (hfinfo->parent != -1) {
8366 header_field_info *parent_hfinfo;
8367 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", 8367
, __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", 8367,
"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", 8367,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf."
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8368
8369 /* Mark parent as indirectly referenced unless it is already directly
8370 * referenced, i.e. the user has specified the parent in a filter.
8371 */
8372 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8373 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8374 }
8375}
8376
8377/* "prime" a proto_tree with a single hfid that a dfilter
8378 * is interested in. */
8379void
8380proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8381{
8382 header_field_info *hfinfo;
8383
8384 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", 8384, __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", 8384, "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", 8384, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8385 /* this field is referenced by an (output) filter so increase the refcount.
8386 also increase the refcount for the parent, i.e the protocol.
8387 */
8388 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8389 /* only increase the refcount if there is a parent.
8390 if this is a protocol and not a field then parent will be -1
8391 and there is no parent to add any refcounting for.
8392 */
8393 if (hfinfo->parent != -1) {
8394 header_field_info *parent_hfinfo;
8395 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", 8395
, __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", 8395,
"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", 8395,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf."
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8396
8397 /* Mark parent as indirectly referenced unless it is already directly
8398 * referenced, i.e. the user has specified the parent in a filter.
8399 */
8400 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8401 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8402 }
8403}
8404
8405proto_tree *
8406proto_item_add_subtree(proto_item *pi, const int idx) {
8407 field_info *fi;
8408
8409 if (!pi)
8410 return NULL((void*)0);
8411
8412 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", 8412, "idx >= 0 && idx < num_tree_types"
))))
;
8413
8414 fi = PITEM_FINFO(pi)((pi)->finfo);
8415 if (!fi)
8416 return (proto_tree *)pi;
8417
8418 fi->tree_type = idx;
8419
8420 return (proto_tree *)pi;
8421}
8422
8423proto_tree *
8424proto_item_get_subtree(proto_item *pi) {
8425 field_info *fi;
8426
8427 if (!pi)
8428 return NULL((void*)0);
8429 fi = PITEM_FINFO(pi)((pi)->finfo);
8430 if ( (fi) && (fi->tree_type == -1) )
8431 return NULL((void*)0);
8432 return (proto_tree *)pi;
8433}
8434
8435proto_item *
8436proto_item_get_parent(const proto_item *ti) {
8437 if (!ti)
8438 return NULL((void*)0);
8439 return ti->parent;
8440}
8441
8442proto_item *
8443proto_item_get_parent_nth(proto_item *ti, int gen) {
8444 if (!ti)
8445 return NULL((void*)0);
8446 while (gen--) {
8447 ti = ti->parent;
8448 if (!ti)
8449 return NULL((void*)0);
8450 }
8451 return ti;
8452}
8453
8454
8455proto_item *
8456proto_tree_get_parent(proto_tree *tree) {
8457 if (!tree)
8458 return NULL((void*)0);
8459 return (proto_item *)tree;
8460}
8461
8462proto_tree *
8463proto_tree_get_parent_tree(proto_tree *tree) {
8464 if (!tree)
8465 return NULL((void*)0);
8466
8467 /* we're the root tree, there's no parent
8468 return ourselves so the caller has at least a tree to attach to */
8469 if (!tree->parent)
8470 return tree;
8471
8472 return (proto_tree *)tree->parent;
8473}
8474
8475proto_tree *
8476proto_tree_get_root(proto_tree *tree) {
8477 if (!tree)
8478 return NULL((void*)0);
8479 while (tree->parent) {
8480 tree = tree->parent;
8481 }
8482 return tree;
8483}
8484
8485void
8486proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8487 proto_item *item_to_move)
8488{
8489 /* This function doesn't generate any values. It only reorganizes the protocol tree
8490 * so we can bail out immediately if it isn't visible. */
8491 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8492 return;
8493
8494 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", 8494, "item_to_move->parent == tree"
))))
;
8495 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", 8495, "fixed_item->parent == tree"
))))
;
8496
8497 /*** cut item_to_move out ***/
8498
8499 /* is item_to_move the first? */
8500 if (tree->first_child == item_to_move) {
8501 /* simply change first child to next */
8502 tree->first_child = item_to_move->next;
8503
8504 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", 8504, "tree->last_child != item_to_move"
))))
;
8505 } else {
8506 proto_item *curr_item;
8507 /* find previous and change it's next */
8508 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8509 if (curr_item->next == item_to_move) {
8510 break;
8511 }
8512 }
8513
8514 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8514, "curr_item"
))))
;
8515
8516 curr_item->next = item_to_move->next;
8517
8518 /* fix last_child if required */
8519 if (tree->last_child == item_to_move) {
8520 tree->last_child = curr_item;
8521 }
8522 }
8523
8524 /*** insert to_move after fixed ***/
8525 item_to_move->next = fixed_item->next;
8526 fixed_item->next = item_to_move;
8527 if (tree->last_child == fixed_item) {
8528 tree->last_child = item_to_move;
8529 }
8530}
8531
8532void
8533proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8534 const unsigned length)
8535{
8536 field_info *fi;
8537
8538 if (tree == NULL((void*)0))
8539 return;
8540
8541 fi = PTREE_FINFO(tree)((tree)->finfo);
8542 if (fi == NULL((void*)0))
8543 return;
8544
8545 /* We don't store a separate data source tvb for the appendix, so
8546 * it must be from the same data source. (XXX - Are there any
8547 * situations where it makes sense to have an appendix from a
8548 * different data source?) */
8549 if (G_LIKELY(tvb)(tvb)) {
8550 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"
, 8550, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8551 start += tvb_raw_offset(tvb);
8552 } else {
8553 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", 8553, "((void*)0) == fi->ds_tvb"
))))
;
8554 }
8555
8556 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8557 * main body? */
8558
8559 fi->appendix_start = start;
8560 fi->appendix_length = length;
8561}
8562
8563static void
8564check_protocol_filter_name_or_fail(const char *filter_name)
8565{
8566 /* Require at least two characters. */
8567 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8568 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)
;
8569 }
8570
8571 if (proto_check_field_name(filter_name) != '\0') {
8572 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)
8573 " 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)
8574 " 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)
;
8575 }
8576
8577 /* Check that it doesn't match some very common numeric forms. */
8578 if (filter_name[0] == '0' &&
8579 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8580 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8581 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])
8582 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])
;
8583 }
8584
8585 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8586
8587 /* Check that it contains at least one letter. */
8588 bool_Bool have_letter = false0;
8589 for (const char *s = filter_name; *s != '\0'; s++) {
8590 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8591 have_letter = true1;
8592 break;
8593 }
8594 }
8595 if (!have_letter) {
8596 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)
8597 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8598 }
8599
8600 /* Check for reserved keywords. */
8601 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8602 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)
8603 " 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)
;
8604 }
8605}
8606
8607int
8608proto_register_protocol(const char *name, const char *short_name,
8609 const char *filter_name)
8610{
8611 protocol_t *protocol;
8612 header_field_info *hfinfo;
8613
8614 check_protocol_filter_name_or_fail(filter_name);
8615
8616 /*
8617 * Add this protocol to the list of known protocols;
8618 * the list is sorted by protocol short name.
8619 */
8620 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8621 protocol->name = name;
8622 protocol->short_name = short_name;
8623 protocol->filter_name = filter_name;
8624 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8625 protocol->is_enabled = true1; /* protocol is enabled by default */
8626 protocol->enabled_by_default = true1; /* see previous comment */
8627 protocol->can_toggle = true1;
8628 protocol->parent_proto_id = -1;
8629 protocol->heur_list = NULL((void*)0);
8630
8631 /* List will be sorted later by name, when all protocols completed registering */
8632 protocols = g_list_prepend(protocols, protocol);
8633 /*
8634 * Make sure there's not already a protocol with any of those
8635 * names. Crash if there is, as that's an error in the code
8636 * or an inappropriate plugin.
8637 * This situation has to be fixed to not register more than one
8638 * protocol with the same name.
8639 */
8640 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8641 /* ws_error will terminate the program */
8642 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)
8643 " 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)
;
8644 }
8645 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8646 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)
8647 " 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)
;
8648 }
8649 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8650 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)
8651 " 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)
;
8652 }
8653
8654 /* Here we allocate a new header_field_info struct */
8655 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8656 hfinfo->name = name;
8657 hfinfo->abbrev = filter_name;
8658 hfinfo->type = FT_PROTOCOL;
8659 hfinfo->display = BASE_NONE;
8660 hfinfo->strings = protocol;
8661 hfinfo->bitmask = 0;
8662 hfinfo->ref_type = HF_REF_TYPE_NONE;
8663 hfinfo->blurb = NULL((void*)0);
8664 hfinfo->parent = -1; /* This field differentiates protos and fields */
8665
8666 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8667 return protocol->proto_id;
8668}
8669
8670int
8671proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8672{
8673 protocol_t *protocol;
8674 header_field_info *hfinfo;
8675
8676 /*
8677 * Helper protocols don't need the strict rules as a "regular" protocol
8678 * Just register it in a list and make a hf_ field from it
8679 */
8680 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8681 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)
;
8682 }
8683
8684 if (parent_proto <= 0) {
8685 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)
8686 " 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)
;
8687 }
8688
8689 check_protocol_filter_name_or_fail(filter_name);
8690
8691 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8692 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8693 protocol->name = name;
8694 protocol->short_name = short_name;
8695 protocol->filter_name = filter_name;
8696 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8697
8698 /* Enabling and toggling is really determined by parent protocol,
8699 but provide default values here */
8700 protocol->is_enabled = true1;
8701 protocol->enabled_by_default = true1;
8702 protocol->can_toggle = true1;
8703
8704 protocol->parent_proto_id = parent_proto;
8705 protocol->heur_list = NULL((void*)0);
8706
8707 /* List will be sorted later by name, when all protocols completed registering */
8708 protocols = g_list_prepend(protocols, protocol);
8709
8710 /* Here we allocate a new header_field_info struct */
8711 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8712 hfinfo->name = name;
8713 hfinfo->abbrev = filter_name;
8714 hfinfo->type = field_type;
8715 hfinfo->display = BASE_NONE;
8716 if (field_type == FT_BYTES) {
8717 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8718 }
8719 hfinfo->strings = protocol;
8720 hfinfo->bitmask = 0;
8721 hfinfo->ref_type = HF_REF_TYPE_NONE;
8722 hfinfo->blurb = NULL((void*)0);
8723 hfinfo->parent = -1; /* This field differentiates protos and fields */
8724
8725 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8726 return protocol->proto_id;
8727}
8728
8729bool_Bool
8730proto_deregister_protocol(const char *short_name)
8731{
8732 protocol_t *protocol;
8733 header_field_info *hfinfo;
8734 int proto_id;
8735 unsigned i;
8736
8737 proto_id = proto_get_id_by_short_name(short_name);
8738 protocol = find_protocol_by_id(proto_id);
8739 if (protocol == NULL((void*)0))
8740 return false0;
8741
8742 g_hash_table_remove(proto_names, protocol->name);
8743 g_hash_table_remove(proto_short_names, (void *)short_name);
8744 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8745
8746 if (protocol->fields) {
8747 for (i = 0; i < protocol->fields->len; i++) {
8748 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8749 hfinfo_remove_from_gpa_name_map(hfinfo);
8750 expert_deregister_expertinfo(hfinfo->abbrev);
8751 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8752 }
8753 g_ptr_array_free(protocol->fields, true1);
8754 protocol->fields = NULL((void*)0);
8755 }
8756
8757 g_list_free(protocol->heur_list);
8758
8759 /* Remove this protocol from the list of known protocols */
8760 protocols = g_list_remove(protocols, protocol);
8761
8762 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8763 wmem_map_remove(gpa_name_map, protocol->filter_name);
8764
8765 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)
;
8766 last_field_name = NULL((void*)0);
8767
8768 return true1;
8769}
8770
8771void
8772proto_register_alias(const int proto_id, const char *alias_name)
8773{
8774 protocol_t *protocol;
8775
8776 protocol = find_protocol_by_id(proto_id);
8777 if (alias_name && protocol) {
8778 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8779 }
8780}
8781
8782/*
8783 * Routines to use to iterate over the protocols.
8784 * The argument passed to the iterator routines is an opaque cookie to
8785 * their callers; it's the GList pointer for the current element in
8786 * the list.
8787 * The ID of the protocol is returned, or -1 if there is no protocol.
8788 */
8789int
8790proto_get_first_protocol(void **cookie)
8791{
8792 protocol_t *protocol;
8793
8794 if (protocols == NULL((void*)0))
8795 return -1;
8796 *cookie = protocols;
8797 protocol = (protocol_t *)protocols->data;
8798 return protocol->proto_id;
8799}
8800
8801int
8802proto_get_data_protocol(void *cookie)
8803{
8804 GList *list_item = (GList *)cookie;
8805
8806 protocol_t *protocol = (protocol_t *)list_item->data;
8807 return protocol->proto_id;
8808}
8809
8810int
8811proto_get_next_protocol(void **cookie)
8812{
8813 GList *list_item = (GList *)*cookie;
8814 protocol_t *protocol;
8815
8816 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8817 if (list_item == NULL((void*)0))
8818 return -1;
8819 *cookie = list_item;
8820 protocol = (protocol_t *)list_item->data;
8821 return protocol->proto_id;
8822}
8823
8824header_field_info *
8825proto_get_first_protocol_field(const int proto_id, void **cookie)
8826{
8827 protocol_t *protocol = find_protocol_by_id(proto_id);
8828
8829 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8830 return NULL((void*)0);
8831
8832 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8833 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8834}
8835
8836header_field_info *
8837proto_get_next_protocol_field(const int proto_id, void **cookie)
8838{
8839 protocol_t *protocol = find_protocol_by_id(proto_id);
8840 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8841
8842 i++;
8843
8844 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8845 return NULL((void*)0);
8846
8847 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8848 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8849}
8850
8851protocol_t *
8852find_protocol_by_id(const int proto_id)
8853{
8854 header_field_info *hfinfo;
8855
8856 if (proto_id <= 0)
8857 return NULL((void*)0);
8858
8859 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", 8859, __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", 8859,
"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", 8859, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8860 if (hfinfo->type != FT_PROTOCOL) {
8861 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", 8861, "hfinfo->display & 0x00004000"
))))
;
8862 }
8863 return (protocol_t *)hfinfo->strings;
8864}
8865
8866int
8867proto_get_id(const protocol_t *protocol)
8868{
8869 return protocol->proto_id;
8870}
8871
8872bool_Bool
8873proto_name_already_registered(const char *name)
8874{
8875 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8875, "name", "No name present"))))
;
8876
8877 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8878 return true1;
8879 return false0;
8880}
8881
8882int
8883proto_get_id_by_filter_name(const char *filter_name)
8884{
8885 const protocol_t *protocol = NULL((void*)0);
8886
8887 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", 8887,
"filter_name", "No filter name present"))))
;
8888
8889 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8890
8891 if (protocol == NULL((void*)0))
8892 return -1;
8893 return protocol->proto_id;
8894}
8895
8896int
8897proto_get_id_by_short_name(const char *short_name)
8898{
8899 const protocol_t *protocol = NULL((void*)0);
8900
8901 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", 8901,
"short_name", "No short name present"))))
;
8902
8903 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8904
8905 if (protocol == NULL((void*)0))
8906 return -1;
8907 return protocol->proto_id;
8908}
8909
8910const char *
8911proto_get_protocol_name(const int proto_id)
8912{
8913 protocol_t *protocol;
8914
8915 protocol = find_protocol_by_id(proto_id);
8916
8917 if (protocol == NULL((void*)0))
8918 return NULL((void*)0);
8919 return protocol->name;
8920}
8921
8922const char *
8923proto_get_protocol_short_name(const protocol_t *protocol)
8924{
8925 if (protocol == NULL((void*)0))
8926 return "(none)";
8927 return protocol->short_name;
8928}
8929
8930const char *
8931proto_get_protocol_long_name(const protocol_t *protocol)
8932{
8933 if (protocol == NULL((void*)0))
8934 return "(none)";
8935 return protocol->name;
8936}
8937
8938const char *
8939proto_get_protocol_filter_name(const int proto_id)
8940{
8941 protocol_t *protocol;
8942
8943 protocol = find_protocol_by_id(proto_id);
8944 if (protocol == NULL((void*)0))
8945 return "(none)";
8946 return protocol->filter_name;
8947}
8948
8949void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8950{
8951 heur_dtbl_entry_t* heuristic_dissector;
8952
8953 if (protocol == NULL((void*)0))
8954 return;
8955
8956 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8957 if (heuristic_dissector != NULL((void*)0))
8958 {
8959 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8960 }
8961}
8962
8963void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8964{
8965 if (protocol == NULL((void*)0))
8966 return;
8967
8968 g_list_foreach(protocol->heur_list, func, user_data);
8969}
8970
8971void
8972proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8973 bool_Bool *is_tcp, bool_Bool *is_udp,
8974 bool_Bool *is_sctp, bool_Bool *is_tls,
8975 bool_Bool *is_rtp,
8976 bool_Bool *is_lte_rlc)
8977{
8978 wmem_list_frame_t *protos = wmem_list_head(layers);
8979 int proto_id;
8980 const char *proto_name;
8981
8982 /* Walk the list of a available protocols in the packet and
8983 attempt to find "major" ones. */
8984 /* It might make more sense to assemble and return a bitfield. */
8985 while (protos != NULL((void*)0))
8986 {
8987 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8988 proto_name = proto_get_protocol_filter_name(proto_id);
8989
8990 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8991 (!strcmp(proto_name, "ipv6")))) {
8992 *is_ip = true1;
8993 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8994 *is_tcp = true1;
8995 } else if (is_udp && !strcmp(proto_name, "udp")) {
8996 *is_udp = true1;
8997 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8998 *is_sctp = true1;
8999 } else if (is_tls && !strcmp(proto_name, "tls")) {
9000 *is_tls = true1;
9001 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
9002 *is_rtp = true1;
9003 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
9004 *is_lte_rlc = true1;
9005 }
9006
9007 protos = wmem_list_frame_next(protos);
9008 }
9009}
9010
9011bool_Bool
9012proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
9013{
9014 wmem_list_frame_t *protos = wmem_list_head(layers);
9015 int proto_id;
9016 const char *name;
9017
9018 /* Walk the list of a available protocols in the packet and
9019 attempt to find the specified protocol. */
9020 while (protos != NULL((void*)0))
9021 {
9022 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
9023 name = proto_get_protocol_filter_name(proto_id);
9024
9025 if (!strcmp(name, proto_name))
9026 {
9027 return true1;
9028 }
9029
9030 protos = wmem_list_frame_next(protos);
9031 }
9032
9033 return false0;
9034}
9035
9036char *
9037proto_list_layers(const packet_info *pinfo)
9038{
9039 wmem_strbuf_t *buf;
9040 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
9041
9042 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
9043
9044 /* Walk the list of layers in the packet and
9045 return a string of all entries. */
9046 while (layers != NULL((void*)0))
9047 {
9048 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
9049
9050 layers = wmem_list_frame_next(layers);
9051 if (layers != NULL((void*)0)) {
9052 wmem_strbuf_append_c(buf, ':');
9053 }
9054 }
9055
9056 return wmem_strbuf_finalize(buf);
9057}
9058
9059uint8_t
9060proto_get_layer_num(const packet_info *pinfo, const int proto_id)
9061{
9062 int *proto_layer_num_ptr;
9063
9064 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
9065 if (proto_layer_num_ptr == NULL((void*)0)) {
9066 return 0;
9067 }
9068
9069 return (uint8_t)*proto_layer_num_ptr;
9070}
9071
9072bool_Bool
9073proto_is_pino(const protocol_t *protocol)
9074{
9075 return (protocol->parent_proto_id != -1);
9076}
9077
9078bool_Bool
9079proto_is_bytes_pino(const protocol_t *protocol)
9080{
9081 header_field_info *hfinfo;
9082
9083 if (!proto_is_pino(protocol))
9084 return false0;
9085
9086 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", 9086
, __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", 9086,
"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", 9086,
"gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[protocol->proto_id];
;
9087 return hfinfo->type != FT_PROTOCOL;
9088}
9089
9090bool_Bool
9091// NOLINTNEXTLINE(misc-no-recursion)
9092proto_is_protocol_enabled(const protocol_t *protocol)
9093{
9094 if (protocol == NULL((void*)0))
9095 return false0;
9096
9097 //parent protocol determines enable/disable for helper dissectors
9098 if (proto_is_pino(protocol))
9099 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9100
9101 return protocol->is_enabled;
9102}
9103
9104bool_Bool
9105// NOLINTNEXTLINE(misc-no-recursion)
9106proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9107{
9108 //parent protocol determines enable/disable for helper dissectors
9109 if (proto_is_pino(protocol))
9110 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9111
9112 return protocol->enabled_by_default;
9113}
9114
9115bool_Bool
9116// NOLINTNEXTLINE(misc-no-recursion)
9117proto_can_toggle_protocol(const int proto_id)
9118{
9119 protocol_t *protocol;
9120
9121 protocol = find_protocol_by_id(proto_id);
9122 //parent protocol determines toggling for helper dissectors
9123 if (proto_is_pino(protocol))
9124 return proto_can_toggle_protocol(protocol->parent_proto_id);
9125
9126 return protocol->can_toggle;
9127}
9128
9129void
9130proto_disable_by_default(const int proto_id)
9131{
9132 protocol_t *protocol;
9133
9134 protocol = find_protocol_by_id(proto_id);
9135 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9135, "protocol->can_toggle"
))))
;
9136 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", 9136, "proto_is_pino(protocol) == 0"
))))
;
9137 protocol->is_enabled = false0;
9138 protocol->enabled_by_default = false0;
9139}
9140
9141void
9142proto_set_decoding(const int proto_id, const bool_Bool enabled)
9143{
9144 protocol_t *protocol;
9145
9146 protocol = find_protocol_by_id(proto_id);
9147 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9147, "protocol->can_toggle"
))))
;
9148 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", 9148, "proto_is_pino(protocol) == 0"
))))
;
9149 protocol->is_enabled = enabled;
9150}
9151
9152void
9153proto_disable_all(void)
9154{
9155 /* This doesn't explicitly disable heuristic protocols,
9156 * but the heuristic doesn't get called if the parent
9157 * protocol isn't enabled.
9158 */
9159 protocol_t *protocol;
9160 GList *list_item = protocols;
9161
9162 if (protocols == NULL((void*)0))
9163 return;
9164
9165 while (list_item) {
9166 protocol = (protocol_t *)list_item->data;
9167 if (protocol->can_toggle) {
9168 protocol->is_enabled = false0;
9169 }
9170 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9171 }
9172}
9173
9174static void
9175heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9176{
9177 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9178
9179 heur->enabled = heur->enabled_by_default;
9180}
9181
9182void
9183proto_reenable_all(void)
9184{
9185 protocol_t *protocol;
9186 GList *list_item = protocols;
9187
9188 if (protocols == NULL((void*)0))
9189 return;
9190
9191 while (list_item) {
9192 protocol = (protocol_t *)list_item->data;
9193 if (protocol->can_toggle)
9194 protocol->is_enabled = protocol->enabled_by_default;
9195 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9196 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9197 }
9198}
9199
9200void
9201proto_set_cant_toggle(const int proto_id)
9202{
9203 protocol_t *protocol;
9204
9205 protocol = find_protocol_by_id(proto_id);
9206 protocol->can_toggle = false0;
9207}
9208
9209static int
9210proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9211{
9212 g_ptr_array_add(proto->fields, hfi);
9213
9214 return proto_register_field_init(hfi, parent);
9215}
9216
9217/* for use with static arrays only, since we don't allocate our own copies
9218of the header_field_info struct contained within the hf_register_info struct */
9219void
9220proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9221{
9222 hf_register_info *ptr = hf;
9223 protocol_t *proto;
9224 int i;
9225
9226 proto = find_protocol_by_id(parent);
9227
9228 /* if (proto == NULL) - error or return? */
9229
9230 if (proto->fields == NULL((void*)0)) {
9231 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9232 * GLib introduced g_ptr_array_new_from_array, which might have
9233 * given a reason to actually use it. (#17774)
9234 */
9235 proto->fields = g_ptr_array_sized_new(num_records);
9236 }
9237
9238 for (i = 0; i < num_records; i++, ptr++) {
9239 /*
9240 * Make sure we haven't registered this yet.
9241 * Most fields have variables associated with them that
9242 * are initialized to 0; some are initialized to -1 (which
9243 * was the standard before 4.4).
9244 *
9245 * XXX - Since this is called almost 300000 times at startup,
9246 * it might be nice to compare to only 0 and require
9247 * dissectors to pass in zero for unregistered fields.
9248 */
9249 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9250 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9251 "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)
9252 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9253 return;
9254 }
9255
9256 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9257 }
9258}
9259
9260/* deregister already registered fields */
9261void
9262proto_deregister_field (const int parent, int hf_id)
9263{
9264 header_field_info *hfi;
9265 protocol_t *proto;
9266 unsigned i;
9267
9268 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)
;
9269 last_field_name = NULL((void*)0);
9270
9271 if (hf_id == -1 || hf_id == 0)
9272 return;
9273
9274 proto = find_protocol_by_id (parent);
9275 if (!proto || proto->fields == NULL((void*)0)) {
9276 return;
9277 }
9278
9279 for (i = 0; i < proto->fields->len; i++) {
9280 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9281 if (hfi->id == hf_id) {
9282 /* Found the hf_id in this protocol */
9283 wmem_map_remove(gpa_name_map, hfi->abbrev);
9284 g_ptr_array_remove_index_fast(proto->fields, i);
9285 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9286 return;
9287 }
9288 }
9289}
9290
9291/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9292void
9293proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9294{
9295 header_field_info *hfinfo;
9296 protocol_t *proto;
9297
9298 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)
;
9299 last_field_name = NULL((void*)0);
9300
9301 proto = find_protocol_by_id(parent);
9302 if (proto && proto->fields && proto->fields->len > 0) {
9303 unsigned i = proto->fields->len;
9304 do {
9305 i--;
9306
9307 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9308 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) )
) {
9309 hfinfo_remove_from_gpa_name_map(hfinfo);
9310 expert_deregister_expertinfo(hfinfo->abbrev);
9311 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9312 g_ptr_array_remove_index_fast(proto->fields, i);
9313 }
9314 } while (i > 0);
9315 }
9316}
9317
9318void
9319proto_add_deregistered_data (void *data)
9320{
9321 g_ptr_array_add(deregistered_data, data);
9322}
9323
9324void
9325proto_add_deregistered_slice (size_t block_size, void *mem_block)
9326{
9327 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)))
;
9328
9329 slice_data->block_size = block_size;
9330 slice_data->mem_block = mem_block;
9331
9332 g_ptr_array_add(deregistered_slice, slice_data);
9333}
9334
9335void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9336{
9337 if (field_strings == NULL((void*)0)) {
9338 return;
9339 }
9340
9341 switch (field_type) {
9342 case FT_FRAMENUM:
9343 /* This is just an integer represented as a pointer */
9344 break;
9345 case FT_PROTOCOL: {
9346 protocol_t *protocol = (protocol_t *)field_strings;
9347 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)
;
9348 break;
9349 }
9350 case FT_BOOLEAN: {
9351 true_false_string *tf = (true_false_string *)field_strings;
9352 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)
;
9353 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)
;
9354 break;
9355 }
9356 case FT_UINT40:
9357 case FT_INT40:
9358 case FT_UINT48:
9359 case FT_INT48:
9360 case FT_UINT56:
9361 case FT_INT56:
9362 case FT_UINT64:
9363 case FT_INT64: {
9364 if (field_display & BASE_UNIT_STRING0x00001000) {
9365 unit_name_string *unit = (unit_name_string *)field_strings;
9366 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)
;
9367 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)
;
9368 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9369 range_string *rs = (range_string *)field_strings;
9370 while (rs->strptr) {
9371 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
)
;
9372 rs++;
9373 }
9374 } else if (field_display & BASE_EXT_STRING0x00000200) {
9375 val64_string_ext *vse = (val64_string_ext *)field_strings;
9376 val64_string *vs = (val64_string *)vse->_vs_p;
9377 while (vs->strptr) {
9378 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
)
;
9379 vs++;
9380 }
9381 val64_string_ext_free(vse);
9382 field_strings = NULL((void*)0);
9383 } else if (field_display == BASE_CUSTOM) {
9384 /* this will be a pointer to a function, don't free that */
9385 field_strings = NULL((void*)0);
9386 } else {
9387 val64_string *vs64 = (val64_string *)field_strings;
9388 while (vs64->strptr) {
9389 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)
;
9390 vs64++;
9391 }
9392 }
9393 break;
9394 }
9395 case FT_CHAR:
9396 case FT_UINT8:
9397 case FT_INT8:
9398 case FT_UINT16:
9399 case FT_INT16:
9400 case FT_UINT24:
9401 case FT_INT24:
9402 case FT_UINT32:
9403 case FT_INT32:
9404 case FT_FLOAT:
9405 case FT_DOUBLE: {
9406 if (field_display & BASE_UNIT_STRING0x00001000) {
9407 unit_name_string *unit = (unit_name_string *)field_strings;
9408 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)
;
9409 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)
;
9410 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9411 range_string *rs = (range_string *)field_strings;
9412 while (rs->strptr) {
9413 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
)
;
9414 rs++;
9415 }
9416 } else if (field_display & BASE_EXT_STRING0x00000200) {
9417 value_string_ext *vse = (value_string_ext *)field_strings;
9418 value_string *vs = (value_string *)vse->_vs_p;
9419 while (vs->strptr) {
9420 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
)
;
9421 vs++;
9422 }
9423 value_string_ext_free(vse);
9424 field_strings = NULL((void*)0);
9425 } else if (field_display == BASE_CUSTOM) {
9426 /* this will be a pointer to a function, don't free that */
9427 field_strings = NULL((void*)0);
9428 } else {
9429 value_string *vs = (value_string *)field_strings;
9430 while (vs->strptr) {
9431 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
)
;
9432 vs++;
9433 }
9434 }
9435 break;
9436 default:
9437 break;
9438 }
9439 }
9440
9441 if (field_type != FT_FRAMENUM) {
9442 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
)
;
9443 }
9444}
9445
9446static void
9447free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9448{
9449 header_field_info *hfi = (header_field_info *) data;
9450 int hf_id = hfi->id;
9451
9452 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
)
;
9453 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
)
;
9454 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
)
;
9455
9456 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9457
9458 if (hfi->parent == -1)
9459 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)
;
9460
9461 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9462}
9463
9464static void
9465free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9466{
9467 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9468}
9469
9470static void
9471free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9472{
9473 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9474
9475 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9476 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)
;
9477}
9478
9479/* free deregistered fields and data */
9480void
9481proto_free_deregistered_fields (void)
9482{
9483 expert_free_deregistered_expertinfos();
9484
9485 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9486 g_ptr_array_free(deregistered_fields, true1);
9487 deregistered_fields = g_ptr_array_new();
9488
9489 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9490 g_ptr_array_free(deregistered_data, true1);
9491 deregistered_data = g_ptr_array_new();
9492
9493 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9494 g_ptr_array_free(deregistered_slice, true1);
9495 deregistered_slice = g_ptr_array_new();
9496}
9497
9498static const value_string hf_display[] = {
9499 { BASE_NONE, "BASE_NONE" },
9500 { BASE_DEC, "BASE_DEC" },
9501 { BASE_HEX, "BASE_HEX" },
9502 { BASE_OCT, "BASE_OCT" },
9503 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9504 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9505 { BASE_CUSTOM, "BASE_CUSTOM" },
9506 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9507 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9508 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9509 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9510 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9511 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9512 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9513 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9514 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9515 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9516 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9517 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9518 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9519 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9520 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9521 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9522 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9523 { BASE_PT_UDP, "BASE_PT_UDP" },
9524 { BASE_PT_TCP, "BASE_PT_TCP" },
9525 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9526 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9527 { BASE_OUI, "BASE_OUI" },
9528 { 0, NULL((void*)0) } };
9529
9530const char* proto_field_display_to_string(int field_display)
9531{
9532 return val_to_str_const(field_display, hf_display, "Unknown");
9533}
9534
9535static inline port_type
9536display_to_port_type(field_display_e e)
9537{
9538 switch (e) {
9539 case BASE_PT_UDP:
9540 return PT_UDP;
9541 case BASE_PT_TCP:
9542 return PT_TCP;
9543 case BASE_PT_DCCP:
9544 return PT_DCCP;
9545 case BASE_PT_SCTP:
9546 return PT_SCTP;
9547 default:
9548 break;
9549 }
9550 return PT_NONE;
9551}
9552
9553/* temporary function containing assert part for easier profiling */
9554static void
9555tmp_fld_check_assert(header_field_info *hfinfo)
9556{
9557 char* tmp_str;
9558
9559 /* The field must have a name (with length > 0) */
9560 if (!hfinfo->name || !hfinfo->name[0]) {
9561 if (hfinfo->abbrev)
9562 /* Try to identify the field */
9563 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)
9564 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9565 else
9566 /* Hum, no luck */
9567 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)"
)
;
9568 }
9569
9570 /* fields with an empty string for an abbreviation aren't filterable */
9571 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9572 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)
;
9573
9574 /* TODO: This check is a significant percentage of startup time (~10%),
9575 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9576 It might be nice to have a way to disable this check when, e.g.,
9577 running TShark many times with the same configuration. */
9578 /* Check that the filter name (abbreviation) is legal;
9579 * it must contain only alphanumerics, '-', "_", and ".". */
9580 unsigned char c;
9581 c = module_check_valid_name(hfinfo->abbrev, false0);
9582 if (c) {
9583 if (c == '.') {
9584 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)
;
9585 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9586 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)
;
9587 } else {
9588 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)
;
9589 }
9590 }
9591
9592 /* These types of fields are allowed to have value_strings,
9593 * true_false_strings or a protocol_t struct
9594 */
9595 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9596 switch (hfinfo->type) {
9597
9598 /*
9599 * These types are allowed to support display value_strings,
9600 * value64_strings, the extended versions of the previous
9601 * two, range strings, or unit strings.
9602 */
9603 case FT_CHAR:
9604 case FT_UINT8:
9605 case FT_UINT16:
9606 case FT_UINT24:
9607 case FT_UINT32:
9608 case FT_UINT40:
9609 case FT_UINT48:
9610 case FT_UINT56:
9611 case FT_UINT64:
9612 case FT_INT8:
9613 case FT_INT16:
9614 case FT_INT24:
9615 case FT_INT32:
9616 case FT_INT40:
9617 case FT_INT48:
9618 case FT_INT56:
9619 case FT_INT64:
9620 case FT_BOOLEAN:
9621 case FT_PROTOCOL:
9622 break;
9623
9624 /*
9625 * This is allowed to have a value of type
9626 * enum ft_framenum_type to indicate what relationship
9627 * the frame in question has to the frame in which
9628 * the field is put.
9629 */
9630 case FT_FRAMENUM:
9631 break;
9632
9633 /*
9634 * These types are allowed to support only unit strings.
9635 */
9636 case FT_FLOAT:
9637 case FT_DOUBLE:
9638 case FT_IEEE_11073_SFLOAT:
9639 case FT_IEEE_11073_FLOAT:
9640 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9641 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))
9642 " (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))
9643 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))
;
9644 }
9645 break;
9646
9647 /*
9648 * These types are allowed to support display
9649 * time_value_strings.
9650 */
9651 case FT_ABSOLUTE_TIME:
9652 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9653 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9654 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9655 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9656 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))
9657 " (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))
9658 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))
;
9659 }
9660 break;
9661
9662 /*
9663 * This type is only allowed to support a string if it's
9664 * a protocol (for pinos).
9665 */
9666 case FT_BYTES:
9667 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9668 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))
9669 " (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))
9670 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))
;
9671 }
9672 break;
9673
9674 default:
9675 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))
9676 " (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))
9677 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))
;
9678 }
9679 }
9680
9681 /* TODO: This check may slow down startup, and output quite a few warnings.
9682 It would be good to be able to enable this (and possibly other checks?)
9683 in non-release builds. */
9684#ifdef ENABLE_CHECK_FILTER
9685 /* Check for duplicate value_string values.
9686 There are lots that have the same value *and* string, so for now only
9687 report those that have same value but different string. */
9688 if ((hfinfo->strings != NULL((void*)0)) &&
9689 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9690 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9691 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9692 (
9693 (hfinfo->type == FT_CHAR) ||
9694 (hfinfo->type == FT_UINT8) ||
9695 (hfinfo->type == FT_UINT16) ||
9696 (hfinfo->type == FT_UINT24) ||
9697 (hfinfo->type == FT_UINT32) ||
9698 (hfinfo->type == FT_INT8) ||
9699 (hfinfo->type == FT_INT16) ||
9700 (hfinfo->type == FT_INT24) ||
9701 (hfinfo->type == FT_INT32) )) {
9702
9703 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9704 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9705 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9706 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9707 } else {
9708 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9709 CHECK_HF_VALUE(value_string, "u", start_values);
9710 }
9711 } else {
9712 const value_string *start_values = (const value_string*)hfinfo->strings;
9713 CHECK_HF_VALUE(value_string, "u", start_values);
9714 }
9715 }
9716
9717 if (hfinfo->type == FT_BOOLEAN) {
9718 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9719 if (tfs) {
9720 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9721 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9723
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9722 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9723
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9723 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9723
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9724 }
9725 }
9726 }
9727
9728 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9729 const range_string *rs = (const range_string*)(hfinfo->strings);
9730 if (rs) {
9731 const range_string *this_it = rs;
9732
9733 do {
9734 if (this_it->value_max < this_it->value_min) {
9735 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"
, 9739, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9736 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9739, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9737 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9739, __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)
9738 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9739, __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)
9739 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9739, __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)
;
9740 ++this_it;
9741 continue;
9742 }
9743
9744 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9745 /* Not OK if this one is completely hidden by an earlier one! */
9746 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9747 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"
, 9753, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9748 "(prev=\"%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"
, 9753, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9749 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9753, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9750 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9753, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9751 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9753, __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)
9752 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9753, __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)
9753 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9753, __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)
;
9754 }
9755 }
9756 ++this_it;
9757 } while (this_it->strptr);
9758 }
9759 }
9760#endif
9761
9762 switch (hfinfo->type) {
9763
9764 case FT_CHAR:
9765 /* Require the char type to have BASE_HEX, BASE_OCT,
9766 * BASE_CUSTOM, or BASE_NONE as its base.
9767 *
9768 * If the display value is BASE_NONE and there is a
9769 * strings conversion then the dissector writer is
9770 * telling us that the field's numerical value is
9771 * meaningless; we'll avoid showing the value to the
9772 * user.
9773 */
9774 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9775 case BASE_HEX:
9776 case BASE_OCT:
9777 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9778 break;
9779 case BASE_NONE:
9780 if (hfinfo->strings == NULL((void*)0))
9781 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
))
9782 " 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
))
9783 " 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
))
9784 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
))
9785 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
))
;
9786 break;
9787 default:
9788 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9789 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)
9790 " 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)
9791 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)
9792 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)
;
9793 //wmem_free(NULL, tmp_str);
9794 }
9795 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9796 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
))
9797 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
))
9798 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
))
;
9799 }
9800 break;
9801 case FT_INT8:
9802 case FT_INT16:
9803 case FT_INT24:
9804 case FT_INT32:
9805 case FT_INT40:
9806 case FT_INT48:
9807 case FT_INT56:
9808 case FT_INT64:
9809 /* Hexadecimal and octal are, in printf() and everywhere
9810 * else, unsigned so don't allow dissectors to register a
9811 * signed field to be displayed unsigned. (Else how would
9812 * we display negative values?)
9813 */
9814 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9815 case BASE_HEX:
9816 case BASE_OCT:
9817 case BASE_DEC_HEX:
9818 case BASE_HEX_DEC:
9819 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9820 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)
9821 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)
9822 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)
;
9823 //wmem_free(NULL, tmp_str);
9824 }
9825 /* FALL THROUGH */
9826 case FT_UINT8:
9827 case FT_UINT16:
9828 case FT_UINT24:
9829 case FT_UINT32:
9830 case FT_UINT40:
9831 case FT_UINT48:
9832 case FT_UINT56:
9833 case FT_UINT64:
9834 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
))
) {
9835 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9836 if (hfinfo->type != FT_UINT16) {
9837 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))
9838 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))
9839 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))
;
9840 }
9841 if (hfinfo->strings != NULL((void*)0)) {
9842 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)
9843 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)
9844 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)
;
9845 }
9846 if (hfinfo->bitmask != 0) {
9847 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)
9848 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)
9849 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)
;
9850 }
9851 wmem_free(NULL((void*)0), tmp_str);
9852 break;
9853 }
9854
9855 if (hfinfo->display == BASE_OUI) {
9856 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9857 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) {
9858 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))
9859 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))
9860 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))
;
9861 }
9862 if (hfinfo->strings != NULL((void*)0)) {
9863 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)
9864 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)
9865 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)
;
9866 }
9867 /* It can be a FT_UINT24 with a 0 bitmask, or
9868 * larger with a bitmask with 24 bits set. */
9869 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9870 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)
9871 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)
9872 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)
;
9873 }
9874 wmem_free(NULL((void*)0), tmp_str);
9875 break;
9876 }
9877
9878 /* Require integral types (other than frame number,
9879 * which is always displayed in decimal) to have a
9880 * number base.
9881 *
9882 * If the display value is BASE_NONE and there is a
9883 * strings conversion then the dissector writer is
9884 * telling us that the field's numerical value is
9885 * meaningless; we'll avoid showing the value to the
9886 * user.
9887 */
9888 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9889 case BASE_DEC:
9890 case BASE_HEX:
9891 case BASE_OCT:
9892 case BASE_DEC_HEX:
9893 case BASE_HEX_DEC:
9894 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9895 break;
9896 case BASE_NONE:
9897 if (hfinfo->strings == NULL((void*)0)) {
9898 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
))
9899 " 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
))
9900 " 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
))
9901 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
))
9902 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
))
;
9903 }
9904 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9905 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
))
9906 " 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
))
9907 " 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
))
9908 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
))
9909 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
))
;
9910 }
9911 break;
9912
9913 default:
9914 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9915 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)
9916 " 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)
9917 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)
9918 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)
;
9919 //wmem_free(NULL, tmp_str);
9920 }
9921 break;
9922 case FT_BYTES:
9923 case FT_UINT_BYTES:
9924 /* Require bytes to have a "display type" that could
9925 * add a character between displayed bytes.
9926 */
9927 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9928 case BASE_NONE:
9929 case SEP_DOT:
9930 case SEP_DASH:
9931 case SEP_COLON:
9932 case SEP_SPACE:
9933 break;
9934 default:
9935 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9936 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)
9937 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)
;
9938 //wmem_free(NULL, tmp_str);
9939 }
9940 if (hfinfo->bitmask != 0)
9941 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
))
9942 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
))
9943 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
))
;
9944 //allowed to support string if its a protocol (for pinos)
9945 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9946 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
))
9947 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
))
9948 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
))
;
9949 break;
9950
9951 case FT_PROTOCOL:
9952 case FT_FRAMENUM:
9953 if (hfinfo->display != BASE_NONE) {
9954 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9955 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)
9956 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)
9957 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)
;
9958 //wmem_free(NULL, tmp_str);
9959 }
9960 if (hfinfo->bitmask != 0)
9961 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
))
9962 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
))
9963 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
))
;
9964 break;
9965
9966 case FT_BOOLEAN:
9967 break;
9968
9969 case FT_ABSOLUTE_TIME:
9970 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9971 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9972 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)
9973 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)
;
9974 //wmem_free(NULL, tmp_str);
9975 }
9976 if (hfinfo->bitmask != 0)
9977 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
))
9978 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
))
9979 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
))
;
9980 break;
9981
9982 case FT_STRING:
9983 case FT_STRINGZ:
9984 case FT_UINT_STRING:
9985 case FT_STRINGZPAD:
9986 case FT_STRINGZTRUNC:
9987 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9988 case BASE_NONE:
9989 case BASE_STR_WSP:
9990 break;
9991
9992 default:
9993 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9994 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)
9995 " 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)
9996 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)
9997 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)
;
9998 //wmem_free(NULL, tmp_str);
9999 }
10000
10001 if (hfinfo->bitmask != 0)
10002 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
))
10003 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
))
10004 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
))
;
10005 if (hfinfo->strings != NULL((void*)0))
10006 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
))
10007 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
))
10008 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
))
;
10009 break;
10010
10011 case FT_IPv4:
10012 switch (hfinfo->display) {
10013 case BASE_NONE:
10014 case BASE_NETMASK:
10015 break;
10016
10017 default:
10018 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10019 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)
10020 " 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)
10021 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)
10022 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)
;
10023 //wmem_free(NULL, tmp_str);
10024 break;
10025 }
10026 break;
10027 case FT_FLOAT:
10028 case FT_DOUBLE:
10029 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
10030 case BASE_NONE:
10031 case BASE_DEC:
10032 case BASE_HEX:
10033 case BASE_EXP:
10034 case BASE_CUSTOM:
10035 break;
10036 default:
10037 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10038 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)
10039 " 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)
10040 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)
10041 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)
;
10042 //wmem_free(NULL, tmp_str);
10043 }
10044 if (hfinfo->bitmask != 0)
10045 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
))
10046 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
))
10047 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
))
;
10048 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10049 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
))
10050 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
))
10051 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
))
;
10052 break;
10053 case FT_IEEE_11073_SFLOAT:
10054 case FT_IEEE_11073_FLOAT:
10055 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
10056 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10057 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)
10058 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)
10059 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)
10060 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)
;
10061 //wmem_free(NULL, tmp_str);
10062 }
10063 if (hfinfo->bitmask != 0)
10064 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
))
10065 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
))
10066 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
))
;
10067 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10068 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
))
10069 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
))
10070 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
))
;
10071 break;
10072 default:
10073 if (hfinfo->display != BASE_NONE) {
10074 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10075 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)
10076 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)
10077 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)
10078 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)
;
10079 //wmem_free(NULL, tmp_str);
10080 }
10081 if (hfinfo->bitmask != 0)
10082 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
))
10083 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
))
10084 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
))
;
10085 if (hfinfo->strings != NULL((void*)0))
10086 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
))
10087 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
))
10088 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
))
;
10089 break;
10090 }
10091}
10092
10093static void
10094register_type_length_mismatch(void)
10095{
10096 static ei_register_info ei[] = {
10097 { &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)}}
}},
10098 { &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)}}
}},
10099 };
10100
10101 expert_module_t* expert_type_length_mismatch;
10102
10103 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10104
10105 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10106 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10107
10108 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10109 disabling them makes no sense. */
10110 proto_set_cant_toggle(proto_type_length_mismatch);
10111}
10112
10113static void
10114register_byte_array_string_decodinws_error(void)
10115{
10116 static ei_register_info ei[] = {
10117 { &ei_byte_array_string_decoding_failed_error,
10118 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10119 "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)}}
10120 }
10121 },
10122 };
10123
10124 expert_module_t* expert_byte_array_string_decoding_error;
10125
10126 proto_byte_array_string_decoding_error =
10127 proto_register_protocol("Byte Array-String Decoding Error",
10128 "Byte Array-string decoding error",
10129 "_ws.byte_array_string.decoding_error");
10130
10131 expert_byte_array_string_decoding_error =
10132 expert_register_protocol(proto_byte_array_string_decoding_error);
10133 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10134
10135 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10136 disabling them makes no sense. */
10137 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10138}
10139
10140static void
10141register_date_time_string_decodinws_error(void)
10142{
10143 static ei_register_info ei[] = {
10144 { &ei_date_time_string_decoding_failed_error,
10145 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10146 "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)}}
10147 }
10148 },
10149 };
10150
10151 expert_module_t* expert_date_time_string_decoding_error;
10152
10153 proto_date_time_string_decoding_error =
10154 proto_register_protocol("Date and Time-String Decoding Error",
10155 "Date and Time-string decoding error",
10156 "_ws.date_time_string.decoding_error");
10157
10158 expert_date_time_string_decoding_error =
10159 expert_register_protocol(proto_date_time_string_decoding_error);
10160 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10161
10162 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10163 disabling them makes no sense. */
10164 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10165}
10166
10167static void
10168register_string_errors(void)
10169{
10170 static ei_register_info ei[] = {
10171 { &ei_string_trailing_characters,
10172 { "_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)}}
}
10173 },
10174 };
10175
10176 expert_module_t* expert_string_errors;
10177
10178 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10179
10180 expert_string_errors = expert_register_protocol(proto_string_errors);
10181 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10182
10183 /* "String Errors" isn't really a protocol, it's an error indication;
10184 disabling them makes no sense. */
10185 proto_set_cant_toggle(proto_string_errors);
10186}
10187
10188static void
10189register_varint_errors(void)
10190{
10191 static ei_register_info ei[] = {
10192 { &ei_varint_decoding_failed_error,
10193 { "_ws.varint.decoding_failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Varint decoding failed", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}
10194 },
10195 };
10196
10197 expert_module_t* expert_varint_errors;
10198
10199 proto_varint_errors = proto_register_protocol("Varint Errors", "Varint errors", "_ws.varint");
10200
10201 expert_varint_errors = expert_register_protocol(proto_varint_errors);
10202 expert_register_field_array(expert_varint_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10203
10204 /* "Varint Errors" isn't really a protocol, it's an error indication;
10205 disabling them makes no sense. */
10206 proto_set_cant_toggle(proto_varint_errors);
10207}
10208
10209static int
10210proto_register_field_init(header_field_info *hfinfo, const int parent)
10211{
10212
10213 tmp_fld_check_assert(hfinfo);
10214
10215 hfinfo->parent = parent;
10216 hfinfo->same_name_next = NULL((void*)0);
10217 hfinfo->same_name_prev_id = -1;
10218
10219 /* if we always add and never delete, then id == len - 1 is correct */
10220 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10221 if (!gpa_hfinfo.hfi) {
10222 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10223 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10224 /* The entry with index 0 is not used. */
10225 gpa_hfinfo.hfi[0] = NULL((void*)0);
10226 gpa_hfinfo.len = 1;
10227 } else {
10228 gpa_hfinfo.allocated_len += 1000;
10229 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10230 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10231 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10232 }
10233 }
10234 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10235 gpa_hfinfo.len++;
10236 hfinfo->id = gpa_hfinfo.len - 1;
10237
10238 /* if we have real names, enter this field in the name tree */
10239 /* Already checked in tmp_fld_check_assert */
10240 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10241 {
10242
10243 header_field_info *same_name_next_hfinfo;
10244
10245 /* We allow multiple hfinfo's to be registered under the same
10246 * abbreviation. This was done for X.25, as, depending
10247 * on whether it's modulo-8 or modulo-128 operation,
10248 * some bitfield fields may be in different bits of
10249 * a byte, and we want to be able to refer to that field
10250 * with one name regardless of whether the packets
10251 * are modulo-8 or modulo-128 packets. */
10252
10253 /* wmem_map_insert - if key is already present the previous
10254 * hfinfo with the same key/name is returned, otherwise NULL */
10255 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10256 if (same_name_hfinfo) {
10257 /* There's already a field with this name.
10258 * Put the current field *before* that field
10259 * in the list of fields with this name, Thus,
10260 * we end up with an effectively
10261 * doubly-linked-list of same-named hfinfo's,
10262 * with the head of the list (stored in the
10263 * hash) being the last seen hfinfo.
10264 */
10265 same_name_next_hfinfo =
10266 same_name_hfinfo->same_name_next;
10267
10268 hfinfo->same_name_next = same_name_next_hfinfo;
10269 if (same_name_next_hfinfo)
10270 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10271
10272 same_name_hfinfo->same_name_next = hfinfo;
10273 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10274#ifdef ENABLE_CHECK_FILTER
10275 while (same_name_hfinfo) {
10276 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10277 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", 10277
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10278 same_name_hfinfo = same_name_hfinfo->same_name_next;
10279 }
10280#endif
10281 }
10282 }
10283
10284 return hfinfo->id;
10285}
10286
10287void
10288proto_register_subtree_array(int * const *indices, const int num_indices)
10289{
10290 int i;
10291 int *const *ptr = indices;
10292
10293 /*
10294 * If we've already allocated the array of tree types, expand
10295 * it; this lets plugins such as mate add tree types after
10296 * the initial startup. (If we haven't already allocated it,
10297 * we don't allocate it; on the first pass, we just assign
10298 * ett values and keep track of how many we've assigned, and
10299 * when we're finished registering all dissectors we allocate
10300 * the array, so that we do only one allocation rather than
10301 * wasting CPU time and memory by growing the array for each
10302 * dissector that registers ett values.)
10303 */
10304 if (tree_is_expanded != NULL((void*)0)) {
10305 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10306
10307 /* set new items to 0 */
10308 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10309 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10310 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10311 }
10312
10313 /*
10314 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10315 * returning the indices through the pointers in the array whose
10316 * first element is pointed to by "indices", and update
10317 * "num_tree_types" appropriately.
10318 */
10319 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10320 if (**ptr != -1 && **ptr != 0) {
10321 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.")
10322 " 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.")
10323 " 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.")
10324 " 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.")
;
10325 }
10326 **ptr = num_tree_types;
10327 }
10328}
10329
10330static void
10331mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10332{
10333 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10334 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10335 char *last_char;
10336
10337 /* ..... field_name: dataaaaaaaaaaaaa
10338 * |
10339 * ^^^^^ name_pos
10340 *
10341 * ..... field_name […]: dataaaaaaaaaaaaa
10342 *
10343 * name_pos==0 means that we have only data or only a field_name
10344 */
10345
10346 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10346, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10347
10348 if (name_pos >= size - trunc_len) {
10349 /* No room for trunc_str after the field_name, put it first. */
10350 name_pos = 0;
10351 }
10352
10353 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10354 if (name_pos == 0) {
10355 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10356 memcpy(label_str, trunc_str + 1, trunc_len);
10357 } else {
10358 memcpy(label_str + name_pos, trunc_str, trunc_len);
10359 }
10360 /* in general, label_str is UTF-8
10361 we can truncate it only at the beginning of a new character
10362 we go backwards from the byte right after our buffer and
10363 find the next starting byte of a UTF-8 character, this is
10364 where we cut
10365 there's no need to use g_utf8_find_prev_char(), the search
10366 will always succeed since we copied trunc_str into the
10367 buffer */
10368 /* g_utf8_prev_char does not deference the memory address
10369 * passed in (until after decrementing it, so it is perfectly
10370 * legal to pass in a pointer one past the last element.
10371 */
10372 last_char = g_utf8_prev_char(label_str + size);
10373 *last_char = '\0';
10374 /* This is unnecessary (above always terminates), but try to
10375 * convince Coverity to avoid dozens of false positives. */
10376 label_str[size - 1] = '\0';
10377
10378 if (value_pos && *value_pos > 0) {
10379 if (name_pos == 0) {
10380 *value_pos += trunc_len;
10381 } else {
10382 /* Move one back to include trunc_str in the value. */
10383 *value_pos -= 1;
10384 }
10385 }
10386
10387 /* Check if value_pos is past label_str. */
10388 if (value_pos && *value_pos >= size) {
10389 *value_pos = size - 1;
10390 }
10391}
10392
10393static void
10394label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10395{
10396 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10397}
10398
10399static size_t
10400label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10401{
10402 size_t name_pos;
10403
10404 /* "%s: %s", hfinfo->name, text */
10405 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)
;
10406 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10407 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10408 if (value_pos) {
10409 *value_pos = pos;
10410 }
10411 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10412 }
10413
10414 if (pos >= ITEM_LABEL_LENGTH240) {
10415 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10416 label_mark_truncated(label_str, name_pos, value_pos);
10417 }
10418
10419 return pos;
10420}
10421
10422static size_t
10423label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10424{
10425 size_t name_pos;
10426
10427 /* "%s: %s (%s)", hfinfo->name, text, descr */
10428 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)
;
10429 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10430 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10431 if (value_pos) {
10432 *value_pos = pos;
10433 }
10434 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10435 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)
;
10436 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)
;
10437 } else {
10438 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)
;
10439 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10440 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)
;
10441 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10442 }
10443 }
10444
10445 if (pos >= ITEM_LABEL_LENGTH240) {
10446 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10447 label_mark_truncated(label_str, name_pos, value_pos);
10448 }
10449
10450 return pos;
10451}
10452
10453void
10454proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10455{
10456 const header_field_info *hfinfo;
10457 const char *str;
10458 const uint8_t *bytes;
10459 uint32_t integer;
10460 const ipv4_addr_and_mask *ipv4;
10461 const ipv6_addr_and_prefix *ipv6;
10462 const e_guid_t *guid;
10463 char *name;
10464 address addr;
10465 char *addr_str;
10466 char *tmp;
10467
10468 if (!label_str) {
10469 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10469, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10470 return;
10471 }
10472
10473 label_str[0]= '\0';
10474
10475 if (!fi) {
10476 return;
10477 }
10478
10479 hfinfo = fi->hfinfo;
10480
10481 switch (hfinfo->type) {
10482 case FT_NONE:
10483 case FT_PROTOCOL:
10484 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10485 if (value_pos) {
10486 *value_pos = strlen(hfinfo->name);
10487 }
10488 break;
10489
10490 case FT_BOOLEAN:
10491 fill_label_boolean(fi, label_str, value_pos);
10492 break;
10493
10494 case FT_BYTES:
10495 case FT_UINT_BYTES:
10496 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10497 fvalue_get_bytes_data(fi->value),
10498 (unsigned)fvalue_length2(fi->value));
10499 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10500 wmem_free(NULL((void*)0), tmp);
10501 break;
10502
10503 case FT_CHAR:
10504 if (hfinfo->bitmask) {
10505 fill_label_bitfield_char(fi, label_str, value_pos);
10506 } else {
10507 fill_label_char(fi, label_str, value_pos);
10508 }
10509 break;
10510
10511 /* Four types of integers to take care of:
10512 * Bitfield, with val_string
10513 * Bitfield, w/o val_string
10514 * Non-bitfield, with val_string
10515 * Non-bitfield, w/o val_string
10516 */
10517 case FT_UINT8:
10518 case FT_UINT16:
10519 case FT_UINT24:
10520 case FT_UINT32:
10521 if (hfinfo->bitmask) {
10522 fill_label_bitfield(fi, label_str, value_pos, false0);
10523 } else {
10524 fill_label_number(fi, label_str, value_pos, false0);
10525 }
10526 break;
10527
10528 case FT_FRAMENUM:
10529 fill_label_number(fi, label_str, value_pos, false0);
10530 break;
10531
10532 case FT_UINT40:
10533 case FT_UINT48:
10534 case FT_UINT56:
10535 case FT_UINT64:
10536 if (hfinfo->bitmask) {
10537 fill_label_bitfield64(fi, label_str, value_pos, false0);
10538 } else {
10539 fill_label_number64(fi, label_str, value_pos, false0);
10540 }
10541 break;
10542
10543 case FT_INT8:
10544 case FT_INT16:
10545 case FT_INT24:
10546 case FT_INT32:
10547 if (hfinfo->bitmask) {
10548 fill_label_bitfield(fi, label_str, value_pos, true1);
10549 } else {
10550 fill_label_number(fi, label_str, value_pos, true1);
10551 }
10552 break;
10553
10554 case FT_INT40:
10555 case FT_INT48:
10556 case FT_INT56:
10557 case FT_INT64:
10558 if (hfinfo->bitmask) {
10559 fill_label_bitfield64(fi, label_str, value_pos, true1);
10560 } else {
10561 fill_label_number64(fi, label_str, value_pos, true1);
10562 }
10563 break;
10564
10565 case FT_FLOAT:
10566 case FT_DOUBLE:
10567 fill_label_float(fi, label_str, value_pos);
10568 break;
10569
10570 case FT_ABSOLUTE_TIME:
10571 {
10572 const nstime_t *value = fvalue_get_time(fi->value);
10573 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10574 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10575 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10576 }
10577 if (hfinfo->strings) {
10578 /*
10579 * Table of time values to be displayed
10580 * specially.
10581 *
10582 * XXX - Initializing these time_value_strings can be a pain
10583 * because the special times usually have special values in
10584 * the original encoding, not when converted to a nstime_t
10585 * relative to the UN*X epoch.
10586 */
10587 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10588 if (time_string != NULL((void*)0)) {
10589 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10590 break;
10591 }
10592 }
10593 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10594 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10595 wmem_free(NULL((void*)0), tmp);
10596 break;
10597 }
10598 case FT_RELATIVE_TIME:
10599 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10600 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10601 wmem_free(NULL((void*)0), tmp);
10602 break;
10603
10604 case FT_IPXNET:
10605 integer = fvalue_get_uinteger(fi->value);
10606 tmp = get_ipxnet_name(NULL((void*)0), integer);
10607 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10608 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10609 wmem_free(NULL((void*)0), tmp);
10610 wmem_free(NULL((void*)0), addr_str);
10611 break;
10612
10613 case FT_VINES:
10614 addr.type = AT_VINES;
10615 addr.len = VINES_ADDR_LEN6;
10616 addr.data = fvalue_get_bytes_data(fi->value);
10617
10618 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10619 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10620 wmem_free(NULL((void*)0), addr_str);
10621 break;
10622
10623 case FT_ETHER:
10624 bytes = fvalue_get_bytes_data(fi->value);
10625
10626 addr.type = AT_ETHER;
10627 addr.len = 6;
10628 addr.data = bytes;
10629
10630 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10631 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10632 wmem_free(NULL((void*)0), addr_str);
10633 break;
10634
10635 case FT_IPv4:
10636 ipv4 = fvalue_get_ipv4(fi->value);
10637 set_address_ipv4(&addr, ipv4);
10638
10639 if (hfinfo->display == BASE_NETMASK) {
10640 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10641 } else {
10642 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10643 }
10644 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10645 wmem_free(NULL((void*)0), addr_str);
10646 free_address(&addr);
10647 break;
10648
10649 case FT_IPv6:
10650 ipv6 = fvalue_get_ipv6(fi->value);
10651 set_address_ipv6(&addr, ipv6);
10652
10653 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10654 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10655 wmem_free(NULL((void*)0), addr_str);
10656 free_address(&addr);
10657 break;
10658
10659 case FT_FCWWN:
10660 bytes = fvalue_get_bytes_data(fi->value);
10661 addr.type = AT_FCWWN;
10662 addr.len = FCWWN_ADDR_LEN8;
10663 addr.data = bytes;
10664
10665 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10666 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10667 wmem_free(NULL((void*)0), addr_str);
10668 break;
10669
10670 case FT_GUID:
10671 guid = fvalue_get_guid(fi->value);
10672 tmp = guid_to_str(NULL((void*)0), guid);
10673 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10674 wmem_free(NULL((void*)0), tmp);
10675 break;
10676
10677 case FT_OID:
10678 bytes = fvalue_get_bytes_data(fi->value);
10679 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10680 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10681 if (name) {
10682 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10683 wmem_free(NULL((void*)0), name);
10684 } else {
10685 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10686 }
10687 wmem_free(NULL((void*)0), tmp);
10688 break;
10689
10690 case FT_REL_OID:
10691 bytes = fvalue_get_bytes_data(fi->value);
10692 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10693 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10694 if (name) {
10695 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10696 wmem_free(NULL((void*)0), name);
10697 } else {
10698 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10699 }
10700 wmem_free(NULL((void*)0), tmp);
10701 break;
10702
10703 case FT_SYSTEM_ID:
10704 bytes = fvalue_get_bytes_data(fi->value);
10705 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10706 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10707 wmem_free(NULL((void*)0), tmp);
10708 break;
10709
10710 case FT_EUI64:
10711 bytes = fvalue_get_bytes_data(fi->value);
10712 addr.type = AT_EUI64;
10713 addr.len = EUI64_ADDR_LEN8;
10714 addr.data = bytes;
10715
10716 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10717 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10718 wmem_free(NULL((void*)0), addr_str);
10719 break;
10720 case FT_STRING:
10721 case FT_STRINGZ:
10722 case FT_UINT_STRING:
10723 case FT_STRINGZPAD:
10724 case FT_STRINGZTRUNC:
10725 case FT_AX25:
10726 str = fvalue_get_string(fi->value);
10727 label_fill(label_str, 0, hfinfo, str, value_pos);
10728 break;
10729
10730 case FT_IEEE_11073_SFLOAT:
10731 case FT_IEEE_11073_FLOAT:
10732 fill_label_ieee_11073_float(fi, label_str, value_pos);
10733 break;
10734
10735 default:
10736 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
))
10737 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
))
10738 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
))
10739 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
))
;
10740 break;
10741 }
10742}
10743
10744static void
10745fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10746{
10747 char *p;
10748 unsigned bitfield_byte_length = 0;
10749 int bitwidth;
10750 uint64_t unshifted_value;
10751 uint64_t value;
10752
10753 const header_field_info *hfinfo = fi->hfinfo;
10754
10755 value = fvalue_get_uinteger64(fi->value);
10756 if (hfinfo->bitmask) {
10757 /* Figure out the bit width */
10758 bitwidth = hfinfo_container_bitwidth(hfinfo);
10759
10760 /* Un-shift bits */
10761 unshifted_value = value;
10762 unshifted_value <<= hfinfo_bitshift(hfinfo);
10763
10764 /* Create the bitfield first */
10765 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10766 bitfield_byte_length = (unsigned) (p - label_str);
10767 }
10768
10769 /* Fill in the textual info */
10770 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10771}
10772
10773static const char *
10774hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10775{
10776 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10777 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10778
10779 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10780 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10781 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10782 else
10783 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10784 }
10785
10786 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10787 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10788
10789 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10790 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10791
10792 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10793}
10794
10795static const char *
10796hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10797{
10798 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10799 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10800 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10801 else
10802 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10803 }
10804
10805 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10806 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10807
10808 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10809 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10810
10811 /* If this is reached somebody registered a 64-bit field with a 32-bit
10812 * value-string, which isn't right. */
10813 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)
10814 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10815
10816 /* This is necessary to squelch MSVC errors; is there
10817 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10818 never returns? */
10819 return NULL((void*)0);
10820}
10821
10822static const char *
10823hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10824{
10825 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10826 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10827
10828 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)
;
10829
10830 /* This is necessary to squelch MSVC errors; is there
10831 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10832 never returns? */
10833 return NULL((void*)0);
10834}
10835
10836static const char *
10837hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10838{
10839 const char *str = hf_try_val_to_str(value, hfinfo);
10840
10841 return (str) ? str : unknown_str;
10842}
10843
10844static const char *
10845hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10846{
10847 const char *str = hf_try_val64_to_str(value, hfinfo);
10848
10849 return (str) ? str : unknown_str;
10850}
10851
10852/* Fills data for bitfield chars with val_strings */
10853static void
10854fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10855{
10856 char *p;
10857 unsigned bitfield_byte_length;
10858 int bitwidth;
10859 uint32_t unshifted_value;
10860 uint32_t value;
10861
10862 char buf[32];
10863 const char *out;
10864
10865 const header_field_info *hfinfo = fi->hfinfo;
10866
10867 /* Figure out the bit width */
10868 bitwidth = hfinfo_container_bitwidth(hfinfo);
10869
10870 /* Un-shift bits */
10871 value = fvalue_get_uinteger(fi->value);
10872
10873 unshifted_value = value;
10874 if (hfinfo->bitmask) {
10875 unshifted_value <<= hfinfo_bitshift(hfinfo);
10876 }
10877
10878 /* Create the bitfield first */
10879 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10880 bitfield_byte_length = (unsigned) (p - label_str);
10881
10882 /* Fill in the textual info using stored (shifted) value */
10883 if (hfinfo->display == BASE_CUSTOM) {
10884 char tmp[ITEM_LABEL_LENGTH240];
10885 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10886
10887 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10887, "fmtfunc"))))
;
10888 fmtfunc(tmp, value);
10889 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10890 }
10891 else if (hfinfo->strings) {
10892 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10893
10894 out = hfinfo_char_vals_format(hfinfo, buf, value);
10895 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10896 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10897 else
10898 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10899 }
10900 else {
10901 out = hfinfo_char_value_format(hfinfo, buf, value);
10902
10903 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10904 }
10905}
10906
10907/* Fills data for bitfield ints with val_strings */
10908static void
10909fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10910{
10911 char *p;
10912 unsigned bitfield_byte_length;
10913 int bitwidth;
10914 uint32_t value, unshifted_value;
10915 char buf[NUMBER_LABEL_LENGTH80];
10916 const char *out;
10917
10918 const header_field_info *hfinfo = fi->hfinfo;
10919
10920 /* Figure out the bit width */
10921 if (fi->flags & FI_VARINT0x00040000)
10922 bitwidth = fi->length*8;
10923 else
10924 bitwidth = hfinfo_container_bitwidth(hfinfo);
10925
10926 /* Un-shift bits */
10927 if (is_signed)
10928 value = fvalue_get_sinteger(fi->value);
10929 else
10930 value = fvalue_get_uinteger(fi->value);
10931
10932 unshifted_value = value;
10933 if (hfinfo->bitmask) {
10934 unshifted_value <<= hfinfo_bitshift(hfinfo);
10935 }
10936
10937 /* Create the bitfield first */
10938 if (fi->flags & FI_VARINT0x00040000)
10939 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10940 else
10941 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10942 bitfield_byte_length = (unsigned) (p - label_str);
10943
10944 /* Fill in the textual info using stored (shifted) value */
10945 if (hfinfo->display == BASE_CUSTOM) {
10946 char tmp[ITEM_LABEL_LENGTH240];
10947 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10948
10949 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10949, "fmtfunc"))))
;
10950 fmtfunc(tmp, value);
10951 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10952 }
10953 else if (hfinfo->strings) {
10954 const char *val_str = hf_try_val_to_str(value, hfinfo);
10955
10956 out = hfinfo_number_vals_format(hfinfo, buf, value);
10957 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10958 /*
10959 * Unique values only display value_string string
10960 * if there is a match. Otherwise it's just a number
10961 */
10962 if (val_str) {
10963 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10964 } else {
10965 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10966 }
10967 } else {
10968 if (val_str == NULL((void*)0))
10969 val_str = "Unknown";
10970
10971 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10972 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10973 else
10974 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10975 }
10976 }
10977 else {
10978 out = hfinfo_number_value_format(hfinfo, buf, value);
10979
10980 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10981 }
10982}
10983
10984static void
10985fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10986{
10987 char *p;
10988 unsigned bitfield_byte_length;
10989 int bitwidth;
10990 uint64_t value, unshifted_value;
10991 char buf[NUMBER_LABEL_LENGTH80];
10992 const char *out;
10993
10994 const header_field_info *hfinfo = fi->hfinfo;
10995
10996 /* Figure out the bit width */
10997 if (fi->flags & FI_VARINT0x00040000)
10998 bitwidth = fi->length*8;
10999 else
11000 bitwidth = hfinfo_container_bitwidth(hfinfo);
11001
11002 /* Un-shift bits */
11003 if (is_signed)
11004 value = fvalue_get_sinteger64(fi->value);
11005 else
11006 value = fvalue_get_uinteger64(fi->value);
11007
11008 unshifted_value = value;
11009 if (hfinfo->bitmask) {
11010 unshifted_value <<= hfinfo_bitshift(hfinfo);
11011 }
11012
11013 /* Create the bitfield first */
11014 if (fi->flags & FI_VARINT0x00040000)
11015 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11016 else
11017 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11018 bitfield_byte_length = (unsigned) (p - label_str);
11019
11020 /* Fill in the textual info using stored (shifted) value */
11021 if (hfinfo->display == BASE_CUSTOM) {
11022 char tmp[ITEM_LABEL_LENGTH240];
11023 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11024
11025 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11025, "fmtfunc64"
))))
;
11026 fmtfunc64(tmp, value);
11027 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
11028 }
11029 else if (hfinfo->strings) {
11030 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11031
11032 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11033 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11034 /*
11035 * Unique values only display value_string string
11036 * if there is a match. Otherwise it's just a number
11037 */
11038 if (val_str) {
11039 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11040 } else {
11041 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11042 }
11043 } else {
11044 if (val_str == NULL((void*)0))
11045 val_str = "Unknown";
11046
11047 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11048 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
11049 else
11050 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11051 }
11052 }
11053 else {
11054 out = hfinfo_number_value_format64(hfinfo, buf, value);
11055
11056 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11057 }
11058}
11059
11060static void
11061fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
11062{
11063 const header_field_info *hfinfo = fi->hfinfo;
11064 uint32_t value;
11065
11066 char buf[32];
11067 const char *out;
11068
11069 value = fvalue_get_uinteger(fi->value);
11070
11071 /* Fill in the textual info */
11072 if (hfinfo->display == BASE_CUSTOM) {
11073 char tmp[ITEM_LABEL_LENGTH240];
11074 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11075
11076 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11076, "fmtfunc"))))
;
11077 fmtfunc(tmp, value);
11078 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11079 }
11080 else if (hfinfo->strings) {
11081 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
11082
11083 out = hfinfo_char_vals_format(hfinfo, buf, value);
11084 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11085 }
11086 else {
11087 out = hfinfo_char_value_format(hfinfo, buf, value);
11088
11089 label_fill(label_str, 0, hfinfo, out, value_pos);
11090 }
11091}
11092
11093static void
11094fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11095{
11096 const header_field_info *hfinfo = fi->hfinfo;
11097 uint32_t value;
11098
11099 char buf[NUMBER_LABEL_LENGTH80];
11100 const char *out;
11101
11102 if (is_signed)
11103 value = fvalue_get_sinteger(fi->value);
11104 else
11105 value = fvalue_get_uinteger(fi->value);
11106
11107 /* Fill in the textual info */
11108 if (hfinfo->display == BASE_CUSTOM) {
11109 char tmp[ITEM_LABEL_LENGTH240];
11110 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11111
11112 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11112, "fmtfunc"))))
;
11113 fmtfunc(tmp, value);
11114 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11115 }
11116 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
11117 /*
11118 * It makes no sense to have a value-string table for a
11119 * frame-number field - they're just integers giving
11120 * the ordinal frame number.
11121 */
11122 const char *val_str = hf_try_val_to_str(value, hfinfo);
11123
11124 out = hfinfo_number_vals_format(hfinfo, buf, value);
11125 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11126 /*
11127 * Unique values only display value_string string
11128 * if there is a match. Otherwise it's just a number
11129 */
11130 if (val_str) {
11131 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11132 } else {
11133 label_fill(label_str, 0, hfinfo, out, value_pos);
11134 }
11135 } else {
11136 if (val_str == NULL((void*)0))
11137 val_str = "Unknown";
11138
11139 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11140 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11141 else
11142 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11143 }
11144 }
11145 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
))
) {
11146 char tmp[ITEM_LABEL_LENGTH240];
11147
11148 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11149 display_to_port_type((field_display_e)hfinfo->display), value);
11150 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11151 }
11152 else {
11153 out = hfinfo_number_value_format(hfinfo, buf, value);
11154
11155 label_fill(label_str, 0, hfinfo, out, value_pos);
11156 }
11157}
11158
11159static void
11160fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11161{
11162 const header_field_info *hfinfo = fi->hfinfo;
11163 uint64_t value;
11164
11165 char buf[NUMBER_LABEL_LENGTH80];
11166 const char *out;
11167
11168 if (is_signed)
11169 value = fvalue_get_sinteger64(fi->value);
11170 else
11171 value = fvalue_get_uinteger64(fi->value);
11172
11173 /* Fill in the textual info */
11174 if (hfinfo->display == BASE_CUSTOM) {
11175 char tmp[ITEM_LABEL_LENGTH240];
11176 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11177
11178 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11178, "fmtfunc64"
))))
;
11179 fmtfunc64(tmp, value);
11180 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11181 }
11182 else if (hfinfo->strings) {
11183 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11184
11185 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11186 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11187 /*
11188 * Unique values only display value_string string
11189 * if there is a match. Otherwise it's just a number
11190 */
11191 if (val_str) {
11192 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11193 } else {
11194 label_fill(label_str, 0, hfinfo, out, value_pos);
11195 }
11196 } else {
11197 if (val_str == NULL((void*)0))
11198 val_str = "Unknown";
11199
11200 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11201 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11202 else
11203 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11204 }
11205 }
11206 else {
11207 out = hfinfo_number_value_format64(hfinfo, buf, value);
11208
11209 label_fill(label_str, 0, hfinfo, out, value_pos);
11210 }
11211}
11212
11213static size_t
11214fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11215{
11216 int display;
11217 int n;
11218 double value;
11219
11220 if (label_str_size < 12) {
11221 /* Not enough room to write an entire floating point value. */
11222 return 0;
11223 }
11224
11225 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11226 value = fvalue_get_floating(fi->value);
11227
11228 if (display == BASE_CUSTOM) {
11229 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11230 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11230, "fmtfunc"))))
;
11231 fmtfunc(label_str, value);
11232 return strlen(label_str);
11233 }
11234
11235 switch (display) {
11236 case BASE_NONE:
11237 if (fi->hfinfo->type == FT_FLOAT) {
11238 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11239 } else {
11240 n = (int)strlen(dtoa_g_fmt(label_str, value));
11241 }
11242 break;
11243 case BASE_DEC:
11244 n = snprintf(label_str, label_str_size, "%f", value);
11245 break;
11246 case BASE_HEX:
11247 n = snprintf(label_str, label_str_size, "%a", value);
11248 break;
11249 case BASE_EXP:
11250 n = snprintf(label_str, label_str_size, "%e", value);
11251 break;
11252 default:
11253 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11253
, __func__, "assertion \"not reached\" failed")
;
11254 }
11255 if (n < 0) {
11256 return 0; /* error */
11257 }
11258 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11259 const char *hf_str_val;
11260 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11261 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11262 }
11263 if (n > label_str_size) {
11264 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11264, __func__, "label length too small"); } } while (0)
;
11265 return strlen(label_str);
11266 }
11267
11268 return n;
11269}
11270
11271void
11272fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11273{
11274 char tmp[ITEM_LABEL_LENGTH240];
11275
11276 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11277 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11278}
11279
11280static size_t
11281fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11282{
11283 int display;
11284 size_t pos = 0;
11285 double value;
11286 char* tmp_str;
11287
11288 if (label_str_size < 12) {
11289 /* Not enough room to write an entire floating point value. */
11290 return 0;
11291 }
11292
11293 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11294 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11295 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11296 wmem_free(NULL((void*)0), tmp_str);
11297
11298 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11299 const char *hf_str_val;
11300 fvalue_to_double(fi->value, &value);
11301 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11302 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)
;
11303 }
11304 if ((int)pos > label_str_size) {
11305 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11305, __func__, "label length too small"); } } while (0)
;
11306 return strlen(label_str);
11307 }
11308
11309 return pos;
11310}
11311
11312void
11313fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11314{
11315 char tmp[ITEM_LABEL_LENGTH240];
11316
11317 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11318 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11319}
11320
11321int
11322hfinfo_bitshift(const header_field_info *hfinfo)
11323{
11324 return ws_ctz(hfinfo->bitmask);
11325}
11326
11327
11328static int
11329hfinfo_bitoffset(const header_field_info *hfinfo)
11330{
11331 if (!hfinfo->bitmask) {
11332 return 0;
11333 }
11334
11335 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11336 * as the first bit */
11337 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11338}
11339
11340static int
11341hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11342{
11343 if (!hfinfo->bitmask) {
11344 return 0;
11345 }
11346
11347 /* ilog2 = first set bit, ctz = last set bit */
11348 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11349}
11350
11351static int
11352hfinfo_type_bitwidth(enum ftenum type)
11353{
11354 int bitwidth = 0;
11355
11356 switch (type) {
11357 case FT_CHAR:
11358 case FT_UINT8:
11359 case FT_INT8:
11360 bitwidth = 8;
11361 break;
11362 case FT_UINT16:
11363 case FT_INT16:
11364 bitwidth = 16;
11365 break;
11366 case FT_UINT24:
11367 case FT_INT24:
11368 bitwidth = 24;
11369 break;
11370 case FT_UINT32:
11371 case FT_INT32:
11372 bitwidth = 32;
11373 break;
11374 case FT_UINT40:
11375 case FT_INT40:
11376 bitwidth = 40;
11377 break;
11378 case FT_UINT48:
11379 case FT_INT48:
11380 bitwidth = 48;
11381 break;
11382 case FT_UINT56:
11383 case FT_INT56:
11384 bitwidth = 56;
11385 break;
11386 case FT_UINT64:
11387 case FT_INT64:
11388 bitwidth = 64;
11389 break;
11390 default:
11391 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11391))
;
11392 ;
11393 }
11394 return bitwidth;
11395}
11396
11397
11398static int
11399hfinfo_container_bitwidth(const header_field_info *hfinfo)
11400{
11401 if (!hfinfo->bitmask) {
11402 return 0;
11403 }
11404
11405 if (hfinfo->type == FT_BOOLEAN) {
11406 return hfinfo->display; /* hacky? :) */
11407 }
11408
11409 return hfinfo_type_bitwidth(hfinfo->type);
11410}
11411
11412static int
11413hfinfo_hex_digits(const header_field_info *hfinfo)
11414{
11415 int bitwidth;
11416
11417 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11418 * appropriate to determine the number of hex digits for the field.
11419 * So instead, we compute it from the bitmask.
11420 */
11421 if (hfinfo->bitmask != 0) {
11422 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11423 } else {
11424 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11425 }
11426
11427 /* Divide by 4, rounding up, to get number of hex digits. */
11428 return (bitwidth + 3) / 4;
11429}
11430
11431const char *
11432hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11433{
11434 char *ptr = &buf[6];
11435 static const char hex_digits[16] =
11436 { '0', '1', '2', '3', '4', '5', '6', '7',
11437 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11438
11439 *ptr = '\0';
11440 *(--ptr) = '\'';
11441 /* Properly format value */
11442 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11443 /*
11444 * Printable, so just show the character, and, if it needs
11445 * to be escaped, escape it.
11446 */
11447 *(--ptr) = value;
11448 if (value == '\\' || value == '\'')
11449 *(--ptr) = '\\';
11450 } else {
11451 /*
11452 * Non-printable; show it as an escape sequence.
11453 */
11454 switch (value) {
11455
11456 case '\0':
11457 /*
11458 * Show a NUL with only one digit.
11459 */
11460 *(--ptr) = '0';
11461 break;
11462
11463 case '\a':
11464 case '\b':
11465 case '\f':
11466 case '\n':
11467 case '\r':
11468 case '\t':
11469 case '\v':
11470 *(--ptr) = value - '\a' + 'a';
11471 break;
11472
11473 default:
11474 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11475
11476 case BASE_OCT:
11477 *(--ptr) = (value & 0x7) + '0';
11478 value >>= 3;
11479 *(--ptr) = (value & 0x7) + '0';
11480 value >>= 3;
11481 *(--ptr) = (value & 0x7) + '0';
11482 break;
11483
11484 case BASE_HEX:
11485 *(--ptr) = hex_digits[value & 0x0F];
11486 value >>= 4;
11487 *(--ptr) = hex_digits[value & 0x0F];
11488 *(--ptr) = 'x';
11489 break;
11490
11491 default:
11492 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11493 }
11494 }
11495 *(--ptr) = '\\';
11496 }
11497 *(--ptr) = '\'';
11498 return ptr;
11499}
11500
11501static const char *
11502hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11503{
11504 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11505 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
))
;
11506
11507 *ptr = '\0';
11508 /* Properly format value */
11509 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11510 case BASE_DEC:
11511 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11512
11513 case BASE_DEC_HEX:
11514 *(--ptr) = ')';
11515 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11516 *(--ptr) = '(';
11517 *(--ptr) = ' ';
11518 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11519 return ptr;
11520
11521 case BASE_OCT:
11522 return oct_to_str_back(ptr, value);
11523
11524 case BASE_HEX:
11525 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11526
11527 case BASE_HEX_DEC:
11528 *(--ptr) = ')';
11529 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11530 *(--ptr) = '(';
11531 *(--ptr) = ' ';
11532 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11533 return ptr;
11534
11535 case BASE_PT_UDP:
11536 case BASE_PT_TCP:
11537 case BASE_PT_DCCP:
11538 case BASE_PT_SCTP:
11539 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11540 display_to_port_type((field_display_e)display), value);
11541 return buf;
11542 case BASE_OUI:
11543 {
11544 uint8_t p_oui[3];
11545 const char *manuf_name;
11546
11547 p_oui[0] = value >> 16 & 0xFF;
11548 p_oui[1] = value >> 8 & 0xFF;
11549 p_oui[2] = value & 0xFF;
11550
11551 /* Attempt an OUI lookup. */
11552 manuf_name = uint_get_manuf_name_if_known(value);
11553 if (manuf_name == NULL((void*)0)) {
11554 /* Could not find an OUI. */
11555 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11556 }
11557 else {
11558 /* Found an address string. */
11559 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11560 }
11561 return buf;
11562 }
11563
11564 default:
11565 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11566 }
11567 return ptr;
11568}
11569
11570static const char *
11571hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11572{
11573 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11574 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
))
;
11575
11576 *ptr = '\0';
11577 /* Properly format value */
11578 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11579 case BASE_DEC:
11580 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11581
11582 case BASE_DEC_HEX:
11583 *(--ptr) = ')';
11584 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11585 *(--ptr) = '(';
11586 *(--ptr) = ' ';
11587 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11588 return ptr;
11589
11590 case BASE_OCT:
11591 return oct64_to_str_back(ptr, value);
11592
11593 case BASE_HEX:
11594 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11595
11596 case BASE_HEX_DEC:
11597 *(--ptr) = ')';
11598 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11599 *(--ptr) = '(';
11600 *(--ptr) = ' ';
11601 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11602 return ptr;
11603
11604 default:
11605 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11606 }
11607
11608 return ptr;
11609}
11610
11611static const char *
11612hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11613{
11614 int display = hfinfo->display;
11615
11616 if (hfinfo->type == FT_FRAMENUM) {
11617 /*
11618 * Frame numbers are always displayed in decimal.
11619 */
11620 display = BASE_DEC;
11621 }
11622
11623 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11624}
11625
11626static const char *
11627hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11628{
11629 int display = hfinfo->display;
11630
11631 if (hfinfo->type == FT_FRAMENUM) {
11632 /*
11633 * Frame numbers are always displayed in decimal.
11634 */
11635 display = BASE_DEC;
11636 }
11637
11638 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11639}
11640
11641static const char *
11642hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11643{
11644 /* Get the underlying BASE_ value */
11645 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11646
11647 return hfinfo_char_value_format_display(display, buf, value);
11648}
11649
11650static const char *
11651hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11652{
11653 /* Get the underlying BASE_ value */
11654 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11655
11656 if (hfinfo->type == FT_FRAMENUM) {
11657 /*
11658 * Frame numbers are always displayed in decimal.
11659 */
11660 display = BASE_DEC;
11661 }
11662
11663 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11664 display = BASE_DEC;
11665 } else if (display == BASE_OUI) {
11666 display = BASE_HEX;
11667 }
11668
11669 switch (display) {
11670 case BASE_NONE:
11671 /* case BASE_DEC: */
11672 case BASE_DEC_HEX:
11673 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11674 case BASE_CUSTOM:
11675 display = BASE_DEC;
11676 break;
11677
11678 /* case BASE_HEX: */
11679 case BASE_HEX_DEC:
11680 display = BASE_HEX;
11681 break;
11682 }
11683
11684 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11685}
11686
11687static const char *
11688hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11689{
11690 /* Get the underlying BASE_ value */
11691 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11692
11693 if (hfinfo->type == FT_FRAMENUM) {
11694 /*
11695 * Frame numbers are always displayed in decimal.
11696 */
11697 display = BASE_DEC;
11698 }
11699
11700 switch (display) {
11701 case BASE_NONE:
11702 /* case BASE_DEC: */
11703 case BASE_DEC_HEX:
11704 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11705 case BASE_CUSTOM:
11706 display = BASE_DEC;
11707 break;
11708
11709 /* case BASE_HEX: */
11710 case BASE_HEX_DEC:
11711 display = BASE_HEX;
11712 break;
11713 }
11714
11715 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11716}
11717
11718static const char *
11719hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11720{
11721 /* Get the underlying BASE_ value */
11722 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11723
11724 return hfinfo_char_value_format_display(display, buf, value);
11725}
11726
11727static const char *
11728hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11729{
11730 /* Get the underlying BASE_ value */
11731 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11732
11733 if (display == BASE_NONE)
11734 return NULL((void*)0);
11735
11736 if (display == BASE_DEC_HEX)
11737 display = BASE_DEC;
11738 if (display == BASE_HEX_DEC)
11739 display = BASE_HEX;
11740
11741 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11742}
11743
11744static const char *
11745hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11746{
11747 /* Get the underlying BASE_ value */
11748 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11749
11750 if (display == BASE_NONE)
11751 return NULL((void*)0);
11752
11753 if (display == BASE_DEC_HEX)
11754 display = BASE_DEC;
11755 if (display == BASE_HEX_DEC)
11756 display = BASE_HEX;
11757
11758 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11759}
11760
11761const char *
11762proto_registrar_get_name(const int n)
11763{
11764 header_field_info *hfinfo;
11765
11766 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", 11766
, __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", 11766
, "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", 11766, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11767 return hfinfo->name;
11768}
11769
11770const char *
11771proto_registrar_get_abbrev(const int n)
11772{
11773 header_field_info *hfinfo;
11774
11775 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", 11775
, __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", 11775
, "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", 11775, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11776 return hfinfo->abbrev;
11777}
11778
11779enum ftenum
11780proto_registrar_get_ftype(const int n)
11781{
11782 header_field_info *hfinfo;
11783
11784 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", 11784
, __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", 11784
, "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", 11784, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11785 return hfinfo->type;
11786}
11787
11788int
11789proto_registrar_get_parent(const int n)
11790{
11791 header_field_info *hfinfo;
11792
11793 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", 11793
, __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", 11793
, "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", 11793, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11794 return hfinfo->parent;
11795}
11796
11797bool_Bool
11798proto_registrar_is_protocol(const int n)
11799{
11800 header_field_info *hfinfo;
11801
11802 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", 11802
, __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", 11802
, "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", 11802, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11803 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11804}
11805
11806/* Returns length of field in packet (not necessarily the length
11807 * in our internal representation, as in the case of IPv4).
11808 * 0 means undeterminable at time of registration
11809 * -1 means the field is not registered. */
11810int
11811proto_registrar_get_length(const int n)
11812{
11813 header_field_info *hfinfo;
11814
11815 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", 11815
, __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", 11815
, "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", 11815, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11816 return ftype_wire_size(hfinfo->type);
11817}
11818
11819size_t
11820proto_registrar_get_count(struct proto_registrar_stats *stats)
11821{
11822 header_field_info *hfinfo;
11823
11824 // Index zero is not used. We have to skip it.
11825 size_t total_count = gpa_hfinfo.len - 1;
11826 if (stats == NULL((void*)0)) {
11827 return total_count;
11828 }
11829 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11830 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11831 stats->deregistered_count++;
11832 continue; /* This is a deregistered protocol or header field */
11833 }
11834
11835 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", 11835
, __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", 11835, "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", 11835, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11836
11837 if (proto_registrar_is_protocol(id))
11838 stats->protocol_count++;
11839
11840 if (hfinfo->same_name_prev_id != -1)
11841 stats->same_name_count++;
11842 }
11843
11844 return total_count;
11845}
11846
11847/* Looks for a protocol or a field in a proto_tree. Returns true if
11848 * it exists anywhere, or false if it exists nowhere. */
11849bool_Bool
11850proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11851{
11852 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11853
11854 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11855 return true1;
11856 }
11857 else {
11858 return false0;
11859 }
11860}
11861
11862/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11863 * This only works if the hfindex was "primed" before the dissection
11864 * took place, as we just pass back the already-created GPtrArray*.
11865 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11866 * handles that. */
11867GPtrArray *
11868proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11869{
11870 if (!tree)
11871 return NULL((void*)0);
11872
11873 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11874 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11875 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11876 else
11877 return NULL((void*)0);
11878}
11879
11880bool_Bool
11881proto_tracking_interesting_fields(const proto_tree *tree)
11882{
11883 GHashTable *interesting_hfids;
11884
11885 if (!tree)
11886 return false0;
11887
11888 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11889
11890 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11891}
11892
11893/* Helper struct for proto_find_info() and proto_all_finfos() */
11894typedef struct {
11895 GPtrArray *array;
11896 int id;
11897} ffdata_t;
11898
11899/* Helper function for proto_find_info() */
11900static bool_Bool
11901find_finfo(proto_node *node, void * data)
11902{
11903 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11904 if (fi && fi->hfinfo) {
11905 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11906 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11907 }
11908 }
11909
11910 /* Don't stop traversing. */
11911 return false0;
11912}
11913
11914/* Helper function for proto_find_first_info() */
11915static bool_Bool
11916find_first_finfo(proto_node *node, void *data)
11917{
11918 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11919 if (fi && fi->hfinfo) {
11920 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11921 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11922
11923 /* Stop traversing. */
11924 return true1;
11925 }
11926 }
11927
11928 /* Continue traversing. */
11929 return false0;
11930}
11931
11932/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11933* This works on any proto_tree, primed or unprimed, but actually searches
11934* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11935* The caller does need to free the returned GPtrArray with
11936* g_ptr_array_free(<array>, true).
11937*/
11938GPtrArray *
11939proto_find_finfo(proto_tree *tree, const int id)
11940{
11941 ffdata_t ffdata;
11942
11943 ffdata.array = g_ptr_array_new();
11944 ffdata.id = id;
11945
11946 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11947
11948 return ffdata.array;
11949}
11950
11951/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11952* This works on any proto_tree, primed or unprimed, but actually searches
11953* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11954* The caller does need to free the returned GPtrArray with
11955* g_ptr_array_free(<array>, true).
11956*/
11957GPtrArray *
11958proto_find_first_finfo(proto_tree *tree, const int id)
11959{
11960 ffdata_t ffdata;
11961
11962 ffdata.array = g_ptr_array_new();
11963 ffdata.id = id;
11964
11965 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11966
11967 return ffdata.array;
11968}
11969
11970/* Helper function for proto_all_finfos() */
11971static bool_Bool
11972every_finfo(proto_node *node, void * data)
11973{
11974 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11975 if (fi && fi->hfinfo) {
11976 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11977 }
11978
11979 /* Don't stop traversing. */
11980 return false0;
11981}
11982
11983/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11984 * The caller does need to free the returned GPtrArray with
11985 * g_ptr_array_free(<array>, true).
11986 */
11987GPtrArray *
11988proto_all_finfos(proto_tree *tree)
11989{
11990 ffdata_t ffdata;
11991
11992 /* Pre allocate enough space to hold all fields in most cases */
11993 ffdata.array = g_ptr_array_sized_new(512);
11994 ffdata.id = 0;
11995
11996 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11997
11998 return ffdata.array;
11999}
12000
12001
12002typedef struct {
12003 unsigned offset;
12004 field_info *finfo;
12005 tvbuff_t *tvb;
12006} offset_search_t;
12007
12008static bool_Bool
12009check_for_offset(proto_node *node, void * data)
12010{
12011 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12012 offset_search_t *offsearch = (offset_search_t *)data;
12013
12014 /* !fi == the top most container node which holds nothing */
12015 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
12016 if (offsearch->offset >= (unsigned) fi->start &&
12017 offsearch->offset < (unsigned) (fi->start + fi->length)) {
12018
12019 offsearch->finfo = fi;
12020 return false0; /* keep traversing */
12021 }
12022 }
12023 return false0; /* keep traversing */
12024}
12025
12026/* Search a proto_tree backwards (from leaves to root) looking for the field
12027 * whose start/length occupies 'offset' */
12028/* XXX - I couldn't find an easy way to search backwards, so I search
12029 * forwards, w/o stopping. Therefore, the last finfo I find will the be
12030 * the one I want to return to the user. This algorithm is inefficient
12031 * and could be re-done, but I'd have to handle all the children and
12032 * siblings of each node myself. When I have more time I'll do that.
12033 * (yeah right) */
12034field_info *
12035proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
12036{
12037 offset_search_t offsearch;
12038
12039 offsearch.offset = offset;
12040 offsearch.finfo = NULL((void*)0);
12041 offsearch.tvb = tvb;
12042
12043 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
12044
12045 return offsearch.finfo;
12046}
12047
12048typedef struct {
12049 unsigned length;
12050 char *buf;
12051} decoded_data_t;
12052
12053static bool_Bool
12054check_for_undecoded(proto_node *node, void * data)
12055{
12056 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12057 decoded_data_t* decoded = (decoded_data_t*)data;
12058 unsigned i;
12059 unsigned byte;
12060 unsigned bit;
12061
12062 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
12063 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
12064 byte = i / 8;
12065 bit = i % 8;
12066 decoded->buf[byte] |= (1 << bit);
12067 }
12068 }
12069
12070 return false0;
12071}
12072
12073char*
12074proto_find_undecoded_data(proto_tree *tree, unsigned length)
12075{
12076 decoded_data_t decoded;
12077 decoded.length = length;
12078 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
12079
12080 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
12081 return decoded.buf;
12082}
12083
12084/* Dumps the protocols in the registration database to stdout. An independent
12085 * program can take this output and format it into nice tables or HTML or
12086 * whatever.
12087 *
12088 * There is one record per line. The fields are tab-delimited.
12089 *
12090 * Field 1 = protocol name
12091 * Field 2 = protocol short name
12092 * Field 3 = protocol filter name
12093 * Field 4 = protocol enabled
12094 * Field 5 = protocol enabled by default
12095 * Field 6 = protocol can toggle
12096 */
12097void
12098proto_registrar_dump_protocols(void)
12099{
12100 protocol_t *protocol;
12101 int i;
12102 void *cookie = NULL((void*)0);
12103
12104
12105 i = proto_get_first_protocol(&cookie);
12106 while (i != -1) {
12107 protocol = find_protocol_by_id(i);
12108 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
12109 protocol->name,
12110 protocol->short_name,
12111 protocol->filter_name,
12112 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
12113 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
12114 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
12115 i = proto_get_next_protocol(&cookie);
12116 }
12117}
12118
12119/* Dumps the value_strings, extended value string headers, range_strings
12120 * or true/false strings for fields that have them.
12121 * There is one record per line. Fields are tab-delimited.
12122 * There are four types of records: Value String, Extended Value String Header,
12123 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
12124 * the type of record.
12125 *
12126 * Note that a record will be generated only if the value_string,... is referenced
12127 * in a registered hfinfo entry.
12128 *
12129 *
12130 * Value Strings
12131 * -------------
12132 * Field 1 = 'V'
12133 * Field 2 = Field abbreviation to which this value string corresponds
12134 * Field 3 = Integer value
12135 * Field 4 = String
12136 *
12137 * Extended Value String Headers
12138 * -----------------------------
12139 * Field 1 = 'E'
12140 * Field 2 = Field abbreviation to which this extended value string header corresponds
12141 * Field 3 = Extended Value String "Name"
12142 * Field 4 = Number of entries in the associated value_string array
12143 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12144 *
12145 * Range Strings
12146 * -------------
12147 * Field 1 = 'R'
12148 * Field 2 = Field abbreviation to which this range string corresponds
12149 * Field 3 = Integer value: lower bound
12150 * Field 4 = Integer value: upper bound
12151 * Field 5 = String
12152 *
12153 * True/False Strings
12154 * ------------------
12155 * Field 1 = 'T'
12156 * Field 2 = Field abbreviation to which this true/false string corresponds
12157 * Field 3 = True String
12158 * Field 4 = False String
12159 */
12160void
12161proto_registrar_dump_values(void)
12162{
12163 header_field_info *hfinfo;
12164 int i, len, vi;
12165 const value_string *vals;
12166 const val64_string *vals64;
12167 const range_string *range;
12168 const true_false_string *tfs;
12169 const unit_name_string *units;
12170
12171 len = gpa_hfinfo.len;
12172 for (i = 1; i < len ; i++) {
12173 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12174 continue; /* This is a deregistered protocol or field */
12175
12176 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", 12176
, __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", 12176
, "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", 12176, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12177
12178 if (hfinfo->id == hf_text_only) {
12179 continue;
12180 }
12181
12182 /* ignore protocols */
12183 if (proto_registrar_is_protocol(i)) {
12184 continue;
12185 }
12186 /* process header fields */
12187#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12188 /*
12189 * If this field isn't at the head of the list of
12190 * fields with this name, skip this field - all
12191 * fields with the same name are really just versions
12192 * of the same field stored in different bits, and
12193 * should have the same type/radix/value list, and
12194 * just differ in their bit masks. (If a field isn't
12195 * a bitfield, but can be, say, 1 or 2 bytes long,
12196 * it can just be made FT_UINT16, meaning the
12197 * *maximum* length is 2 bytes, and be used
12198 * for all lengths.)
12199 */
12200 if (hfinfo->same_name_prev_id != -1)
12201 continue;
12202#endif
12203 vals = NULL((void*)0);
12204 vals64 = NULL((void*)0);
12205 range = NULL((void*)0);
12206 tfs = NULL((void*)0);
12207 units = NULL((void*)0);
12208
12209 if (hfinfo->strings != NULL((void*)0)) {
12210 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12211 (hfinfo->type == FT_CHAR ||
12212 hfinfo->type == FT_UINT8 ||
12213 hfinfo->type == FT_UINT16 ||
12214 hfinfo->type == FT_UINT24 ||
12215 hfinfo->type == FT_UINT32 ||
12216 hfinfo->type == FT_UINT40 ||
12217 hfinfo->type == FT_UINT48 ||
12218 hfinfo->type == FT_UINT56 ||
12219 hfinfo->type == FT_UINT64 ||
12220 hfinfo->type == FT_INT8 ||
12221 hfinfo->type == FT_INT16 ||
12222 hfinfo->type == FT_INT24 ||
12223 hfinfo->type == FT_INT32 ||
12224 hfinfo->type == FT_INT40 ||
12225 hfinfo->type == FT_INT48 ||
12226 hfinfo->type == FT_INT56 ||
12227 hfinfo->type == FT_INT64 ||
12228 hfinfo->type == FT_FLOAT ||
12229 hfinfo->type == FT_DOUBLE)) {
12230
12231 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12232 range = (const range_string *)hfinfo->strings;
12233 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12234 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12235 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12236 } else {
12237 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12238 }
12239 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12240 vals64 = (const val64_string *)hfinfo->strings;
12241 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12242 units = (const unit_name_string *)hfinfo->strings;
12243 } else {
12244 vals = (const value_string *)hfinfo->strings;
12245 }
12246 }
12247 else if (hfinfo->type == FT_BOOLEAN) {
12248 tfs = (const struct true_false_string *)hfinfo->strings;
12249 }
12250 }
12251
12252 /* Print value strings? */
12253 if (vals) {
12254 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12255 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12256 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12257 if (!val64_string_ext_validate(vse_p)) {
12258 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12258, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12259 continue;
12260 }
12261 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12262 printf("E\t%s\t%u\t%s\t%s\n",
12263 hfinfo->abbrev,
12264 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12265 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12266 val64_string_ext_match_type_str(vse_p));
12267 } else {
12268 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12269 if (!value_string_ext_validate(vse_p)) {
12270 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12270, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12271 continue;
12272 }
12273 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12274 printf("E\t%s\t%u\t%s\t%s\n",
12275 hfinfo->abbrev,
12276 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12277 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12278 value_string_ext_match_type_str(vse_p));
12279 }
12280 }
12281 vi = 0;
12282 while (vals[vi].strptr) {
12283 /* Print in the proper base */
12284 if (hfinfo->type == FT_CHAR) {
12285 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12286 printf("V\t%s\t'%c'\t%s\n",
12287 hfinfo->abbrev,
12288 vals[vi].value,
12289 vals[vi].strptr);
12290 } else {
12291 if (hfinfo->display == BASE_HEX) {
12292 printf("V\t%s\t'\\x%02x'\t%s\n",
12293 hfinfo->abbrev,
12294 vals[vi].value,
12295 vals[vi].strptr);
12296 }
12297 else {
12298 printf("V\t%s\t'\\%03o'\t%s\n",
12299 hfinfo->abbrev,
12300 vals[vi].value,
12301 vals[vi].strptr);
12302 }
12303 }
12304 } else {
12305 if (hfinfo->display == BASE_HEX) {
12306 printf("V\t%s\t0x%x\t%s\n",
12307 hfinfo->abbrev,
12308 vals[vi].value,
12309 vals[vi].strptr);
12310 }
12311 else {
12312 printf("V\t%s\t%u\t%s\n",
12313 hfinfo->abbrev,
12314 vals[vi].value,
12315 vals[vi].strptr);
12316 }
12317 }
12318 vi++;
12319 }
12320 }
12321 else if (vals64) {
12322 vi = 0;
12323 while (vals64[vi].strptr) {
12324 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12325 hfinfo->abbrev,
12326 vals64[vi].value,
12327 vals64[vi].strptr);
12328 vi++;
12329 }
12330 }
12331
12332 /* print range strings? */
12333 else if (range) {
12334 vi = 0;
12335 while (range[vi].strptr) {
12336 /* Print in the proper base */
12337 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12338 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12339 hfinfo->abbrev,
12340 range[vi].value_min,
12341 range[vi].value_max,
12342 range[vi].strptr);
12343 }
12344 else {
12345 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12346 hfinfo->abbrev,
12347 range[vi].value_min,
12348 range[vi].value_max,
12349 range[vi].strptr);
12350 }
12351 vi++;
12352 }
12353 }
12354
12355 /* Print true/false strings? */
12356 else if (tfs) {
12357 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12358 tfs->true_string, tfs->false_string);
12359 }
12360 /* Print unit strings? */
12361 else if (units) {
12362 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12363 units->singular, units->plural ? units->plural : "(no plural)");
12364 }
12365 }
12366}
12367
12368/* Prints the number of registered fields.
12369 * Useful for determining an appropriate value for
12370 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12371 *
12372 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12373 * the number of fields, true otherwise.
12374 */
12375bool_Bool
12376proto_registrar_dump_fieldcount(void)
12377{
12378 struct proto_registrar_stats stats = {0, 0, 0};
12379 size_t total_count = proto_registrar_get_count(&stats);
12380
12381 printf("There are %zu header fields registered, of which:\n"
12382 "\t%zu are deregistered\n"
12383 "\t%zu are protocols\n"
12384 "\t%zu have the same name as another field\n\n",
12385 total_count, stats.deregistered_count, stats.protocol_count,
12386 stats.same_name_count);
12387
12388 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12389 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12390 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12391 "\n");
12392
12393 printf("The header field table consumes %u KiB of memory.\n",
12394 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12395 printf("The fields themselves consume %u KiB of memory.\n",
12396 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12397
12398 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12399}
12400
12401static void
12402elastic_add_base_mapping(json_dumper *dumper)
12403{
12404 json_dumper_set_member_name(dumper, "index_patterns");
12405 json_dumper_begin_array(dumper);
12406 // The index names from write_json_index() in print.c
12407 json_dumper_value_string(dumper, "packets-*");
12408 json_dumper_end_array(dumper);
12409
12410 json_dumper_set_member_name(dumper, "settings");
12411 json_dumper_begin_object(dumper);
12412 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12413 json_dumper_value_anyf(dumper, "%d", 1000000);
12414 json_dumper_end_object(dumper);
12415}
12416
12417static char*
12418ws_type_to_elastic(unsigned type)
12419{
12420 switch(type) {
12421 case FT_INT8:
12422 return "byte";
12423 case FT_UINT8:
12424 case FT_INT16:
12425 return "short";
12426 case FT_UINT16:
12427 case FT_INT32:
12428 case FT_UINT24:
12429 case FT_INT24:
12430 return "integer";
12431 case FT_FRAMENUM:
12432 case FT_UINT32:
12433 case FT_UINT40:
12434 case FT_UINT48:
12435 case FT_UINT56:
12436 case FT_INT40:
12437 case FT_INT48:
12438 case FT_INT56:
12439 case FT_INT64:
12440 return "long";
12441 case FT_UINT64:
12442 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12443 case FT_FLOAT:
12444 return "float";
12445 case FT_DOUBLE:
12446 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12447 return "double";
12448 case FT_IPv6:
12449 case FT_IPv4:
12450 return "ip";
12451 case FT_ABSOLUTE_TIME:
12452 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12453 case FT_BOOLEAN:
12454 return "boolean";
12455 default:
12456 return NULL((void*)0);
12457 }
12458}
12459
12460static char*
12461dot_to_underscore(char* str)
12462{
12463 unsigned i;
12464 for (i = 0; i < strlen(str); i++) {
12465 if (str[i] == '.')
12466 str[i] = '_';
12467 }
12468 return str;
12469}
12470
12471/* Dumps a mapping file for ElasticSearch
12472 * This is the v1 (legacy) _template API.
12473 * At some point it may need to be updated with the composable templates
12474 * introduced in Elasticsearch 7.8 (_index_template)
12475 */
12476void
12477proto_registrar_dump_elastic(const char* filter)
12478{
12479 header_field_info *hfinfo;
12480 header_field_info *parent_hfinfo;
12481 unsigned i;
12482 bool_Bool open_object = true1;
12483 const char* prev_proto = NULL((void*)0);
12484 char* str;
12485 char** protos = NULL((void*)0);
12486 char* proto;
12487 bool_Bool found;
12488 unsigned j;
12489 char* type;
12490 char* prev_item = NULL((void*)0);
12491
12492 /* We have filtering protocols. Extract them. */
12493 if (filter) {
12494 protos = g_strsplit(filter, ",", -1);
12495 }
12496
12497 /*
12498 * To help tracking down the json tree, objects have been appended with a comment:
12499 * n.label -> where n is the indentation level and label the name of the object
12500 */
12501
12502 json_dumper dumper = {
12503 .output_file = stdoutstdout,
12504 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12505 };
12506 json_dumper_begin_object(&dumper); // 1.root
12507 elastic_add_base_mapping(&dumper);
12508
12509 json_dumper_set_member_name(&dumper, "mappings");
12510 json_dumper_begin_object(&dumper); // 2.mappings
12511
12512 json_dumper_set_member_name(&dumper, "properties");
12513 json_dumper_begin_object(&dumper); // 3.properties
12514 json_dumper_set_member_name(&dumper, "timestamp");
12515 json_dumper_begin_object(&dumper); // 4.timestamp
12516 json_dumper_set_member_name(&dumper, "type");
12517 json_dumper_value_string(&dumper, "date");
12518 json_dumper_end_object(&dumper); // 4.timestamp
12519
12520 json_dumper_set_member_name(&dumper, "layers");
12521 json_dumper_begin_object(&dumper); // 4.layers
12522 json_dumper_set_member_name(&dumper, "properties");
12523 json_dumper_begin_object(&dumper); // 5.properties
12524
12525 for (i = 1; i < gpa_hfinfo.len; i++) {
12526 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12527 continue; /* This is a deregistered protocol or header field */
12528
12529 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", 12529
, __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", 12529
, "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", 12529, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12530
12531 /*
12532 * Skip the pseudo-field for "proto_tree_add_text()" since
12533 * we don't want it in the list of filterable protocols.
12534 */
12535 if (hfinfo->id == hf_text_only)
12536 continue;
12537
12538 if (!proto_registrar_is_protocol(i)) {
12539 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", 12539
, __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", 12539
, "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", 12539
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf."
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12540
12541 /*
12542 * Skip the field if filter protocols have been set and this one's
12543 * parent is not listed.
12544 */
12545 if (protos) {
12546 found = false0;
12547 j = 0;
12548 proto = protos[0];
12549 while(proto) {
12550 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12551 found = true1;
12552 break;
12553 }
12554 j++;
12555 proto = protos[j];
12556 }
12557 if (!found)
12558 continue;
12559 }
12560
12561 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12562 json_dumper_end_object(&dumper); // 7.properties
12563 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12564 open_object = true1;
12565 }
12566
12567 prev_proto = parent_hfinfo->abbrev;
12568
12569 if (open_object) {
12570 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12571 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12572 json_dumper_set_member_name(&dumper, "properties");
12573 json_dumper_begin_object(&dumper); // 7.properties
12574 open_object = false0;
12575 }
12576 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12577 type = ws_type_to_elastic(hfinfo->type);
12578 /* when type is NULL, we have the default mapping: string */
12579 if (type) {
12580 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12581 dot_to_underscore(str);
12582 if (g_strcmp0(prev_item, str)) {
12583 json_dumper_set_member_name(&dumper, str);
12584 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12585 json_dumper_set_member_name(&dumper, "type");
12586 json_dumper_value_string(&dumper, type);
12587 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12588 }
12589 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)
;
12590 prev_item = str;
12591 }
12592 }
12593 }
12594 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)
;
12595
12596 if (prev_proto) {
12597 json_dumper_end_object(&dumper); // 7.properties
12598 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12599 }
12600
12601 json_dumper_end_object(&dumper); // 5.properties
12602 json_dumper_end_object(&dumper); // 4.layers
12603 json_dumper_end_object(&dumper); // 3.properties
12604 json_dumper_end_object(&dumper); // 2.mappings
12605 json_dumper_end_object(&dumper); // 1.root
12606 bool_Bool ret = json_dumper_finish(&dumper);
12607 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12607, "ret"))))
;
12608
12609 g_strfreev(protos);
12610}
12611
12612/* Dumps the contents of the registration database to stdout. An independent
12613 * program can take this output and format it into nice tables or HTML or
12614 * whatever.
12615 *
12616 * There is one record per line. Each record is either a protocol or a header
12617 * field, differentiated by the first field. The fields are tab-delimited.
12618 *
12619 * Protocols
12620 * ---------
12621 * Field 1 = 'P'
12622 * Field 2 = descriptive protocol name
12623 * Field 3 = protocol abbreviation
12624 *
12625 * Header Fields
12626 * -------------
12627 * Field 1 = 'F'
12628 * Field 2 = descriptive field name
12629 * Field 3 = field abbreviation
12630 * Field 4 = type ( textual representation of the ftenum type )
12631 * Field 5 = parent protocol abbreviation
12632 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12633 * Field 7 = bitmask: format: hex: 0x....
12634 * Field 8 = blurb describing field
12635 */
12636void
12637proto_registrar_dump_fields(void)
12638{
12639 header_field_info *hfinfo, *parent_hfinfo;
12640 int i, len;
12641 const char *enum_name;
12642 const char *base_name;
12643 const char *blurb;
12644 char width[5];
12645
12646 len = gpa_hfinfo.len;
12647 for (i = 1; i < len ; i++) {
12648 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12649 continue; /* This is a deregistered protocol or header field */
12650
12651 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", 12651
, __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", 12651
, "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", 12651, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12652
12653 /*
12654 * Skip the pseudo-field for "proto_tree_add_text()" since
12655 * we don't want it in the list of filterable fields.
12656 */
12657 if (hfinfo->id == hf_text_only)
12658 continue;
12659
12660 /* format for protocols */
12661 if (proto_registrar_is_protocol(i)) {
12662 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12663 }
12664 /* format for header fields */
12665 else {
12666 /*
12667 * If this field isn't at the head of the list of
12668 * fields with this name, skip this field - all
12669 * fields with the same name are really just versions
12670 * of the same field stored in different bits, and
12671 * should have the same type/radix/value list, and
12672 * just differ in their bit masks. (If a field isn't
12673 * a bitfield, but can be, say, 1 or 2 bytes long,
12674 * it can just be made FT_UINT16, meaning the
12675 * *maximum* length is 2 bytes, and be used
12676 * for all lengths.)
12677 */
12678 if (hfinfo->same_name_prev_id != -1)
12679 continue;
12680
12681 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", 12681
, __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", 12681
, "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", 12681
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf."
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12682
12683 enum_name = ftype_name(hfinfo->type);
12684 base_name = "";
12685
12686 if (hfinfo->type == FT_CHAR ||
12687 hfinfo->type == FT_UINT8 ||
12688 hfinfo->type == FT_UINT16 ||
12689 hfinfo->type == FT_UINT24 ||
12690 hfinfo->type == FT_UINT32 ||
12691 hfinfo->type == FT_UINT40 ||
12692 hfinfo->type == FT_UINT48 ||
12693 hfinfo->type == FT_UINT56 ||
12694 hfinfo->type == FT_UINT64 ||
12695 hfinfo->type == FT_INT8 ||
12696 hfinfo->type == FT_INT16 ||
12697 hfinfo->type == FT_INT24 ||
12698 hfinfo->type == FT_INT32 ||
12699 hfinfo->type == FT_INT40 ||
12700 hfinfo->type == FT_INT48 ||
12701 hfinfo->type == FT_INT56 ||
12702 hfinfo->type == FT_INT64) {
12703
12704 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12705 case BASE_NONE:
12706 case BASE_DEC:
12707 case BASE_HEX:
12708 case BASE_OCT:
12709 case BASE_DEC_HEX:
12710 case BASE_HEX_DEC:
12711 case BASE_CUSTOM:
12712 case BASE_PT_UDP:
12713 case BASE_PT_TCP:
12714 case BASE_PT_DCCP:
12715 case BASE_PT_SCTP:
12716 case BASE_OUI:
12717 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12718 break;
12719 default:
12720 base_name = "????";
12721 break;
12722 }
12723 } else if (hfinfo->type == FT_BOOLEAN) {
12724 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12725 snprintf(width, sizeof(width), "%d", hfinfo->display);
12726 base_name = width;
12727 }
12728
12729 blurb = hfinfo->blurb;
12730 if (blurb == NULL((void*)0))
12731 blurb = "";
12732 else if (strlen(blurb) == 0)
12733 blurb = "\"\"";
12734
12735 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12736 hfinfo->name, hfinfo->abbrev, enum_name,
12737 parent_hfinfo->abbrev, base_name,
12738 hfinfo->bitmask, blurb);
12739 }
12740 }
12741}
12742
12743/* Dumps all abbreviated field and protocol completions of the given string to
12744 * stdout. An independent program may use this for command-line tab completion
12745 * of fields.
12746 */
12747bool_Bool
12748proto_registrar_dump_field_completions(const char *prefix)
12749{
12750 header_field_info *hfinfo;
12751 int i, len;
12752 size_t prefix_len;
12753 bool_Bool matched = false0;
12754
12755 prefix_len = strlen(prefix);
12756 len = gpa_hfinfo.len;
12757 for (i = 1; i < len ; i++) {
12758 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12759 continue; /* This is a deregistered protocol or header field */
12760
12761 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", 12761
, __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", 12761
, "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", 12761, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf."
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12762
12763 /*
12764 * Skip the pseudo-field for "proto_tree_add_text()" since
12765 * we don't want it in the list of filterable fields.
12766 */
12767 if (hfinfo->id == hf_text_only)
12768 continue;
12769
12770 /* format for protocols */
12771 if (proto_registrar_is_protocol(i)) {
12772 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12773 matched = true1;
12774 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12775 }
12776 }
12777 /* format for header fields */
12778 else {
12779 /*
12780 * If this field isn't at the head of the list of
12781 * fields with this name, skip this field - all
12782 * fields with the same name are really just versions
12783 * of the same field stored in different bits, and
12784 * should have the same type/radix/value list, and
12785 * just differ in their bit masks. (If a field isn't
12786 * a bitfield, but can be, say, 1 or 2 bytes long,
12787 * it can just be made FT_UINT16, meaning the
12788 * *maximum* length is 2 bytes, and be used
12789 * for all lengths.)
12790 */
12791 if (hfinfo->same_name_prev_id != -1)
12792 continue;
12793
12794 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12795 matched = true1;
12796 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12797 }
12798 }
12799 }
12800 return matched;
12801}
12802
12803/* Dumps field types and descriptive names to stdout. An independent
12804 * program can take this output and format it into nice tables or HTML or
12805 * whatever.
12806 *
12807 * There is one record per line. The fields are tab-delimited.
12808 *
12809 * Field 1 = field type name, e.g. FT_UINT8
12810 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12811 */
12812void
12813proto_registrar_dump_ftypes(void)
12814{
12815 int fte;
12816
12817 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12818 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12819 }
12820}
12821
12822/* This function indicates whether it's possible to construct a
12823 * "match selected" display filter string for the specified field,
12824 * returns an indication of whether it's possible, and, if it's
12825 * possible and "filter" is non-null, constructs the filter and
12826 * sets "*filter" to point to it.
12827 * You do not need to [g_]free() this string since it will be automatically
12828 * freed once the next packet is dissected.
12829 */
12830static bool_Bool
12831construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12832 char **filter)
12833{
12834 const header_field_info *hfinfo;
12835 int start, length, length_remaining;
12836
12837 if (!finfo)
12838 return false0;
12839
12840 hfinfo = finfo->hfinfo;
12841 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12841, "hfinfo"))))
;
12842
12843 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12844 * then "the numeric value ... is not used when preparing
12845 * filters for the field in question." If it's any other
12846 * base, we'll generate the filter normally (which will
12847 * be numeric, even though the human-readable string does
12848 * work for filtering.)
12849 *
12850 * XXX - It might be nice to use fvalue_to_string_repr() in
12851 * "proto_item_fill_label()" as well, although, there, you'd
12852 * have to deal with the base *and* with resolved values for
12853 * addresses.
12854 *
12855 * Perhaps in addition to taking the repr type (DISPLAY
12856 * or DFILTER) and the display (base), fvalue_to_string_repr()
12857 * should have the the "strings" values in the header_field_info
12858 * structure for the field as a parameter, so it can have
12859 * if the field is Boolean or an enumerated integer type,
12860 * the tables used to generate human-readable values.
12861 */
12862 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12863 const char *str = NULL((void*)0);
12864
12865 switch (hfinfo->type) {
12866
12867 case FT_INT8:
12868 case FT_INT16:
12869 case FT_INT24:
12870 case FT_INT32:
12871 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12872 break;
12873
12874 case FT_CHAR:
12875 case FT_UINT8:
12876 case FT_UINT16:
12877 case FT_UINT24:
12878 case FT_UINT32:
12879 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12880 break;
12881
12882 default:
12883 break;
12884 }
12885
12886 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12887 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12888 return true1;
12889 }
12890 }
12891
12892 switch (hfinfo->type) {
12893
12894 case FT_PROTOCOL:
12895 if (filter != NULL((void*)0))
12896 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12897 break;
12898
12899 case FT_NONE:
12900 /*
12901 * If the length is 0, just match the name of the
12902 * field.
12903 *
12904 * (Also check for negative values, just in case,
12905 * as we'll cast it to an unsigned value later.)
12906 */
12907 length = finfo->length;
12908 if (length == 0) {
12909 if (filter != NULL((void*)0))
12910 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12911 break;
12912 }
12913 if (length < 0)
12914 return false0;
12915
12916 /*
12917 * This doesn't have a value, so we'd match
12918 * on the raw bytes at this address.
12919 *
12920 * Should we be allowed to access to the raw bytes?
12921 * If "edt" is NULL, the answer is "no".
12922 */
12923 if (edt == NULL((void*)0))
12924 return false0;
12925
12926 /*
12927 * Is this field part of the raw frame tvbuff?
12928 * If not, we can't use "frame[N:M]" to match
12929 * it.
12930 *
12931 * XXX - should this be frame-relative, or
12932 * protocol-relative?
12933 *
12934 * XXX - does this fallback for non-registered
12935 * fields even make sense?
12936 */
12937 if (finfo->ds_tvb != edt->tvb)
12938 return false0; /* you lose */
12939
12940 /*
12941 * Don't go past the end of that tvbuff.
12942 */
12943 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12944 if (length > length_remaining)
12945 length = length_remaining;
12946 if (length <= 0)
12947 return false0;
12948
12949 if (filter != NULL((void*)0)) {
12950 start = finfo->start;
12951 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12952 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12953 wmem_free(NULL((void*)0), str);
12954 }
12955 break;
12956
12957 /* By default, use the fvalue's "to_string_repr" method. */
12958 default:
12959 if (filter != NULL((void*)0)) {
12960 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12961 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12962 wmem_free(NULL((void*)0), str);
12963 }
12964 break;
12965 }
12966
12967 return true1;
12968}
12969
12970/*
12971 * Returns true if we can do a "match selected" on the field, false
12972 * otherwise.
12973 */
12974bool_Bool
12975proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12976{
12977 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12978}
12979
12980/* This function attempts to construct a "match selected" display filter
12981 * string for the specified field; if it can do so, it returns a pointer
12982 * to the string, otherwise it returns NULL.
12983 *
12984 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12985 */
12986char *
12987proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12988{
12989 char *filter = NULL((void*)0);
12990
12991 if (!construct_match_selected_string(finfo, edt, &filter))
12992 {
12993 wmem_free(NULL((void*)0), filter);
12994 return NULL((void*)0);
12995 }
12996 return filter;
12997}
12998
12999/* This function is common code for all proto_tree_add_bitmask... functions.
13000 */
13001
13002static bool_Bool
13003proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
13004 const unsigned len, const int ett, int * const *fields,
13005 const int flags, bool_Bool first,
13006 bool_Bool use_parent_tree,
13007 proto_tree* tree, uint64_t value)
13008{
13009 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
13010 uint64_t bitmask = 0;
13011 uint64_t tmpval;
13012 header_field_info *hf;
13013 uint32_t integer32;
13014 int bit_offset;
13015 int no_of_bits;
13016
13017 if (!*fields)
13018 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"
)
;
13019
13020 if (len > 8)
13021 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
13022 /**
13023 * packet-frame.c uses len=0 since the value is taken from the packet
13024 * metadata, not the packet bytes. In that case, assume that all bits
13025 * in the provided value are valid.
13026 */
13027 if (len > 0) {
13028 available_bits >>= (8 - len)*8;
13029 }
13030
13031 if (use_parent_tree == false0)
13032 tree = proto_item_add_subtree(item, ett);
13033
13034 while (*fields) {
13035 uint64_t present_bits;
13036 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", 13036, __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", 13036
, "**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", 13036, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[**fields];
;
13037 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", 13037
, "hf->bitmask != 0", hf->abbrev))))
;
13038
13039 bitmask |= hf->bitmask;
13040
13041 /* Skip fields that aren't fully present */
13042 present_bits = available_bits & hf->bitmask;
13043 if (present_bits != hf->bitmask) {
13044 fields++;
13045 continue;
13046 }
13047
13048 switch (hf->type) {
13049 case FT_CHAR:
13050 case FT_UINT8:
13051 case FT_UINT16:
13052 case FT_UINT24:
13053 case FT_UINT32:
13054 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
13055 break;
13056
13057 case FT_INT8:
13058 case FT_INT16:
13059 case FT_INT24:
13060 case FT_INT32:
13061 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
13062 break;
13063
13064 case FT_UINT40:
13065 case FT_UINT48:
13066 case FT_UINT56:
13067 case FT_UINT64:
13068 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
13069 break;
13070
13071 case FT_INT40:
13072 case FT_INT48:
13073 case FT_INT56:
13074 case FT_INT64:
13075 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
13076 break;
13077
13078 case FT_BOOLEAN:
13079 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
13080 break;
13081
13082 default:
13083 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))
13084 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))
13085 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))
13086 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))
;
13087 break;
13088 }
13089 if (flags & BMT_NO_APPEND0x01) {
13090 fields++;
13091 continue;
13092 }
13093 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
13094
13095 /* XXX: README.developer and the comments have always defined
13096 * BMT_NO_INT as "only boolean flags are added to the title /
13097 * don't add non-boolean (integral) fields", but the
13098 * implementation has always added BASE_CUSTOM and fields with
13099 * value_strings, though not fields with unit_strings.
13100 * Possibly this is because some dissectors use a FT_UINT8
13101 * with a value_string for fields that should be a FT_BOOLEAN.
13102 */
13103 switch (hf->type) {
13104 case FT_CHAR:
13105 if (hf->display == BASE_CUSTOM) {
13106 char lbl[ITEM_LABEL_LENGTH240];
13107 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13108
13109 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13109, "fmtfunc"))))
;
13110 fmtfunc(lbl, (uint32_t) tmpval);
13111 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13112 hf->name, lbl);
13113 first = false0;
13114 }
13115 else if (hf->strings) {
13116 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13117 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13118 first = false0;
13119 }
13120 else if (!(flags & BMT_NO_INT0x02)) {
13121 char buf[32];
13122 const char *out;
13123
13124 if (!first) {
13125 proto_item_append_text(item, ", ");
13126 }
13127
13128 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13129 proto_item_append_text(item, "%s: %s", hf->name, out);
13130 first = false0;
13131 }
13132
13133 break;
13134
13135 case FT_UINT8:
13136 case FT_UINT16:
13137 case FT_UINT24:
13138 case FT_UINT32:
13139 if (hf->display == BASE_CUSTOM) {
13140 char lbl[ITEM_LABEL_LENGTH240];
13141 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13142
13143 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13143, "fmtfunc"))))
;
13144 fmtfunc(lbl, (uint32_t) tmpval);
13145 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13146 hf->name, lbl);
13147 first = false0;
13148 }
13149 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13150 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13151 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13152 first = false0;
13153 }
13154 else if (!(flags & BMT_NO_INT0x02)) {
13155 char buf[NUMBER_LABEL_LENGTH80];
13156 const char *out = NULL((void*)0);
13157
13158 if (!first) {
13159 proto_item_append_text(item, ", ");
13160 }
13161
13162 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13163 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13164 }
13165 if (out == NULL((void*)0)) {
13166 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13167 }
13168 proto_item_append_text(item, "%s: %s", hf->name, out);
13169 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13170 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13171 }
13172 first = false0;
13173 }
13174
13175 break;
13176
13177 case FT_INT8:
13178 case FT_INT16:
13179 case FT_INT24:
13180 case FT_INT32:
13181 integer32 = (uint32_t) tmpval;
13182 if (hf->bitmask) {
13183 no_of_bits = ws_count_ones(hf->bitmask);
13184 integer32 = ws_sign_ext32(integer32, no_of_bits);
13185 }
13186 if (hf->display == BASE_CUSTOM) {
13187 char lbl[ITEM_LABEL_LENGTH240];
13188 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13189
13190 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13190, "fmtfunc"))))
;
13191 fmtfunc(lbl, (int32_t) integer32);
13192 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13193 hf->name, lbl);
13194 first = false0;
13195 }
13196 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13197 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13198 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13199 first = false0;
13200 }
13201 else if (!(flags & BMT_NO_INT0x02)) {
13202 char buf[NUMBER_LABEL_LENGTH80];
13203 const char *out = NULL((void*)0);
13204
13205 if (!first) {
13206 proto_item_append_text(item, ", ");
13207 }
13208
13209 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13210 out = hf_try_val_to_str((int32_t) integer32, hf);
13211 }
13212 if (out == NULL((void*)0)) {
13213 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13214 }
13215 proto_item_append_text(item, "%s: %s", hf->name, out);
13216 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13217 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13218 }
13219 first = false0;
13220 }
13221
13222 break;
13223
13224 case FT_UINT40:
13225 case FT_UINT48:
13226 case FT_UINT56:
13227 case FT_UINT64:
13228 if (hf->display == BASE_CUSTOM) {
13229 char lbl[ITEM_LABEL_LENGTH240];
13230 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13231
13232 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13232, "fmtfunc"))))
;
13233 fmtfunc(lbl, tmpval);
13234 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13235 hf->name, lbl);
13236 first = false0;
13237 }
13238 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13239 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13240 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13241 first = false0;
13242 }
13243 else if (!(flags & BMT_NO_INT0x02)) {
13244 char buf[NUMBER_LABEL_LENGTH80];
13245 const char *out = NULL((void*)0);
13246
13247 if (!first) {
13248 proto_item_append_text(item, ", ");
13249 }
13250
13251 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13252 out = hf_try_val64_to_str(tmpval, hf);
13253 }
13254 if (out == NULL((void*)0)) {
13255 out = hfinfo_number_value_format64(hf, buf, tmpval);
13256 }
13257 proto_item_append_text(item, "%s: %s", hf->name, out);
13258 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13259 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13260 }
13261 first = false0;
13262 }
13263
13264 break;
13265
13266 case FT_INT40:
13267 case FT_INT48:
13268 case FT_INT56:
13269 case FT_INT64:
13270 if (hf->bitmask) {
13271 no_of_bits = ws_count_ones(hf->bitmask);
13272 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13273 }
13274 if (hf->display == BASE_CUSTOM) {
13275 char lbl[ITEM_LABEL_LENGTH240];
13276 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13277
13278 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13278, "fmtfunc"))))
;
13279 fmtfunc(lbl, (int64_t) tmpval);
13280 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13281 hf->name, lbl);
13282 first = false0;
13283 }
13284 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13285 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13286 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13287 first = false0;
13288 }
13289 else if (!(flags & BMT_NO_INT0x02)) {
13290 char buf[NUMBER_LABEL_LENGTH80];
13291 const char *out = NULL((void*)0);
13292
13293 if (!first) {
13294 proto_item_append_text(item, ", ");
13295 }
13296
13297 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13298 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13299 }
13300 if (out == NULL((void*)0)) {
13301 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13302 }
13303 proto_item_append_text(item, "%s: %s", hf->name, out);
13304 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13305 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13306 }
13307 first = false0;
13308 }
13309
13310 break;
13311
13312 case FT_BOOLEAN:
13313 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13314 /* If we have true/false strings, emit full - otherwise messages
13315 might look weird */
13316 const struct true_false_string *tfs =
13317 (const struct true_false_string *)hf->strings;
13318
13319 if (tmpval) {
13320 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13321 hf->name, tfs->true_string);
13322 first = false0;
13323 } else if (!(flags & BMT_NO_FALSE0x04)) {
13324 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13325 hf->name, tfs->false_string);
13326 first = false0;
13327 }
13328 } else if (hf->bitmask & value) {
13329 /* If the flag is set, show the name */
13330 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13331 first = false0;
13332 }
13333 break;
13334 default:
13335 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))
13336 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))
13337 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))
13338 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))
;
13339 break;
13340 }
13341
13342 fields++;
13343 }
13344
13345 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13346 * but then again most dissectors don't set the bitmask field for
13347 * the higher level bitmask hfi, so calculate the bitmask from the
13348 * fields present. */
13349 if (item) {
13350 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13351 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13352 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)
;
13353 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)
;
13354 }
13355 return first;
13356}
13357
13358/* This function will dissect a sequence of bytes that describe a
13359 * bitmask and supply the value of that sequence through a pointer.
13360 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13361 * to be dissected.
13362 * This field will form an expansion under which the individual fields of the
13363 * bitmask is dissected and displayed.
13364 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13365 *
13366 * fields is an array of pointers to int that lists all the fields of the
13367 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13368 * or another integer of the same type/size as hf_hdr with a mask specified.
13369 * This array is terminated by a NULL entry.
13370 *
13371 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13372 * FT_integer fields that have a value_string attached will have the
13373 * matched string displayed on the expansion line.
13374 */
13375proto_item *
13376proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13377 const unsigned offset, const int hf_hdr,
13378 const int ett, int * const *fields,
13379 const unsigned encoding, uint64_t *retval)
13380{
13381 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);
13382}
13383
13384/* This function will dissect a sequence of bytes that describe a
13385 * bitmask.
13386 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13387 * to be dissected.
13388 * This field will form an expansion under which the individual fields of the
13389 * bitmask is dissected and displayed.
13390 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13391 *
13392 * fields is an array of pointers to int that lists all the fields of the
13393 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13394 * or another integer of the same type/size as hf_hdr with a mask specified.
13395 * This array is terminated by a NULL entry.
13396 *
13397 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13398 * FT_integer fields that have a value_string attached will have the
13399 * matched string displayed on the expansion line.
13400 */
13401proto_item *
13402proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13403 const unsigned offset, const int hf_hdr,
13404 const int ett, int * const *fields,
13405 const unsigned encoding)
13406{
13407 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13408}
13409
13410/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13411 * what data is appended to the header.
13412 */
13413proto_item *
13414proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13415 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13416 uint64_t *retval)
13417{
13418 proto_item *item = NULL((void*)0);
13419 header_field_info *hf;
13420 unsigned len;
13421 uint64_t value;
13422
13423 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", 13423, __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", 13423
, "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", 13423, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13424 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", 13424, (hf)->abbrev)))
;
13425 len = ftype_wire_size(hf->type);
13426 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13427
13428 if (parent_tree) {
13429 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13430 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13431 flags, false0, false0, NULL((void*)0), value);
13432 }
13433
13434 *retval = value;
13435 if (hf->bitmask) {
13436 /* Mask out irrelevant portions */
13437 *retval &= hf->bitmask;
13438 /* Shift bits */
13439 *retval >>= hfinfo_bitshift(hf);
13440 }
13441
13442 return item;
13443}
13444
13445/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13446 * what data is appended to the header.
13447 */
13448proto_item *
13449proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13450 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13451{
13452 proto_item *item = NULL((void*)0);
13453 header_field_info *hf;
13454 unsigned len;
13455 uint64_t value;
13456
13457 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", 13457, __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", 13457
, "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", 13457, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13458 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", 13458, (hf)->abbrev)))
;
13459
13460 if (parent_tree) {
13461 len = ftype_wire_size(hf->type);
13462 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13463 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13464 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13465 flags, false0, false0, NULL((void*)0), value);
13466 }
13467
13468 return item;
13469}
13470
13471/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13472 can't be retrieved directly from tvb) */
13473proto_item *
13474proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13475 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13476{
13477 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13478 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13479}
13480
13481/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13482WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13483proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13484 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13485{
13486 proto_item *item = NULL((void*)0);
13487 header_field_info *hf;
13488 unsigned len;
13489
13490 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", 13490, __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", 13490
, "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", 13490, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13491 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", 13491, (hf)->abbrev)))
;
13492 /* the proto_tree_add_uint/_uint64() calls below
13493 will fail if tvb==NULL and len!=0 */
13494 len = tvb ? ftype_wire_size(hf->type) : 0;
13495
13496 if (parent_tree) {
13497 if (len <= 4)
13498 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13499 else
13500 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13501
13502 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13503 flags, false0, false0, NULL((void*)0), value);
13504 }
13505
13506 return item;
13507}
13508
13509/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13510void
13511proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13512 const unsigned len, int * const *fields, const unsigned encoding)
13513{
13514 uint64_t value;
13515
13516 if (tree) {
13517 value = get_uint64_value(tree, tvb, offset, len, encoding);
13518 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13519 BMT_NO_APPEND0x01, false0, true1, tree, value);
13520 }
13521}
13522
13523WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13524proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13525 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13526{
13527 uint64_t value;
13528
13529 value = get_uint64_value(tree, tvb, offset, len, encoding);
13530 if (tree) {
13531 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13532 BMT_NO_APPEND0x01, false0, true1, tree, value);
13533 }
13534 if (retval) {
13535 *retval = value;
13536 }
13537}
13538
13539WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13540proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13541 const unsigned len, int * const *fields, const uint64_t value)
13542{
13543 if (tree) {
13544 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13545 BMT_NO_APPEND0x01, false0, true1, tree, value);
13546 }
13547}
13548
13549
13550/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13551 * This is intended to support bitmask fields whose lengths can vary, perhaps
13552 * as the underlying standard evolves over time.
13553 * With this API there is the possibility of being called to display more or
13554 * less data than the dissector was coded to support.
13555 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13556 * Thus when presented with "too much" or "too little" data, MSbits will be
13557 * ignored or MSfields sacrificed.
13558 *
13559 * Only fields for which all defined bits are available are displayed.
13560 */
13561proto_item *
13562proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13563 const unsigned offset, const unsigned len, const int hf_hdr,
13564 const int ett, int * const *fields, struct expert_field* exp,
13565 const unsigned encoding)
13566{
13567 proto_item *item = NULL((void*)0);
13568 header_field_info *hf;
13569 unsigned decodable_len;
13570 unsigned decodable_offset;
13571 uint32_t decodable_value;
13572 uint64_t value;
13573
13574 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", 13574, __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", 13574
, "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", 13574, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13575 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", 13575, (hf)->abbrev)))
;
13576
13577 decodable_offset = offset;
13578 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13579
13580 /* If we are ftype_wire_size-limited,
13581 * make sure we decode as many LSBs as possible.
13582 */
13583 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13584 decodable_offset += (len - decodable_len);
13585 }
13586
13587 if (parent_tree) {
13588 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13589 decodable_len, encoding);
13590
13591 /* The root item covers all the bytes even if we can't decode them all */
13592 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13593 decodable_value);
13594 }
13595
13596 if (decodable_len < len) {
13597 /* Dissector likely requires updating for new protocol revision */
13598 expert_add_info_format(NULL((void*)0), item, exp,
13599 "Only least-significant %d of %d bytes decoded",
13600 decodable_len, len);
13601 }
13602
13603 if (item) {
13604 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13605 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13606 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13607 }
13608
13609 return item;
13610}
13611
13612/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13613proto_item *
13614proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13615 const unsigned offset, const unsigned len,
13616 const char *name, const char *fallback,
13617 const int ett, int * const *fields,
13618 const unsigned encoding, const int flags)
13619{
13620 proto_item *item = NULL((void*)0);
13621 uint64_t value;
13622
13623 if (parent_tree) {
13624 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13625 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13626 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13627 flags, true1, false0, NULL((void*)0), value) && fallback) {
13628 /* Still at first item - append 'fallback' text if any */
13629 proto_item_append_text(item, "%s", fallback);
13630 }
13631 }
13632
13633 return item;
13634}
13635
13636proto_item *
13637proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13638 const unsigned bit_offset, const int no_of_bits,
13639 const unsigned encoding)
13640{
13641 header_field_info *hfinfo;
13642 int octet_length;
13643 unsigned octet_offset;
13644
13645 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", 13645, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13645
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13645, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13646
13647 if (no_of_bits < 0) {
13648 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13649 }
13650 octet_length = (no_of_bits + 7) >> 3;
13651 octet_offset = bit_offset >> 3;
13652 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13653
13654 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13655 * but only after doing a bunch more work (which we can, in the common
13656 * case, shortcut here).
13657 */
13658 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13659 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", 13659
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13659, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13659, "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", 13659, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13660
13661 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13662}
13663
13664/*
13665 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13666 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13667 * Offset should be given in bits from the start of the tvb.
13668 */
13669
13670static proto_item *
13671_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13672 const unsigned bit_offset, const int no_of_bits,
13673 uint64_t *return_value, const unsigned encoding)
13674{
13675 unsigned offset;
13676 unsigned length;
13677 uint8_t tot_no_bits;
13678 char *bf_str;
13679 char lbl_str[ITEM_LABEL_LENGTH240];
13680 uint64_t value = 0;
13681 uint8_t *bytes = NULL((void*)0);
13682 size_t bytes_length = 0;
13683
13684 proto_item *pi;
13685 header_field_info *hf_field;
13686
13687 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13688 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", 13688, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13688
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13688, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13689
13690 if (hf_field->bitmask != 0) {
13691 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)
13692 " 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)
13693 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)
;
13694 }
13695
13696 if (no_of_bits < 0) {
13697 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13698 } else if (no_of_bits == 0) {
13699 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)
13700 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)
;
13701 }
13702
13703 /* Byte align offset */
13704 offset = bit_offset>>3;
13705
13706 /*
13707 * Calculate the number of octets used to hold the bits
13708 */
13709 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13710 length = (tot_no_bits + 7) >> 3;
13711
13712 if (no_of_bits < 65) {
13713 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13714 } else if (hf_field->type != FT_BYTES) {
13715 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)
13716 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)
;
13717 return NULL((void*)0);
13718 }
13719
13720 /* Sign extend for signed types */
13721 switch (hf_field->type) {
13722 case FT_INT8:
13723 case FT_INT16:
13724 case FT_INT24:
13725 case FT_INT32:
13726 case FT_INT40:
13727 case FT_INT48:
13728 case FT_INT56:
13729 case FT_INT64:
13730 value = ws_sign_ext64(value, no_of_bits);
13731 break;
13732
13733 default:
13734 break;
13735 }
13736
13737 if (return_value) {
13738 *return_value = value;
13739 }
13740
13741 /* Coast clear. Try and fake it */
13742 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13743 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", 13743
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13743, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13743, "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", 13743, __func__, "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); } } }
;
13744
13745 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13746
13747 switch (hf_field->type) {
13748 case FT_BOOLEAN:
13749 /* Boolean field */
13750 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13751 "%s = %s: %s",
13752 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13753 break;
13754
13755 case FT_CHAR:
13756 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13757 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13758 break;
13759
13760 case FT_UINT8:
13761 case FT_UINT16:
13762 case FT_UINT24:
13763 case FT_UINT32:
13764 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13765 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13766 break;
13767
13768 case FT_INT8:
13769 case FT_INT16:
13770 case FT_INT24:
13771 case FT_INT32:
13772 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13773 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13774 break;
13775
13776 case FT_UINT40:
13777 case FT_UINT48:
13778 case FT_UINT56:
13779 case FT_UINT64:
13780 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13781 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13782 break;
13783
13784 case FT_INT40:
13785 case FT_INT48:
13786 case FT_INT56:
13787 case FT_INT64:
13788 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13789 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13790 break;
13791
13792 case FT_BYTES:
13793 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13794 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13795 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13796 proto_item_set_text(pi, "%s", lbl_str);
13797 return pi;
13798
13799 /* TODO: should handle FT_UINT_BYTES ? */
13800
13801 default:
13802 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))
13803 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))
13804 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))
13805 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))
;
13806 return NULL((void*)0);
13807 }
13808
13809 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13810 return pi;
13811}
13812
13813proto_item *
13814proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13815 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13816 uint64_t *return_value)
13817{
13818 proto_item *pi;
13819 int no_of_bits;
13820 unsigned octet_offset;
13821 unsigned mask_initial_bit_offset;
13822 unsigned mask_greatest_bit_offset;
13823 unsigned octet_length;
13824 uint8_t i;
13825 char bf_str[256];
13826 char lbl_str[ITEM_LABEL_LENGTH240];
13827 uint64_t value;
13828 uint64_t composite_bitmask;
13829 uint64_t composite_bitmap;
13830
13831 header_field_info *hf_field;
13832
13833 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13834 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", 13834, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13834
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13834, "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
13835
13836 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13837 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)
13838 " 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)
13839 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)
;
13840 }
13841
13842 mask_initial_bit_offset = bit_offset % 8;
13843
13844 no_of_bits = 0;
13845 value = 0;
13846 i = 0;
13847 mask_greatest_bit_offset = 0;
13848 composite_bitmask = 0;
13849 composite_bitmap = 0;
13850
13851 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
13852 uint64_t crumb_mask, crumb_value;
13853 uint8_t crumb_end_bit_offset;
13854
13855 crumb_value = tvb_get_bits64(tvb,
13856 bit_offset + crumb_spec[i].crumb_bit_offset,
13857 crumb_spec[i].crumb_bit_length,
13858 ENC_BIG_ENDIAN0x00000000);
13859 value += crumb_value;
13860 no_of_bits += crumb_spec[i].crumb_bit_length;
13861 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", 13861
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13862
13863 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13864 octet containing the initial offset.
13865 If the mask is beyond 32 bits, then give up on bit map display.
13866 This could be improved in future, probably showing a table
13867 of 32 or 64 bits per row */
13868 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13869 crumb_end_bit_offset = mask_initial_bit_offset
13870 + crumb_spec[i].crumb_bit_offset
13871 + crumb_spec[i].crumb_bit_length;
13872 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'
13873
13874 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13875 mask_greatest_bit_offset = crumb_end_bit_offset;
13876 }
13877 /* Currently the bitmap of the crumbs are only shown if
13878 * smaller than 32 bits. Do not bother calculating the
13879 * mask if it is larger than that. */
13880 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13881 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'
13882 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13883 }
13884 }
13885 /* Shift left for the next segment */
13886 value <<= crumb_spec[++i].crumb_bit_length;
13887 }
13888
13889 /* Sign extend for signed types */
13890 switch (hf_field->type) {
13891 case FT_INT8:
13892 case FT_INT16:
13893 case FT_INT24:
13894 case FT_INT32:
13895 case FT_INT40:
13896 case FT_INT48:
13897 case FT_INT56:
13898 case FT_INT64:
13899 value = ws_sign_ext64(value, no_of_bits);
13900 break;
13901 default:
13902 break;
13903 }
13904
13905 if (return_value) {
13906 *return_value = value;
13907 }
13908
13909 /* Coast clear. Try and fake it */
13910 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13911 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", 13911
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13911, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13911, "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", 13911, __func__, "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); } } }
;
13912
13913 /* initialise the format string */
13914 bf_str[0] = '\0';
13915
13916 octet_offset = bit_offset >> 3;
13917
13918 /* Round up mask length to nearest octet */
13919 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13920 mask_greatest_bit_offset = octet_length << 3;
13921
13922 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13923 It would be a useful enhancement to eliminate this restriction. */
13924 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13925 other_decode_bitfield_value(bf_str,
13926 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13927 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13928 mask_greatest_bit_offset);
13929 } else {
13930 /* If the bitmask is too large, try to describe its contents. */
13931 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13932 }
13933
13934 switch (hf_field->type) {
13935 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13936 /* Boolean field */
13937 return proto_tree_add_boolean_format(tree, hfindex,
13938 tvb, octet_offset, octet_length, value,
13939 "%s = %s: %s",
13940 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13941 break;
13942
13943 case FT_CHAR:
13944 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13945 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13946 break;
13947
13948 case FT_UINT8:
13949 case FT_UINT16:
13950 case FT_UINT24:
13951 case FT_UINT32:
13952 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13953 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13954 break;
13955
13956 case FT_INT8:
13957 case FT_INT16:
13958 case FT_INT24:
13959 case FT_INT32:
13960 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13961 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13962 break;
13963
13964 case FT_UINT40:
13965 case FT_UINT48:
13966 case FT_UINT56:
13967 case FT_UINT64:
13968 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13969 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13970 break;
13971
13972 case FT_INT40:
13973 case FT_INT48:
13974 case FT_INT56:
13975 case FT_INT64:
13976 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13977 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13978 break;
13979
13980 default:
13981 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))
13982 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))
13983 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))
13984 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))
;
13985 return NULL((void*)0);
13986 }
13987 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13988 return pi;
13989}
13990
13991void
13992proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13993 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13994{
13995 header_field_info *hfinfo;
13996 unsigned start = bit_offset >> 3;
13997 unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13998
13999 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
14000 * so that we can use the tree's memory scope in calculating the string */
14001 tvb_ensure_bytes_exist(tvb, start, length);
14002 if (!tree) return;
14003
14004 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", 14004, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 14004
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14004, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
14005 proto_tree_add_text_internal(tree, tvb, start, length,
14006 "%s crumb %d of %s (decoded above)",
14007 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
14008 tvb_get_bits32(tvb,
14009 bit_offset,
14010 crumb_spec[crumb_index].crumb_bit_length,
14011 ENC_BIG_ENDIAN0x00000000),
14012 ENC_BIG_ENDIAN0x00000000),
14013 crumb_index,
14014 hfinfo->name);
14015}
14016
14017proto_item *
14018proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14019 const unsigned bit_offset, const int no_of_bits,
14020 uint64_t *return_value, const unsigned encoding)
14021{
14022 proto_item *item;
14023
14024 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
14025 bit_offset, no_of_bits,
14026 return_value, encoding))) {
14027 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)
;
14028 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)
;
14029 }
14030 return item;
14031}
14032
14033static proto_item *
14034_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14035 tvbuff_t *tvb, const unsigned bit_offset,
14036 const int no_of_bits, void *value_ptr,
14037 const unsigned encoding, char *value_str)
14038{
14039 unsigned offset;
14040 unsigned length;
14041 uint8_t tot_no_bits;
14042 char *str;
14043 uint64_t value = 0;
14044 header_field_info *hf_field;
14045
14046 /* We do not have to return a value, try to fake it as soon as possible */
14047 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14048 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", 14048
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14048, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14048, "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", 14048, __func__, "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); } } }
;
14049
14050 if (hf_field->bitmask != 0) {
14051 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)
14052 " 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)
14053 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)
;
14054 }
14055
14056 if (no_of_bits < 0) {
14057 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
14058 } else if (no_of_bits == 0) {
14059 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)
14060 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)
;
14061 }
14062
14063 /* Byte align offset */
14064 offset = bit_offset>>3;
14065
14066 /*
14067 * Calculate the number of octets used to hold the bits
14068 */
14069 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
14070 length = tot_no_bits>>3;
14071 /* If we are using part of the next octet, increase length by 1 */
14072 if (tot_no_bits & 0x07)
14073 length++;
14074
14075 if (no_of_bits < 65) {
14076 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
14077 } else {
14078 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)
14079 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)
;
14080 return NULL((void*)0);
14081 }
14082
14083 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
14084
14085 (void) g_strlcat(str, " = ", 256+64);
14086 (void) g_strlcat(str, hf_field->name, 256+64);
14087
14088 /*
14089 * This function does not receive an actual value but a dimensionless pointer to that value.
14090 * For this reason, the type of the header field is examined in order to determine
14091 * what kind of value we should read from this address.
14092 * The caller of this function must make sure that for the specific header field type the address of
14093 * a compatible value is provided.
14094 */
14095 switch (hf_field->type) {
14096 case FT_BOOLEAN:
14097 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14098 "%s: %s", str, value_str);
14099 break;
14100
14101 case FT_CHAR:
14102 case FT_UINT8:
14103 case FT_UINT16:
14104 case FT_UINT24:
14105 case FT_UINT32:
14106 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
14107 "%s: %s", str, value_str);
14108 break;
14109
14110 case FT_UINT40:
14111 case FT_UINT48:
14112 case FT_UINT56:
14113 case FT_UINT64:
14114 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14115 "%s: %s", str, value_str);
14116 break;
14117
14118 case FT_INT8:
14119 case FT_INT16:
14120 case FT_INT24:
14121 case FT_INT32:
14122 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
14123 "%s: %s", str, value_str);
14124 break;
14125
14126 case FT_INT40:
14127 case FT_INT48:
14128 case FT_INT56:
14129 case FT_INT64:
14130 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14131 "%s: %s", str, value_str);
14132 break;
14133
14134 case FT_FLOAT:
14135 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14136 "%s: %s", str, value_str);
14137 break;
14138
14139 default:
14140 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))
14141 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))
14142 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))
14143 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))
;
14144 return NULL((void*)0);
14145 }
14146}
14147
14148static proto_item *
14149proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14150 tvbuff_t *tvb, const unsigned bit_offset,
14151 const int no_of_bits, void *value_ptr,
14152 const unsigned encoding, char *value_str)
14153{
14154 proto_item *item;
14155
14156 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14157 tvb, bit_offset, no_of_bits,
14158 value_ptr, encoding, value_str))) {
14159 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)
;
14160 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)
;
14161 }
14162 return item;
14163}
14164
14165#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);
\
14166 va_start(ap, format)__builtin_va_start(ap, format); \
14167 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14168 va_end(ap)__builtin_va_end(ap);
14169
14170proto_item *
14171proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14172 tvbuff_t *tvb, const unsigned bit_offset,
14173 const int no_of_bits, uint32_t value,
14174 const unsigned encoding,
14175 const char *format, ...)
14176{
14177 va_list ap;
14178 char *dst;
14179 header_field_info *hf_field;
14180
14181 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14182
14183 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", 14183
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14183, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14183, "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", 14183, __func__, "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); } } }
;
14184
14185 switch (hf_field->type) {
14186 case FT_UINT8:
14187 case FT_UINT16:
14188 case FT_UINT24:
14189 case FT_UINT32:
14190 break;
14191
14192 default:
14193 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)
14194 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)
;
14195 return NULL((void*)0);
14196 }
14197
14198 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);
;
14199
14200 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14201}
14202
14203proto_item *
14204proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14205 tvbuff_t *tvb, const unsigned bit_offset,
14206 const int no_of_bits, uint64_t value,
14207 const unsigned encoding,
14208 const char *format, ...)
14209{
14210 va_list ap;
14211 char *dst;
14212 header_field_info *hf_field;
14213
14214 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14215
14216 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", 14216
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14216, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14216, "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", 14216, __func__, "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); } } }
;
14217
14218 switch (hf_field->type) {
14219 case FT_UINT40:
14220 case FT_UINT48:
14221 case FT_UINT56:
14222 case FT_UINT64:
14223 break;
14224
14225 default:
14226 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)
14227 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)
;
14228 return NULL((void*)0);
14229 }
14230
14231 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);
;
14232
14233 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14234}
14235
14236proto_item *
14237proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14238 tvbuff_t *tvb, const unsigned bit_offset,
14239 const int no_of_bits, float value,
14240 const unsigned encoding,
14241 const char *format, ...)
14242{
14243 va_list ap;
14244 char *dst;
14245 header_field_info *hf_field;
14246
14247 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14248
14249 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", 14249
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14249, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14249, "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", 14249, __func__, "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); } } }
;
14250
14251 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",
14251, ((hf_field))->abbrev))))
;
14252
14253 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);
;
14254
14255 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14256}
14257
14258proto_item *
14259proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14260 tvbuff_t *tvb, const unsigned bit_offset,
14261 const int no_of_bits, int32_t value,
14262 const unsigned encoding,
14263 const char *format, ...)
14264{
14265 va_list ap;
14266 char *dst;
14267 header_field_info *hf_field;
14268
14269 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14270
14271 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", 14271
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14271, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14271, "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", 14271, __func__, "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); } } }
;
14272
14273 switch (hf_field->type) {
14274 case FT_INT8:
14275 case FT_INT16:
14276 case FT_INT24:
14277 case FT_INT32:
14278 break;
14279
14280 default:
14281 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)
14282 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)
;
14283 return NULL((void*)0);
14284 }
14285
14286 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);
;
14287
14288 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14289}
14290
14291proto_item *
14292proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14293 tvbuff_t *tvb, const unsigned bit_offset,
14294 const int no_of_bits, int64_t value,
14295 const unsigned encoding,
14296 const char *format, ...)
14297{
14298 va_list ap;
14299 char *dst;
14300 header_field_info *hf_field;
14301
14302 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14303
14304 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", 14304
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14304, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14304, "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", 14304, __func__, "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); } } }
;
14305
14306 switch (hf_field->type) {
14307 case FT_INT40:
14308 case FT_INT48:
14309 case FT_INT56:
14310 case FT_INT64:
14311 break;
14312
14313 default:
14314 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)
14315 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)
;
14316 return NULL((void*)0);
14317 }
14318
14319 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);
;
14320
14321 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14322}
14323
14324proto_item *
14325proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14326 tvbuff_t *tvb, const unsigned bit_offset,
14327 const int no_of_bits, uint64_t value,
14328 const unsigned encoding,
14329 const char *format, ...)
14330{
14331 va_list ap;
14332 char *dst;
14333 header_field_info *hf_field;
14334
14335 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14336
14337 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", 14337
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14337, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14337, "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", 14337, __func__, "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); } } }
;
14338
14339 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"
, 14339, ((hf_field))->abbrev))))
;
14340
14341 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);
;
14342
14343 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14344}
14345
14346proto_item *
14347proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14348 const unsigned bit_offset, const int no_of_chars)
14349{
14350 proto_item *pi;
14351 header_field_info *hfinfo;
14352 int byte_length;
14353 unsigned byte_offset;
14354 char *string;
14355
14356 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14357
14358 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", 14358
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14358, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14358, "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", 14358, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14359
14360 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"
, 14360, ((hfinfo))->abbrev))))
;
14361
14362 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14363 byte_offset = bit_offset >> 3;
14364
14365 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14366
14367 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14368 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14368, "byte_length >= 0"
))))
;
14369 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14370
14371 return pi;
14372}
14373
14374proto_item *
14375proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14376 const unsigned bit_offset, const int no_of_chars)
14377{
14378 proto_item *pi;
14379 header_field_info *hfinfo;
14380 int byte_length;
14381 unsigned byte_offset;
14382 char *string;
14383
14384 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14385
14386 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", 14386
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14386, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14386, "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", 14386, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14387
14388 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"
, 14388, ((hfinfo))->abbrev))))
;
14389
14390 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14391 byte_offset = bit_offset >> 3;
14392
14393 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14394
14395 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14396 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14396, "byte_length >= 0"
))))
;
14397 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14398
14399 return pi;
14400}
14401
14402const value_string proto_checksum_vals[] = {
14403 { PROTO_CHECKSUM_E_BAD, "Bad" },
14404 { PROTO_CHECKSUM_E_GOOD, "Good" },
14405 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14406 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14407 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14408
14409 { 0, NULL((void*)0) }
14410};
14411
14412#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14413
14414proto_item *
14415proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14416 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14417 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14418{
14419 header_field_info *hfinfo;
14420 uint32_t checksum;
14421 uint32_t len;
14422 proto_item* ti = NULL((void*)0);
14423 proto_item* ti2;
14424 bool_Bool incorrect_checksum = true1;
14425
14426 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", 14426, __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", 14426
, "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", 14426, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14427
14428 switch (hfinfo->type) {
14429 case FT_UINT8:
14430 len = 1;
14431 break;
14432 case FT_UINT16:
14433 len = 2;
14434 break;
14435 case FT_UINT24:
14436 len = 3;
14437 break;
14438 case FT_UINT32:
14439 len = 4;
14440 break;
14441 default:
14442 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)
14443 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14444 }
14445
14446 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14447 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14448 proto_item_set_generated(ti);
14449 // Backward compatible with use of -1
14450 if (hf_checksum_status > 0) {
14451 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14452 proto_item_set_generated(ti2);
14453 }
14454 return ti;
14455 }
14456
14457 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14458 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14459 proto_item_set_generated(ti);
14460 } else {
14461 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14462 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14463 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14464 if (computed_checksum == 0) {
14465 proto_item_append_text(ti, " [correct]");
14466 // Backward compatible with use of -1
14467 if (hf_checksum_status > 0) {
14468 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14469 proto_item_set_generated(ti2);
14470 }
14471 incorrect_checksum = false0;
14472 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14473 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14474 /* XXX - This can't distinguish between "shouldbe"
14475 * 0x0000 and 0xFFFF unless we know whether there
14476 * were any nonzero bits (other than the checksum).
14477 * Protocols should not use this path if they might
14478 * have an all zero packet.
14479 * Some implementations put the wrong zero; maybe
14480 * we should have a special expert info for that?
14481 */
14482 }
14483 } else {
14484 if (checksum == computed_checksum) {
14485 proto_item_append_text(ti, " [correct]");
14486 // Backward compatible with use of -1
14487 if (hf_checksum_status > 0) {
14488 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14489 proto_item_set_generated(ti2);
14490 }
14491 incorrect_checksum = false0;
14492 }
14493 }
14494
14495 if (incorrect_checksum) {
14496 // Backward compatible with use of -1
14497 if (hf_checksum_status > 0) {
14498 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14499 proto_item_set_generated(ti2);
14500 }
14501 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14502 proto_item_append_text(ti, " [incorrect]");
14503 if (bad_checksum_expert != NULL((void*)0))
14504 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14505 } else {
14506 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14507 if (bad_checksum_expert != NULL((void*)0))
14508 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);
14509 }
14510 }
14511 } else {
14512 // Backward compatible with use of -1
14513 if (hf_checksum_status > 0) {
14514 proto_item_append_text(ti, " [unverified]");
14515 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14516 proto_item_set_generated(ti2);
14517 }
14518 }
14519 }
14520
14521 return ti;
14522}
14523
14524proto_item *
14525proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14526 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14527 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14528{
14529 header_field_info *hfinfo;
14530 uint8_t *checksum = NULL((void*)0);
14531 proto_item* ti = NULL((void*)0);
14532 proto_item* ti2;
14533 bool_Bool incorrect_checksum = true1;
14534
14535 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", 14535, __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", 14535
, "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", 14535, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14536
14537 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",
14537, ((hfinfo))->abbrev))))
;
14538
14539 /* Make sure a NULL computed_checksum isn't dereferenced.
14540 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14541 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14542 * cases the behavior is unexpected and still a programmer error;
14543 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14544 * _NOT_PRESENT nor _GENERATED is correct.
14545 */
14546 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", 14546, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14547
14548 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14549 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14550 proto_item_set_generated(ti);
14551 // Backward compatible with use of -1
14552 if (hf_checksum_status > 0) {
14553 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14554 proto_item_set_generated(ti2);
14555 }
14556 return ti;
14557 }
14558
14559 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14560 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14561 proto_item_set_generated(ti);
14562 return ti;
14563 }
14564
14565 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14566 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14567 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14568 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14569 bool_Bool non_zero_flag = false0;
14570 for (size_t index = 0; index < checksum_len; index++) {
14571 if (computed_checksum[index]) {
14572 non_zero_flag = true1;
14573 break;
14574 }
14575 }
14576 if (!non_zero_flag) {
14577 proto_item_append_text(ti, " [correct]");
14578 // Backward compatible with use of -1
14579 if (hf_checksum_status > 0) {
14580 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14581 proto_item_set_generated(ti2);
14582 }
14583 incorrect_checksum = false0;
14584 }
14585 } else {
14586 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14587 proto_item_append_text(ti, " [correct]");
14588 // Backward compatible with use of -1
14589 if (hf_checksum_status > 0) {
14590 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14591 proto_item_set_generated(ti2);
14592 }
14593 incorrect_checksum = false0;
14594 }
14595 }
14596
14597 if (incorrect_checksum) {
14598 // Backward compatible with use of -1
14599 if (hf_checksum_status > 0) {
14600 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14601 proto_item_set_generated(ti2);
14602 }
14603 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14604 proto_item_append_text(ti, " [incorrect]");
14605 if (bad_checksum_expert != NULL((void*)0))
14606 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14607 } else {
14608 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14609 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14610 if (bad_checksum_expert != NULL((void*)0))
14611 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14612 }
14613 }
14614 } else {
14615 // Backward compatible with use of -1
14616 if (hf_checksum_status > 0) {
14617 proto_item_append_text(ti, " [unverified]");
14618 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14619 proto_item_set_generated(ti2);
14620 }
14621 }
14622
14623 return ti;
14624}
14625
14626unsigned char
14627proto_check_field_name(const char *field_name)
14628{
14629 return module_check_valid_name(field_name, false0);
14630}
14631
14632unsigned char
14633proto_check_field_name_lower(const char *field_name)
14634{
14635 return module_check_valid_name(field_name, true1);
14636}
14637
14638bool_Bool
14639tree_expanded(int tree_type)
14640{
14641 if (tree_type <= 0) {
14642 return false0;
14643 }
14644 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", 14644, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14645 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14646}
14647
14648void
14649tree_expanded_set(int tree_type, bool_Bool value)
14650{
14651 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", 14651, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14652
14653 if (value)
14654 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14655 else
14656 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14657}
14658
14659/*
14660 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14661 *
14662 * Local variables:
14663 * c-basic-offset: 8
14664 * tab-width: 8
14665 * indent-tabs-mode: t
14666 * End:
14667 *
14668 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14669 * :indentSize=8:tabSize=8:noTabs=false:
14670 */