Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13635, 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-21/lib/clang/21 -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/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../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=gnu11 -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 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-04-10-100350-3642-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 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int 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 int 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 int start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 int start, int *length);
300
301static void
302proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303static void
304proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305
306static void
307proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308static void
309proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310static void
311proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
312static void
313proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314static void
315proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316static void
317proto_tree_set_string(field_info *fi, const char* value);
318static void
319proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_vines(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ether(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
330static void
331proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332static void
333proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334static void
335proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336static void
337proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
338static void
339proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342static void
343proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
344static void
345proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350static void
351proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
352static void
353proto_tree_set_boolean(field_info *fi, uint64_t value);
354static void
355proto_tree_set_float(field_info *fi, float value);
356static void
357proto_tree_set_double(field_info *fi, double value);
358static void
359proto_tree_set_uint(field_info *fi, uint32_t value);
360static void
361proto_tree_set_int(field_info *fi, int32_t value);
362static void
363proto_tree_set_uint64(field_info *fi, uint64_t value);
364static void
365proto_tree_set_int64(field_info *fi, int64_t value);
366static void
367proto_tree_set_eui64(field_info *fi, const uint64_t value);
368static void
369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
370
371/* Handle type length mismatch (now filterable) expert info */
372static int proto_type_length_mismatch;
373static expert_field ei_type_length_mismatch_error;
374static expert_field ei_type_length_mismatch_warn;
375static void register_type_length_mismatch(void);
376
377/* Handle byte array string decoding errors with expert info */
378static int proto_byte_array_string_decoding_error;
379static expert_field ei_byte_array_string_decoding_failed_error;
380static void register_byte_array_string_decodinws_error(void);
381
382/* Handle date and time string decoding errors with expert info */
383static int proto_date_time_string_decoding_error;
384static expert_field ei_date_time_string_decoding_failed_error;
385static void register_date_time_string_decodinws_error(void);
386
387/* Handle string errors expert info */
388static int proto_string_errors;
389static expert_field ei_string_trailing_characters;
390static void register_string_errors(void);
391
392static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393
394/* special-case header field used within proto.c */
395static header_field_info hfi_text_only =
396 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
397int hf_text_only;
398
399/* Structure for information about a protocol */
400struct _protocol {
401 const char *name; /* long description */
402 const char *short_name; /* short description */
403 const char *filter_name; /* name of this protocol in filters */
404 GPtrArray *fields; /* fields for this protocol */
405 int proto_id; /* field ID for this protocol */
406 bool_Bool is_enabled; /* true if protocol is enabled */
407 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
408 bool_Bool can_toggle; /* true if is_enabled can be changed */
409 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
410 For dissectors that need a protocol name so they
411 can be added to a dissector table, but use the
412 parent_proto_id for things like enable/disable */
413 GList *heur_list; /* Heuristic dissectors associated with this protocol */
414};
415
416/* List of all protocols */
417static GList *protocols;
418
419/* Structure stored for deregistered g_slice */
420struct g_slice_data {
421 size_t block_size;
422 void *mem_block;
423};
424
425/* Deregistered fields */
426static GPtrArray *deregistered_fields;
427static GPtrArray *deregistered_data;
428static GPtrArray *deregistered_slice;
429
430/* indexed by prefix, contains initializers */
431static GHashTable* prefixes;
432
433/* Contains information about a field when a dissector calls
434 * proto_tree_add_item. */
435#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)))
436#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
437
438/* Contains the space for proto_nodes. */
439#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
440 node->first_child = NULL((void*)0); \
441 node->last_child = NULL((void*)0); \
442 node->next = NULL((void*)0);
443
444#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
445 wmem_free(pool, node)
446
447/* String space for protocol and field items for the GUI */
448#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;
\
449 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
450 il->value_pos = 0; \
451 il->value_len = 0;
452#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
453 wmem_free(pool, il);
454
455#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", 455, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
456 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 457
, __func__, "Unregistered hf! index=%d", hfindex)
; \
458 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", 458, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
459 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", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
460 hfinfo = gpa_hfinfo.hfi[hfindex];
461
462#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
463
464/* List which stores protocols and fields that have been registered */
465typedef struct _gpa_hfinfo_t {
466 uint32_t len;
467 uint32_t allocated_len;
468 header_field_info **hfi;
469} gpa_hfinfo_t;
470
471static gpa_hfinfo_t gpa_hfinfo;
472
473/* Hash table of abbreviations and IDs */
474static wmem_map_t *gpa_name_map;
475static header_field_info *same_name_hfinfo;
476
477/* Hash table protocol aliases. const char * -> const char * */
478static GHashTable *gpa_protocol_aliases;
479
480/*
481 * We're called repeatedly with the same field name when sorting a column.
482 * Cache our last gpa_name_map hit for faster lookups.
483 */
484static char *last_field_name;
485static header_field_info *last_hfinfo;
486
487/* Points to the first element of an array of bits, indexed by
488 a subtree item type; that array element is true if subtrees of
489 an item of that type are to be expanded. */
490static uint32_t *tree_is_expanded;
491
492/* Number of elements in that array. The entry with index 0 is not used. */
493int num_tree_types = 1;
494
495/* Name hashtables for fast detection of duplicate names */
496static GHashTable* proto_names;
497static GHashTable* proto_short_names;
498static GHashTable* proto_filter_names;
499
500static const char * const reserved_filter_names[] = {
501 /* Display filter keywords. */
502 "eq",
503 "ne",
504 "all_eq",
505 "any_eq",
506 "all_ne",
507 "any_ne",
508 "gt",
509 "ge",
510 "lt",
511 "le",
512 "bitand",
513 "bitwise_and",
514 "contains",
515 "matches",
516 "not",
517 "and",
518 "or",
519 "xor",
520 "in",
521 "any",
522 "all",
523 "true",
524 "false",
525 "nan",
526 "inf",
527 "infinity",
528 NULL((void*)0)
529};
530
531static GHashTable *proto_reserved_filter_names;
532static GQueue* saved_dir_queue;
533
534static int
535proto_compare_name(const void *p1_arg, const void *p2_arg)
536{
537 const protocol_t *p1 = (const protocol_t *)p1_arg;
538 const protocol_t *p2 = (const protocol_t *)p2_arg;
539
540 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541}
542
543static GSList *dissector_plugins;
544
545#ifdef HAVE_PLUGINS1
546void
547proto_register_plugin(const proto_plugin *plug)
548{
549 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550}
551#else /* HAVE_PLUGINS */
552void
553proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
554{
555 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 555, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
556}
557#endif /* HAVE_PLUGINS */
558
559static void
560call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
561{
562 proto_plugin *plug = (proto_plugin *)data;
563
564 if (plug->register_protoinfo) {
565 plug->register_protoinfo();
566 }
567}
568
569static void
570call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
571{
572 proto_plugin *plug = (proto_plugin *)data;
573
574 if (plug->register_handoff) {
575 plug->register_handoff();
576 }
577}
578
579void proto_pre_init(void)
580{
581 saved_dir_queue = g_queue_new();
582
583 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586
587 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 /* GHashTable has no key destructor so the cast is safe. */
590 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591 }
592
593 gpa_hfinfo.len = 0;
594 gpa_hfinfo.allocated_len = 0;
595 gpa_hfinfo.hfi = NULL((void*)0);
596 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
598 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599 deregistered_fields = g_ptr_array_new();
600 deregistered_data = g_ptr_array_new();
601 deregistered_slice = g_ptr_array_new();
602}
603
604/* initialize data structures and register protocols and fields */
605void
606proto_init(GSList *register_all_plugin_protocols_list,
607 GSList *register_all_plugin_handoffs_list,
608 register_entity_func register_func, register_entity_func handoff_func,
609 register_cb cb,
610 void *client_data)
611{
612 /* Initialize the ftype subsystem */
613 ftypes_initialize();
614
615 /* Initialize the address type subsystem */
616 address_types_initialize();
617
618 /* Register one special-case FT_TEXT_ONLY field for use when
619 converting wireshark to new-style proto_tree. These fields
620 are merely strings on the GUI tree; they are not filterable */
621 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622
623 /* Register the pseudo-protocols used for exceptions. */
624 register_show_exception();
625 register_type_length_mismatch();
626 register_byte_array_string_decodinws_error();
627 register_date_time_string_decodinws_error();
628 register_string_errors();
629 ftypes_register_pseudofields();
630 col_register_protocol();
631
632 /* Have each built-in dissector register its protocols, fields,
633 dissector tables, and dissectors to be called through a
634 handle, and do whatever one-time initialization it needs to
635 do. */
636 if (register_func != NULL((void*)0))
637 register_func(cb, client_data);
638
639 /* Now call the registration routines for all epan plugins. */
640 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
641 ((void (*)(register_cb, void *))l->data)(cb, client_data);
642 }
643
644 /* Now call the registration routines for all dissector plugins. */
645 if (cb)
646 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
647 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
648
649 /* Now call the "handoff registration" routines of all built-in
650 dissectors; those routines register the dissector in other
651 dissectors' handoff tables, and fetch any dissector handles
652 they need. */
653 if (handoff_func != NULL((void*)0))
654 handoff_func(cb, client_data);
655
656 /* Now do the same with epan plugins. */
657 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
658 ((void (*)(register_cb, void *))l->data)(cb, client_data);
659 }
660
661 /* Now do the same with dissector plugins. */
662 if (cb)
663 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
664 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
665
666 /* sort the protocols by protocol name */
667 protocols = g_list_sort(protocols, proto_compare_name);
668
669 /* sort the dissector handles in dissector tables (for -G reports
670 * and -d error messages. The GUI sorts the handles itself.) */
671 packet_all_tables_sort_handles();
672
673 /* We've assigned all the subtree type values; allocate the array
674 for them, and zero it out. */
675 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
)))
;
676}
677
678static void
679proto_cleanup_base(void)
680{
681 protocol_t *protocol;
682 header_field_info *hfinfo;
683
684 /* Free the abbrev/ID hash table */
685 if (gpa_name_map) {
686 // XXX - We don't have a wmem_map_destroy, but
687 // it does get cleaned up when epan scope is
688 // destroyed
689 //g_hash_table_destroy(gpa_name_map);
690 gpa_name_map = NULL((void*)0);
691 }
692 if (gpa_protocol_aliases) {
693 g_hash_table_destroy(gpa_protocol_aliases);
694 gpa_protocol_aliases = NULL((void*)0);
695 }
696 g_free(last_field_name);
697 last_field_name = NULL((void*)0);
698
699 while (protocols) {
700 protocol = (protocol_t *)protocols->data;
701 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", 701
, __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", 701, "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", 701, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
702 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", 702, "protocol->proto_id == hfinfo->id"
))))
;
703
704 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)
;
705 if (protocol->parent_proto_id != -1) {
706 // pino protocol
707 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 707, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
708 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"
, 708, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
709 } else {
710 if (protocol->fields) {
711 g_ptr_array_free(protocol->fields, true1);
712 }
713 g_list_free(protocol->heur_list);
714 }
715 protocols = g_list_remove(protocols, protocol);
716 g_free(protocol);
717 }
718
719 if (proto_names) {
720 g_hash_table_destroy(proto_names);
721 proto_names = NULL((void*)0);
722 }
723
724 if (proto_short_names) {
725 g_hash_table_destroy(proto_short_names);
726 proto_short_names = NULL((void*)0);
727 }
728
729 if (proto_filter_names) {
730 g_hash_table_destroy(proto_filter_names);
731 proto_filter_names = NULL((void*)0);
732 }
733
734 if (proto_reserved_filter_names) {
735 g_hash_table_destroy(proto_reserved_filter_names);
736 proto_reserved_filter_names = NULL((void*)0);
737 }
738
739 if (gpa_hfinfo.allocated_len) {
740 gpa_hfinfo.len = 0;
741 gpa_hfinfo.allocated_len = 0;
742 g_free(gpa_hfinfo.hfi);
743 gpa_hfinfo.hfi = NULL((void*)0);
744 }
745
746 if (deregistered_fields) {
747 g_ptr_array_free(deregistered_fields, true1);
748 deregistered_fields = NULL((void*)0);
749 }
750
751 if (deregistered_data) {
752 g_ptr_array_free(deregistered_data, true1);
753 deregistered_data = NULL((void*)0);
754 }
755
756 if (deregistered_slice) {
757 g_ptr_array_free(deregistered_slice, true1);
758 deregistered_slice = NULL((void*)0);
759 }
760
761 g_free(tree_is_expanded);
762 tree_is_expanded = NULL((void*)0);
763
764 if (prefixes)
765 g_hash_table_destroy(prefixes);
766
767 if (saved_dir_queue != NULL((void*)0)) {
768 g_queue_clear_full(saved_dir_queue, g_free);
769 g_queue_free(saved_dir_queue);
770 saved_dir_queue = NULL((void*)0);
771 }
772}
773
774void
775proto_cleanup(void)
776{
777 proto_free_deregistered_fields();
778 proto_cleanup_base();
779
780 g_slist_free(dissector_plugins);
781 dissector_plugins = NULL((void*)0);
782}
783
784static bool_Bool
785ws_pushd(const char* dir)
786{
787 //Save the current working directory
788 const char* save_wd = get_current_working_dir();
789 if (save_wd != NULL((void*)0))
790 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
791
792 //Change to the new one
793#ifdef _WIN32
794 SetCurrentDirectory(utf_8to16(dir));
795 return true1;
796#else
797 return (chdir(dir) == 0);
798#endif
799}
800
801static bool_Bool
802ws_popd(void)
803{
804 int ret = 0;
805 char* saved_wd = g_queue_pop_head(saved_dir_queue);
806 if (saved_wd == NULL((void*)0))
807 return false0;
808
809 //Restore the previous one
810#ifdef _WIN32
811 SetCurrentDirectory(utf_8to16(saved_wd));
812#else
813 ret = chdir(saved_wd);
814#endif
815 g_free(saved_wd);
816 return (ret == 0);
817}
818
819void
820proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
821{
822 if (ws_pushd(dir))
823 {
824 func(param);
825 ws_popd();
826 }
827}
828
829static bool_Bool
830// NOLINTNEXTLINE(misc-no-recursion)
831proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
832 void *data)
833{
834 proto_node *pnode = tree;
835 proto_node *child;
836 proto_node *current;
837
838 if (func(pnode, data))
839 return true1;
840
841 child = pnode->first_child;
842 while (child != NULL((void*)0)) {
843 /*
844 * The routine we call might modify the child, e.g. by
845 * freeing it, so we get the child's successor before
846 * calling that routine.
847 */
848 current = child;
849 child = current->next;
850 // We recurse here, but we're limited by prefs.gui_max_tree_depth
851 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
852 return true1;
853 }
854
855 return false0;
856}
857
858void
859proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
860 void *data)
861{
862 proto_node *node = tree;
863 proto_node *current;
864
865 if (!node)
866 return;
867
868 node = node->first_child;
869 while (node != NULL((void*)0)) {
870 current = node;
871 node = current->next;
872 func((proto_tree *)current, data);
873 }
874}
875
876static void
877free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
878{
879 GPtrArray *ptrs = (GPtrArray *)value;
880 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
881 header_field_info *hfinfo;
882
883 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", 883, __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", 883, "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", 883, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
884 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
885 /* when a field is referenced by a filter this also
886 affects the refcount for the parent protocol so we need
887 to adjust the refcount for the parent as well
888 */
889 if (hfinfo->parent != -1) {
890 header_field_info *parent_hfinfo;
891 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", 891
, __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", 891, "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", 891, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
892 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
893 }
894 hfinfo->ref_type = HF_REF_TYPE_NONE;
895 }
896
897 g_ptr_array_free(ptrs, true1);
898}
899
900static void
901proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
902{
903 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
904
905 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
906
907 if (finfo) {
908 fvalue_free(finfo->value);
909 finfo->value = NULL((void*)0);
910 }
911}
912
913void
914proto_tree_reset(proto_tree *tree)
915{
916 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
917
918 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
919
920 /* free tree data */
921 if (tree_data->interesting_hfids) {
922 /* Free all the GPtrArray's in the interesting_hfids hash. */
923 g_hash_table_foreach(tree_data->interesting_hfids,
924 free_GPtrArray_value, NULL((void*)0));
925
926 /* And then remove all values. */
927 g_hash_table_remove_all(tree_data->interesting_hfids);
928 }
929
930 /* Reset track of the number of children */
931 tree_data->count = 0;
932
933 /* Reset our loop checks */
934 tree_data->idle_count_ds_tvb = NULL((void*)0);
935 tree_data->max_start = 0;
936 tree_data->start_idle_count = 0;
937
938 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
939}
940
941/* frees the resources that the dissection a proto_tree uses */
942void
943proto_tree_free(proto_tree *tree)
944{
945 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
946
947 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
948
949 /* free tree data */
950 if (tree_data->interesting_hfids) {
951 /* Free all the GPtrArray's in the interesting_hfids hash. */
952 g_hash_table_foreach(tree_data->interesting_hfids,
953 free_GPtrArray_value, NULL((void*)0));
954
955 /* And then destroy the hash. */
956 g_hash_table_destroy(tree_data->interesting_hfids);
957 }
958
959 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)
;
960
961 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
962}
963
964/* Is the parsing being done for a visible proto_tree or an invisible one?
965 * By setting this correctly, the proto_tree creation is sped up by not
966 * having to call vsnprintf and copy strings around.
967 */
968bool_Bool
969proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
970{
971 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
972
973 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
974
975 return old_visible;
976}
977
978void
979proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
980{
981 if (tree)
982 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
983}
984
985/* Assume dissector set only its protocol fields.
986 This function is called by dissectors and allows the speeding up of filtering
987 in wireshark; if this function returns false it is safe to reset tree to NULL
988 and thus skip calling most of the expensive proto_tree_add_...()
989 functions.
990 If the tree is visible we implicitly assume the field is referenced.
991*/
992bool_Bool
993proto_field_is_referenced(proto_tree *tree, int proto_id)
994{
995 register header_field_info *hfinfo;
996
997
998 if (!tree)
999 return false0;
1000
1001 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1002 return true1;
1003
1004 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", 1004, __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", 1004,
"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", 1004, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1005 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1006 return true1;
1007
1008 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1009 return true1;
1010
1011 return false0;
1012}
1013
1014
1015/* Finds a record in the hfinfo array by id. */
1016header_field_info *
1017proto_registrar_get_nth(unsigned hfindex)
1018{
1019 register header_field_info *hfinfo;
1020
1021 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", 1021, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1021,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1021, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1022 return hfinfo;
1023}
1024
1025
1026/* Prefix initialization
1027 * this allows for a dissector to register a display filter name prefix
1028 * so that it can delay the initialization of the hf array as long as
1029 * possible.
1030 */
1031
1032/* compute a hash for the part before the dot of a display filter */
1033static unsigned
1034prefix_hash (const void *key) {
1035 /* end the string at the dot and compute its hash */
1036 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1037 char* c = copy;
1038 unsigned tmp;
1039
1040 for (; *c; c++) {
1041 if (*c == '.') {
1042 *c = 0;
1043 break;
1044 }
1045 }
1046
1047 tmp = wmem_str_hash(copy);
1048 g_free(copy);
1049 return tmp;
1050}
1051
1052/* are both strings equal up to the end or the dot? */
1053static gboolean
1054prefix_equal (const void *ap, const void *bp) {
1055 const char* a = (const char *)ap;
1056 const char* b = (const char *)bp;
1057
1058 do {
1059 char ac = *a++;
1060 char bc = *b++;
1061
1062 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1063
1064 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1065 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1066
1067 if (ac != bc) return FALSE(0);
1068 } while (1);
1069
1070 return FALSE(0);
1071}
1072
1073/* Register a new prefix for "delayed" initialization of field arrays */
1074void
1075proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1076 if (! prefixes ) {
1077 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1078 }
1079
1080 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1081}
1082
1083/* helper to call all prefix initializers */
1084static gboolean
1085initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1086 ((prefix_initializer_t)v)((const char *)k);
1087 return TRUE(!(0));
1088}
1089
1090/** Initialize every remaining uninitialized prefix. */
1091void
1092proto_initialize_all_prefixes(void) {
1093 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1094}
1095
1096/* Finds a record in the hfinfo array by name.
1097 * If it fails to find it in the already registered fields,
1098 * it tries to find and call an initializer in the prefixes
1099 * table and if so it looks again.
1100 */
1101
1102header_field_info *
1103proto_registrar_get_byname(const char *field_name)
1104{
1105 header_field_info *hfinfo;
1106 prefix_initializer_t pi;
1107
1108 if (!field_name)
1109 return NULL((void*)0);
1110
1111 if (g_strcmp0(field_name, last_field_name) == 0) {
1112 return last_hfinfo;
1113 }
1114
1115 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1116
1117 if (hfinfo) {
1118 g_free(last_field_name);
1119 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1120 last_hfinfo = hfinfo;
1121 return hfinfo;
1122 }
1123
1124 if (!prefixes)
1125 return NULL((void*)0);
1126
1127 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1128 pi(field_name);
1129 g_hash_table_remove(prefixes, field_name);
1130 } else {
1131 return NULL((void*)0);
1132 }
1133
1134 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1135
1136 if (hfinfo) {
1137 g_free(last_field_name);
1138 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1139 last_hfinfo = hfinfo;
1140 }
1141 return hfinfo;
1142}
1143
1144header_field_info*
1145proto_registrar_get_byalias(const char *alias_name)
1146{
1147 if (!alias_name) {
1148 return NULL((void*)0);
1149 }
1150
1151 /* Find our aliased protocol. */
1152 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1153 char *dot = strchr(an_copy, '.');
1154 if (dot) {
1155 *dot = '\0';
1156 }
1157 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1158 if (!proto_pfx) {
1159 g_free(an_copy);
1160 return NULL((void*)0);
1161 }
1162
1163 /* Construct our aliased field and look it up. */
1164 GString *filter_name = g_string_new(proto_pfx);
1165 if (dot) {
1166 g_string_append_printf(filter_name, ".%s", dot+1);
1167 }
1168 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1169 g_free(an_copy);
1170 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)))))
;
1171
1172 return hfinfo;
1173}
1174
1175int
1176proto_registrar_get_id_byname(const char *field_name)
1177{
1178 header_field_info *hfinfo;
1179
1180 hfinfo = proto_registrar_get_byname(field_name);
1181
1182 if (!hfinfo)
1183 return -1;
1184
1185 return hfinfo->id;
1186}
1187
1188static int
1189label_strcat_flags(const header_field_info *hfinfo)
1190{
1191 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1192 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1193
1194 return 0;
1195}
1196
1197static char *
1198format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1199 const uint8_t *bytes, unsigned length, size_t max_str_len)
1200{
1201 char *str = NULL((void*)0);
1202 const uint8_t *p;
1203 bool_Bool is_printable;
1204
1205 if (bytes) {
1206 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1207 /*
1208 * If all bytes are valid and printable UTF-8, show the
1209 * bytes as a string - in quotes to indicate that it's
1210 * a string.
1211 */
1212 if (isprint_utf8_string((const char*)bytes, length)) {
1213 str = wmem_strdup_printf(scope, "\"%.*s\"",
1214 (int)length, bytes);
1215 return str;
1216 }
1217 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1218 /*
1219 * Check whether all bytes are printable.
1220 */
1221 is_printable = true1;
1222 for (p = bytes; p < bytes+length; p++) {
1223 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1224 /* Not printable. */
1225 is_printable = false0;
1226 break;
1227 }
1228 }
1229
1230 /*
1231 * If all bytes are printable ASCII, show the bytes
1232 * as a string - in quotes to indicate that it's
1233 * a string.
1234 */
1235 if (is_printable) {
1236 str = wmem_strdup_printf(scope, "\"%.*s\"",
1237 (int)length, bytes);
1238 return str;
1239 }
1240 }
1241
1242 /*
1243 * Either it's not printable ASCII, or we don't care whether
1244 * it's printable ASCII; show it as hex bytes.
1245 */
1246 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1247 case SEP_DOT:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1249 break;
1250 case SEP_DASH:
1251 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1252 break;
1253 case SEP_COLON:
1254 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1255 break;
1256 case SEP_SPACE:
1257 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1258 break;
1259 case BASE_NONE:
1260 default:
1261 if (prefs.display_byte_fields_with_spaces) {
1262 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1263 } else {
1264 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1265 }
1266 break;
1267 }
1268 }
1269 else {
1270 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1271 str = wmem_strdup(scope, "<none>");
1272 } else {
1273 str = wmem_strdup(scope, "<MISSING>");
1274 }
1275 }
1276 return str;
1277}
1278
1279static char *
1280format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1281 const uint8_t *bytes, unsigned length)
1282{
1283 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1284}
1285
1286static void
1287ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1288{
1289 subtree_lvl *pushed_tree;
1290
1291 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"
, 1291, "ptvc->pushed_tree_max <= 256-8"))))
;
1292 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1293
1294 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1295 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1295, "pushed_tree != ((void*)0)"
))))
;
1296 ptvc->pushed_tree = pushed_tree;
1297}
1298
1299static void
1300ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1301{
1302 ptvc->pushed_tree = NULL((void*)0);
1303 ptvc->pushed_tree_max = 0;
1304 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", 1304, "ptvc->pushed_tree_index == 0"
))))
;
1305 ptvc->pushed_tree_index = 0;
1306}
1307
1308/* Allocates an initializes a ptvcursor_t with 3 variables:
1309 * proto_tree, tvbuff, and offset. */
1310ptvcursor_t *
1311ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1312{
1313 ptvcursor_t *ptvc;
1314
1315 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1316 ptvc->scope = scope;
1317 ptvc->tree = tree;
1318 ptvc->tvb = tvb;
1319 ptvc->offset = offset;
1320 ptvc->pushed_tree = NULL((void*)0);
1321 ptvc->pushed_tree_max = 0;
1322 ptvc->pushed_tree_index = 0;
1323 return ptvc;
1324}
1325
1326
1327/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1328void
1329ptvcursor_free(ptvcursor_t *ptvc)
1330{
1331 ptvcursor_free_subtree_levels(ptvc);
1332 wmem_free(ptvc->scope, ptvc);
1333}
1334
1335/* Returns tvbuff. */
1336tvbuff_t *
1337ptvcursor_tvbuff(ptvcursor_t *ptvc)
1338{
1339 return ptvc->tvb;
1340}
1341
1342/* Returns current offset. */
1343unsigned
1344ptvcursor_current_offset(ptvcursor_t *ptvc)
1345{
1346 return ptvc->offset;
1347}
1348
1349proto_tree *
1350ptvcursor_tree(ptvcursor_t *ptvc)
1351{
1352 if (!ptvc)
1353 return NULL((void*)0);
1354
1355 return ptvc->tree;
1356}
1357
1358void
1359ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1360{
1361 ptvc->tree = tree;
1362}
1363
1364/* creates a subtree, sets it as the working tree and pushes the old working tree */
1365proto_tree *
1366ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1367{
1368 subtree_lvl *subtree;
1369 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1370 ptvcursor_new_subtree_levels(ptvc);
1371
1372 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1373 subtree->tree = ptvc->tree;
1374 subtree->it= NULL((void*)0);
1375 ptvc->pushed_tree_index++;
1376 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1377}
1378
1379/* pops a subtree */
1380void
1381ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1382{
1383 subtree_lvl *subtree;
1384
1385 if (ptvc->pushed_tree_index <= 0)
1386 return;
1387
1388 ptvc->pushed_tree_index--;
1389 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1390 if (subtree->it != NULL((void*)0))
1391 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1392
1393 ptvc->tree = subtree->tree;
1394}
1395
1396/* saves the current tvb offset and the item in the current subtree level */
1397static void
1398ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1399{
1400 subtree_lvl *subtree;
1401
1402 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", 1402, "ptvc->pushed_tree_index > 0"
))))
;
1403
1404 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1405 subtree->it = it;
1406 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1407}
1408
1409/* Creates a subtree and adds it to the cursor as the working tree but does not
1410 * save the old working tree */
1411proto_tree *
1412ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1413{
1414 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1415 return ptvc->tree;
1416}
1417
1418static proto_tree *
1419ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1420{
1421 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1422 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1423 ptvcursor_subtree_set_item(ptvc, it);
1424 return ptvcursor_tree(ptvc);
1425}
1426
1427/* Add an item to the tree and create a subtree
1428 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1429 * In this case, when the subtree will be closed, the parent item length will
1430 * be equal to the advancement of the cursor since the creation of the subtree.
1431 */
1432proto_tree *
1433ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1434 const unsigned encoding, int ett_subtree)
1435{
1436 proto_item *it;
1437
1438 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1439 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1440}
1441
1442static proto_item *
1443proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1444
1445/* Add a text node to the tree and create a subtree
1446 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447 * In this case, when the subtree will be closed, the item length will be equal
1448 * to the advancement of the cursor since the creation of the subtree.
1449 */
1450proto_tree *
1451ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452 int ett_subtree, const char *format, ...)
1453{
1454 proto_item *pi;
1455 va_list ap;
1456 header_field_info *hfinfo;
1457 proto_tree *tree;
1458
1459 tree = ptvcursor_tree(ptvc);
1460
1461 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1462
1463 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", 1463
, __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", 1463, "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", 1463, "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", 1463, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1464
1465 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466 ptvcursor_current_offset(ptvc), length);
1467
1468 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1469
1470 va_start(ap, format)__builtin_va_start(ap, format);
1471 proto_tree_set_representation(pi, format, ap);
1472 va_end(ap)__builtin_va_end(ap);
1473
1474 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475}
1476
1477/* Add a text-only node, leaving it to our caller to fill the text in */
1478static proto_item *
1479proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1480{
1481 proto_item *pi;
1482
1483 if (tree == NULL((void*)0))
1484 return NULL((void*)0);
1485
1486 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487
1488 return pi;
1489}
1490
1491/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492proto_item *
1493proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1494 const char *format, ...)
1495{
1496 proto_item *pi;
1497 va_list ap;
1498 header_field_info *hfinfo;
1499
1500 if (length == -1) {
1501 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502 } else {
1503 tvb_ensure_bytes_exist(tvb, start, length);
1504 }
1505
1506 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507
1508 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", 1508
, __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", 1508, "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", 1508, "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", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1509
1510 pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1513
1514 va_start(ap, format)__builtin_va_start(ap, format);
1515 proto_tree_set_representation(pi, format, ap);
1516 va_end(ap)__builtin_va_end(ap);
1517
1518 return pi;
1519}
1520
1521/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522proto_item *
1523proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1524 int length, const char *format, va_list ap)
1525{
1526 proto_item *pi;
1527 header_field_info *hfinfo;
1528
1529 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 * the length to be what's in the tvbuff if length is -1, and the
1532 * minimum of length and what's in the tvbuff if not.
1533 */
1534
1535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536
1537 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", 1537
, __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", 1537, "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", 1537, "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", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1538
1539 pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1542
1543 proto_tree_set_representation(pi, format, ap);
1544
1545 return pi;
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1552{
1553 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554}
1555
1556/* Add a text-only node that creates a subtree underneath.
1557 */
1558proto_tree *
1559proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560{
1561 proto_tree *pt;
1562 proto_item *pi;
1563 va_list ap;
1564
1565 va_start(ap, format)__builtin_va_start(ap, format);
1566 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567 va_end(ap)__builtin_va_end(ap);
1568
1569 if (tree_item != NULL((void*)0))
1570 *tree_item = pi;
1571
1572 pt = proto_item_add_subtree(pi, idx);
1573
1574 return pt;
1575}
1576
1577/* Add a text-only node for debugging purposes. The caller doesn't need
1578 * to worry about tvbuff, start, or length. Debug message gets sent to
1579 * STDOUT, too */
1580proto_item *
1581proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582{
1583 proto_item *pi;
1584 va_list ap;
1585
1586 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1587
1588 if (pi) {
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 proto_tree_set_representation(pi, format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 }
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 vprintf(format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 printf("\n");
1597
1598 return pi;
1599}
1600
1601proto_item *
1602proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1603{
1604 proto_item *pi;
1605 header_field_info *hfinfo;
1606
1607 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1608
1609 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", 1609
, __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", 1609, "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", 1609, "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", 1609, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1610
1611 pi = proto_tree_add_text_node(tree, tvb, start, length);
1612
1613 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1613, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1614
1615 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616
1617 return pi;
1618}
1619
1620proto_item *
1621proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1622{
1623 proto_item *pi;
1624 header_field_info *hfinfo;
1625 char *str;
1626
1627 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1628
1629 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", 1629
, __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", 1629, "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", 1629, "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", 1629, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1630
1631 pi = proto_tree_add_text_node(tree, tvb, start, length);
1632
1633 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1633, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1634
1635 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1636 proto_item_set_text(pi, "%s", str);
1637 wmem_free(NULL((void*)0), str);
1638
1639 return pi;
1640}
1641
1642void proto_report_dissector_bug(const char *format, ...)
1643{
1644 va_list args;
1645
1646 if (wireshark_abort_on_dissector_bug) {
1647 /*
1648 * Try to have the error message show up in the crash
1649 * information.
1650 */
1651 va_start(args, format)__builtin_va_start(args, format);
1652 ws_vadd_crash_info(format, args);
1653 va_end(args)__builtin_va_end(args);
1654
1655 /*
1656 * Print the error message.
1657 */
1658 va_start(args, format)__builtin_va_start(args, format);
1659 vfprintf(stderrstderr, format, args);
1660 va_end(args)__builtin_va_end(args);
1661 putc('\n', stderrstderr);
1662
1663 /*
1664 * And crash.
1665 */
1666 abort();
1667 } else {
1668 va_start(args, format)__builtin_va_start(args, format);
1669 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1670 va_end(args)__builtin_va_end(args);
1671 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1671
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1672 }
1673}
1674
1675/* We could probably get away with changing is_error to a minimum length value. */
1676static void
1677report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1678{
1679 if (is_error) {
1680 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681 } else {
1682 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683 }
1684
1685 if (is_error) {
1686 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1687 }
1688}
1689
1690static uint32_t
1691get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692{
1693 uint32_t value;
1694 bool_Bool length_error;
1695
1696 switch (length) {
1697
1698 case 1:
1699 value = tvb_get_uint8(tvb, offset);
1700 if (encoding & ENC_ZIGBEE0x40000000) {
1701 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702 value = 0;
1703 }
1704 }
1705 break;
1706
1707 case 2:
1708 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1709 : tvb_get_ntohs(tvb, offset);
1710 if (encoding & ENC_ZIGBEE0x40000000) {
1711 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712 value = 0;
1713 }
1714 }
1715 break;
1716
1717 case 3:
1718 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1719 : tvb_get_ntoh24(tvb, offset);
1720 break;
1721
1722 case 4:
1723 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 : tvb_get_ntohl(tvb, offset);
1725 break;
1726
1727 default:
1728 if (length < 1) {
1729 length_error = true1;
1730 value = 0;
1731 } else {
1732 length_error = false0;
1733 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1734 : tvb_get_ntohl(tvb, offset);
1735 }
1736 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737 break;
1738 }
1739 return value;
1740}
1741
1742static inline uint64_t
1743get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1744{
1745 uint64_t value;
1746
1747 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748
1749 if (length < 1 || length > 8) {
1750 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751 }
1752
1753 return value;
1754}
1755
1756static int32_t
1757get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1758{
1759 int32_t value;
1760 bool_Bool length_error;
1761
1762 switch (length) {
1763
1764 case 1:
1765 value = tvb_get_int8(tvb, offset);
1766 break;
1767
1768 case 2:
1769 value = encoding ? tvb_get_letohis(tvb, offset)
1770 : tvb_get_ntohis(tvb, offset);
1771 break;
1772
1773 case 3:
1774 value = encoding ? tvb_get_letohi24(tvb, offset)
1775 : tvb_get_ntohi24(tvb, offset);
1776 break;
1777
1778 case 4:
1779 value = encoding ? tvb_get_letohil(tvb, offset)
1780 : tvb_get_ntohil(tvb, offset);
1781 break;
1782
1783 default:
1784 if (length < 1) {
1785 length_error = true1;
1786 value = 0;
1787 } else {
1788 length_error = false0;
1789 value = encoding ? tvb_get_letohil(tvb, offset)
1790 : tvb_get_ntohil(tvb, offset);
1791 }
1792 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793 break;
1794 }
1795 return value;
1796}
1797
1798/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799 * be cast-able as a int64_t. This is weird, but what the code has always done.
1800 */
1801static inline uint64_t
1802get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1803{
1804 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805
1806 switch (length) {
1807 case 7:
1808 value = ws_sign_ext64(value, 56);
1809 break;
1810 case 6:
1811 value = ws_sign_ext64(value, 48);
1812 break;
1813 case 5:
1814 value = ws_sign_ext64(value, 40);
1815 break;
1816 case 4:
1817 value = ws_sign_ext64(value, 32);
1818 break;
1819 case 3:
1820 value = ws_sign_ext64(value, 24);
1821 break;
1822 case 2:
1823 value = ws_sign_ext64(value, 16);
1824 break;
1825 case 1:
1826 value = ws_sign_ext64(value, 8);
1827 break;
1828 }
1829
1830 return value;
1831}
1832
1833/* For FT_STRING */
1834static inline const uint8_t *
1835get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1836 int length, int *ret_length, const unsigned encoding)
1837{
1838 if (length == -1) {
1839 length = tvb_ensure_captured_length_remaining(tvb, start);
1840 }
1841 *ret_length = length;
1842 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843}
1844
1845/* For FT_STRINGZ */
1846static inline const uint8_t *
1847get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848 int start, int length, int *ret_length, const unsigned encoding)
1849{
1850 const uint8_t *value;
1851
1852 if (length < -1) {
1853 report_type_length_mismatch(tree, "a string", length, true1);
1854 }
1855
1856 /* XXX - Ideally, every "null-terminated string which fits into a
1857 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860 * as unknown length as well (since there is a trailing '\0', the real
1861 * length is never zero), allowing switching to unsigned lengths.
1862 */
1863 if (length == -1) {
1864 /* This can throw an exception */
1865 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866 } else {
1867 /* In this case, length signifies the length of the string.
1868 *
1869 * This could either be a null-padded string, which doesn't
1870 * necessarily have a '\0' at the end, or a null-terminated
1871 * string, with a trailing '\0'. (Yes, there are cases
1872 * where you have a string that's both counted and null-
1873 * terminated.)
1874 *
1875 * In the first case, we must allocate a buffer of length
1876 * "length+1", to make room for a trailing '\0'.
1877 *
1878 * In the second case, we don't assume that there is a
1879 * trailing '\0' there, as the packet might be malformed.
1880 * (XXX - should we throw an exception if there's no
1881 * trailing '\0'?) Therefore, we allocate a buffer of
1882 * length "length+1", and put in a trailing '\0', just to
1883 * be safe.
1884 *
1885 * (XXX - this would change if we made string values counted
1886 * rather than null-terminated.)
1887 */
1888 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889 }
1890 *ret_length = length;
1891 return value;
1892}
1893
1894/* For FT_UINT_STRING */
1895static inline const uint8_t *
1896get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897 tvbuff_t *tvb, int start, int length, int *ret_length,
1898 const unsigned encoding)
1899{
1900 uint32_t n;
1901 const uint8_t *value;
1902
1903 /* I believe it's ok if this is called with a NULL tree */
1904 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1905 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906 length += n;
1907 *ret_length = length;
1908 return value;
1909}
1910
1911/* For FT_STRINGZPAD */
1912static inline const uint8_t *
1913get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1914 int length, int *ret_length, const unsigned encoding)
1915{
1916 /*
1917 * XXX - currently, string values are null-
1918 * terminated, so a "zero-padded" string
1919 * isn't special. If we represent string
1920 * values as something that includes a counted
1921 * array of bytes, we'll need to strip the
1922 * trailing NULs.
1923 */
1924 if (length == -1) {
1925 length = tvb_ensure_captured_length_remaining(tvb, start);
1926 }
1927 *ret_length = length;
1928 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929}
1930
1931/* For FT_STRINGZTRUNC */
1932static inline const uint8_t *
1933get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1934 int length, int *ret_length, const unsigned encoding)
1935{
1936 /*
1937 * XXX - currently, string values are null-
1938 * terminated, so a "zero-truncated" string
1939 * isn't special. If we represent string
1940 * values as something that includes a counted
1941 * array of bytes, we'll need to strip everything
1942 * starting with the terminating NUL.
1943 */
1944 if (length == -1) {
1945 length = tvb_ensure_captured_length_remaining(tvb, start);
1946 }
1947 *ret_length = length;
1948 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949}
1950
1951/*
1952 * Deltas between the epochs for various non-UN*X time stamp formats and
1953 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954 * stamp format.
1955 */
1956
1957/*
1958 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959 * XXX - if it's OK if this is unsigned, can we just use
1960 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961 */
1962#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1963
1964/*
1965 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966 */
1967#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1968
1969/* this can be called when there is no tree, so tree may be null */
1970static void
1971get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1972 const int length, const unsigned encoding, nstime_t *time_stamp,
1973 const bool_Bool is_relative)
1974{
1975 uint32_t tmpsecs;
1976 uint64_t tmp64secs;
1977 uint64_t todusecs;
1978
1979 switch (encoding) {
1980
1981 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1982 /*
1983 * If the length is 16, 8-byte seconds, followed
1984 * by 8-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 12, 8-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 8, 4-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * For absolute times, the seconds are seconds
1996 * since the UN*X epoch.
1997 */
1998 if (length == 16) {
1999 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2000 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001 } else if (length == 12) {
2002 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2003 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004 } else if (length == 8) {
2005 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2006 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007 } else if (length == 4) {
2008 /*
2009 * Backwards compatibility.
2010 * ENC_TIME_SECS_NSECS is 0; using
2011 * ENC_BIG_ENDIAN by itself with a 4-byte
2012 * time-in-seconds value was done in the
2013 * past.
2014 */
2015 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2016 time_stamp->nsecs = 0;
2017 } else {
2018 time_stamp->secs = 0;
2019 time_stamp->nsecs = 0;
2020 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021 }
2022 break;
2023
2024 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2025 /*
2026 * If the length is 16, 8-byte seconds, followed
2027 * by 8-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 12, 8-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 8, 4-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * For absolute times, the seconds are seconds
2039 * since the UN*X epoch.
2040 */
2041 if (length == 16) {
2042 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2043 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044 } else if (length == 12) {
2045 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2046 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047 } else if (length == 8) {
2048 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2049 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050 } else if (length == 4) {
2051 /*
2052 * Backwards compatibility.
2053 * ENC_TIME_SECS_NSECS is 0; using
2054 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055 * time-in-seconds value was done in the
2056 * past.
2057 */
2058 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2059 time_stamp->nsecs = 0;
2060 } else {
2061 time_stamp->secs = 0;
2062 time_stamp->nsecs = 0;
2063 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064 }
2065 break;
2066
2067 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2068 /*
2069 * NTP time stamp, big-endian.
2070 * Only supported for absolute times.
2071 */
2072 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2072, "!is_relative"
))))
;
2073
2074 /* We need a temporary variable here so the unsigned math
2075 * works correctly (for years > 2036 according to RFC 2030
2076 * chapter 3).
2077 *
2078 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080 * If bit 0 is not set, the time is in the range 2036-2104 and
2081 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082 */
2083 tmpsecs = tvb_get_ntohl(tvb, start);
2084 if ((tmpsecs & 0x80000000) != 0)
2085 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2086 else
2087 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2088
2089 if (length == 8) {
2090 tmp64secs = tvb_get_ntoh64(tvb, start);
2091 if (tmp64secs == 0) {
2092 //This is "NULL" time
2093 time_stamp->secs = 0;
2094 time_stamp->nsecs = 0;
2095 } else {
2096 /*
2097 * Convert 1/2^32s of a second to
2098 * nanoseconds.
2099 */
2100 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 }
2102 } else if (length == 4) {
2103 /*
2104 * Backwards compatibility.
2105 */
2106 if (tmpsecs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 }
2110 time_stamp->nsecs = 0;
2111 } else {
2112 time_stamp->secs = 0;
2113 time_stamp->nsecs = 0;
2114 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115 }
2116 break;
2117
2118 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2119 /*
2120 * NTP time stamp, little-endian.
2121 * Only supported for absolute times.
2122 *
2123 * NTP doesn't use this, because it's an Internet format
2124 * and hence big-endian. Any implementation must decide
2125 * whether the NTP timestamp is a 64-bit unsigned fixed
2126 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127 * with a 32-bit unsigned seconds field followed by a
2128 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129 * the previous two).
2130 *
2131 * XXX: We do the latter, but no dissector uses this format.
2132 * OTOH, ERF timestamps do the former, so perhaps we
2133 * should switch the interpretation so that packet-erf.c
2134 * could use this directly?
2135 */
2136 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative"
))))
;
2137
2138 /* We need a temporary variable here so the unsigned math
2139 * works correctly (for years > 2036 according to RFC 2030
2140 * chapter 3).
2141 *
2142 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144 * If bit 0 is not set, the time is in the range 2036-2104 and
2145 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146 */
2147 tmpsecs = tvb_get_letohl(tvb, start);
2148 if ((tmpsecs & 0x80000000) != 0)
2149 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2150 else
2151 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2152
2153 if (length == 8) {
2154 tmp64secs = tvb_get_letoh64(tvb, start);
2155 if (tmp64secs == 0) {
2156 //This is "NULL" time
2157 time_stamp->secs = 0;
2158 time_stamp->nsecs = 0;
2159 } else {
2160 /*
2161 * Convert 1/2^32s of a second to
2162 * nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165 }
2166 } else if (length == 4) {
2167 /*
2168 * Backwards compatibility.
2169 */
2170 if (tmpsecs == 0) {
2171 //This is "NULL" time
2172 time_stamp->secs = 0;
2173 }
2174 time_stamp->nsecs = 0;
2175 } else {
2176 time_stamp->secs = 0;
2177 time_stamp->nsecs = 0;
2178 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179 }
2180 break;
2181
2182 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2183 /*
2184 * S/3x0 and z/Architecture TOD clock time stamp,
2185 * big-endian. The epoch is January 1, 1900,
2186 * 00:00:00 (proleptic?) UTC.
2187 *
2188 * Only supported for absolute times.
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "length == 8"
))))
;
2192
2193 if (length == 8) {
2194 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2195 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2196 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2197 } else {
2198 time_stamp->secs = 0;
2199 time_stamp->nsecs = 0;
2200 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201 }
2202 break;
2203
2204 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2205 /*
2206 * S/3x0 and z/Architecture TOD clock time stamp,
2207 * little-endian. The epoch is January 1, 1900,
2208 * 00:00:00 (proleptic?) UTC.
2209 *
2210 * Only supported for absolute times.
2211 */
2212 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2212, "!is_relative"
))))
;
2213
2214 if (length == 8) {
2215 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2216 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2217 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2218 } else {
2219 time_stamp->secs = 0;
2220 time_stamp->nsecs = 0;
2221 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222 }
2223 break;
2224
2225 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2226 /*
2227 * Time stamp using the same seconds/fraction format
2228 * as NTP, but with the origin of the time stamp being
2229 * the UNIX epoch rather than the NTP epoch; big-
2230 * endian.
2231 *
2232 * Only supported for absolute times.
2233 */
2234 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2234, "!is_relative"
))))
;
2235
2236 if (length == 8) {
2237 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238 /*
2239 * Convert 1/2^32s of a second to nanoseconds.
2240 */
2241 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242 } else {
2243 time_stamp->secs = 0;
2244 time_stamp->nsecs = 0;
2245 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246 }
2247 break;
2248
2249 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2250 /*
2251 * Time stamp using the same seconds/fraction format
2252 * as NTP, but with the origin of the time stamp being
2253 * the UNIX epoch rather than the NTP epoch; little-
2254 * endian.
2255 *
2256 * Only supported for absolute times.
2257 *
2258 * The RTPS specification explicitly supports Little
2259 * Endian encoding. In one place, it states that its
2260 * Time_t representation "is the one defined by ...
2261 * RFC 1305", but in another explicitly defines it as
2262 * a struct consisting of an 32 bit unsigned seconds
2263 * field and a 32 bit unsigned fraction field, not a 64
2264 * bit fixed point, so we do that here.
2265 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266 */
2267 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2267, "!is_relative"
))))
;
2268
2269 if (length == 8) {
2270 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271 /*
2272 * Convert 1/2^32s of a second to nanoseconds.
2273 */
2274 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275 } else {
2276 time_stamp->secs = 0;
2277 time_stamp->nsecs = 0;
2278 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279 }
2280 break;
2281
2282 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2283 /*
2284 * MIP6 time stamp, big-endian.
2285 * A 64-bit unsigned integer field containing a timestamp. The
2286 * value indicates the number of seconds since January 1, 1970,
2287 * 00:00 UTC, by using a fixed point format. In this format, the
2288 * integer number of seconds is contained in the first 48 bits of
2289 * the field, and the remaining 16 bits indicate the number of
2290 * 1/65536 fractions of a second.
2291
2292 * Only supported for absolute times.
2293 */
2294 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2294, "!is_relative"
))))
;
2295
2296 if (length == 8) {
2297 /* We need a temporary variable here so the casting and fractions
2298 * of a second work correctly.
2299 */
2300 tmp64secs = tvb_get_ntoh48(tvb, start);
2301 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302 tmpsecs <<= 16;
2303
2304 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305 //This is "NULL" time
2306 time_stamp->secs = 0;
2307 time_stamp->nsecs = 0;
2308 } else {
2309 time_stamp->secs = (time_t)tmp64secs;
2310 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311 }
2312 } else {
2313 time_stamp->secs = 0;
2314 time_stamp->nsecs = 0;
2315 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316 }
2317 break;
2318
2319 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2320 /*
2321 * If the length is 16, 8-byte seconds, followed
2322 * by 8-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 12, 8-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 8, 4-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * For absolute times, the seconds are seconds
2334 * since the UN*X epoch.
2335 */
2336 if (length == 16) {
2337 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2338 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339 } else if (length == 12) {
2340 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2341 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342 } else if (length == 8) {
2343 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2344 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345 } else {
2346 time_stamp->secs = 0;
2347 time_stamp->nsecs = 0;
2348 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349 }
2350 break;
2351
2352 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2353 /*
2354 * If the length is 16, 8-byte seconds, followed
2355 * by 8-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 12, 8-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 8, 4-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * For absolute times, the seconds are seconds
2367 * since the UN*X epoch.
2368 */
2369 if (length == 16) {
2370 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2371 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372 } else if (length == 12) {
2373 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2374 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375 } else if (length == 8) {
2376 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2377 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378 } else {
2379 time_stamp->secs = 0;
2380 time_stamp->nsecs = 0;
2381 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382 }
2383 break;
2384
2385 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2386 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2387 /*
2388 * Seconds, 1 to 8 bytes.
2389 * For absolute times, it's seconds since the
2390 * UN*X epoch.
2391 */
2392 if (length >= 1 && length <= 8) {
2393 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394 time_stamp->nsecs = 0;
2395 } else {
2396 time_stamp->secs = 0;
2397 time_stamp->nsecs = 0;
2398 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399 }
2400 break;
2401
2402 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2403 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2404 /*
2405 * Milliseconds, 1 to 8 bytes.
2406 * For absolute times, it's milliseconds since the
2407 * UN*X epoch.
2408 */
2409 if (length >= 1 && length <= 8) {
2410 uint64_t msecs;
2411
2412 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413 time_stamp->secs = (time_t)(msecs / 1000);
2414 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415 } else {
2416 time_stamp->secs = 0;
2417 time_stamp->nsecs = 0;
2418 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419 }
2420 break;
2421
2422 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2423 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2424 /*
2425 * Microseconds, 1 to 8 bytes.
2426 * For absolute times, it's microseconds since the
2427 * UN*X epoch.
2428 */
2429 if (length >= 1 && length <= 8) {
2430 uint64_t usecs;
2431
2432 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433 time_stamp->secs = (time_t)(usecs / 1000000);
2434 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435 } else {
2436 time_stamp->secs = 0;
2437 time_stamp->nsecs = 0;
2438 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439 }
2440 break;
2441
2442 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2443 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2444 /*
2445 * nanoseconds, 1 to 8 bytes.
2446 * For absolute times, it's nanoseconds since the
2447 * UN*X epoch.
2448 */
2449
2450 if (length >= 1 && length <= 8) {
2451 uint64_t nsecs;
2452
2453 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454 time_stamp->secs = (time_t)(nsecs / 1000000000);
2455 time_stamp->nsecs = (int)(nsecs % 1000000000);
2456 } else {
2457 time_stamp->secs = 0;
2458 time_stamp->nsecs = 0;
2459 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460 }
2461 break;
2462
2463 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2464 /*
2465 * 1/64ths of a second since the UN*X epoch,
2466 * big-endian.
2467 *
2468 * Only supported for absolute times.
2469 */
2470 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2470, "!is_relative"
))))
;
2471
2472 if (length == 8) {
2473 /*
2474 * The upper 48 bits are seconds since the
2475 * UN*X epoch.
2476 */
2477 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2478 /*
2479 * The lower 16 bits are 1/2^16s of a second;
2480 * convert them to nanoseconds.
2481 *
2482 * XXX - this may give the impression of higher
2483 * precision than you actually get.
2484 */
2485 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486 } else {
2487 time_stamp->secs = 0;
2488 time_stamp->nsecs = 0;
2489 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490 }
2491 break;
2492
2493 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2494 /*
2495 * 1/64ths of a second since the UN*X epoch,
2496 * little-endian.
2497 *
2498 * Only supported for absolute times.
2499 */
2500 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2500, "!is_relative"
))))
;
2501
2502 if (length == 8) {
2503 /*
2504 * XXX - this is assuming that, if anybody
2505 * were ever to use this format - RFC 3971
2506 * doesn't, because that's an Internet
2507 * protocol, and those use network byte
2508 * order, i.e. big-endian - they'd treat it
2509 * as a 64-bit count of 1/2^16s of a second,
2510 * putting the upper 48 bits at the end.
2511 *
2512 * The lower 48 bits are seconds since the
2513 * UN*X epoch.
2514 */
2515 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2516 /*
2517 * The upper 16 bits are 1/2^16s of a second;
2518 * convert them to nanoseconds.
2519 *
2520 * XXX - this may give the impression of higher
2521 * precision than you actually get.
2522 */
2523 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524 } else {
2525 time_stamp->secs = 0;
2526 time_stamp->nsecs = 0;
2527 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528 }
2529 break;
2530
2531 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2532 /*
2533 * NTP time stamp, with 1-second resolution (i.e.,
2534 * seconds since the NTP epoch), big-endian.
2535 * Only supported for absolute times.
2536 */
2537 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2537, "!is_relative"
))))
;
2538
2539 if (length == 4) {
2540 /*
2541 * We need a temporary variable here so the unsigned math
2542 * works correctly (for years > 2036 according to RFC 2030
2543 * chapter 3).
2544 *
2545 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547 * If bit 0 is not set, the time is in the range 2036-2104 and
2548 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549 */
2550 tmpsecs = tvb_get_ntohl(tvb, start);
2551 if ((tmpsecs & 0x80000000) != 0)
2552 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2553 else
2554 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2555 time_stamp->nsecs = 0;
2556 } else {
2557 time_stamp->secs = 0;
2558 time_stamp->nsecs = 0;
2559 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560 }
2561 break;
2562
2563 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2564 /*
2565 * NTP time stamp, with 1-second resolution (i.e.,
2566 * seconds since the NTP epoch), little-endian.
2567 * Only supported for absolute times.
2568 */
2569 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2569, "!is_relative"
))))
;
2570
2571 /*
2572 * We need a temporary variable here so the unsigned math
2573 * works correctly (for years > 2036 according to RFC 2030
2574 * chapter 3).
2575 *
2576 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578 * If bit 0 is not set, the time is in the range 2036-2104 and
2579 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580 */
2581 if (length == 4) {
2582 tmpsecs = tvb_get_letohl(tvb, start);
2583 if ((tmpsecs & 0x80000000) != 0)
2584 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2585 else
2586 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2587 time_stamp->nsecs = 0;
2588 } else {
2589 time_stamp->secs = 0;
2590 time_stamp->nsecs = 0;
2591 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592 }
2593 break;
2594
2595 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2596 /*
2597 * Milliseconds, 6 to 8 bytes.
2598 * For absolute times, it's milliseconds since the
2599 * NTP epoch.
2600 *
2601 * ETSI TS 129.274 8.119 defines this as:
2602 * "a 48 bit unsigned integer in network order format
2603 * ...encoded as the number of milliseconds since
2604 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605 * rounded value of 1000 x the value of the 64-bit
2606 * timestamp (Seconds + (Fraction / (1<<32))) defined
2607 * in clause 6 of IETF RFC 5905."
2608 *
2609 * Taken literally, the part after "i.e." would
2610 * mean that the value rolls over before reaching
2611 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612 * when the 64 bit timestamp rolls over, and we have
2613 * to pick an NTP Era equivalence class to support
2614 * (such as 1968-01-20 to 2104-02-06).
2615 *
2616 * OTOH, the extra room might be used to store Era
2617 * information instead, in which case times until
2618 * 10819-08-03 can be represented with 6 bytes without
2619 * ambiguity. We handle both implementations, and assume
2620 * that times before 1968-01-20 are not represented.
2621 *
2622 * Only 6 bytes or more makes sense as an absolute
2623 * time. 5 bytes or fewer could express a span of
2624 * less than 35 years, either 1900-1934 or 2036-2070.
2625 */
2626 if (length >= 6 && length <= 8) {
2627 uint64_t msecs;
2628
2629 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630 tmp64secs = (msecs / 1000);
2631 /*
2632 * Assume that times in the first half of NTP
2633 * Era 0 really represent times in the NTP
2634 * Era 1.
2635 */
2636 if (tmp64secs >= 0x80000000)
2637 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2638 else
2639 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2640 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641 }
2642 else {
2643 time_stamp->secs = 0;
2644 time_stamp->nsecs = 0;
2645 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646 }
2647 break;
2648
2649 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2650 /*
2651 * MP4 file time stamps, big-endian.
2652 * Only supported for absolute times.
2653 */
2654 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2654, "!is_relative"
))))
;
2655
2656 if (length == 8) {
2657 tmp64secs = tvb_get_ntoh64(tvb, start);
2658 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else if (length == 4) {
2661 tmpsecs = tvb_get_ntohl(tvb, start);
2662 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else {
2665 time_stamp->secs = 0;
2666 time_stamp->nsecs = 0;
2667 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668 }
2669 break;
2670
2671 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2672 /*
2673 * Zigbee ZCL time stamps, big-endian.
2674 * Only supported for absolute times.
2675 */
2676 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2676, "!is_relative"
))))
;
2677
2678 if (length == 8) {
2679 tmp64secs = tvb_get_ntoh64(tvb, start);
2680 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else if (length == 4) {
2683 tmpsecs = tvb_get_ntohl(tvb, start);
2684 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 time_stamp->nsecs = 0;
2686 } else {
2687 time_stamp->secs = 0;
2688 time_stamp->nsecs = 0;
2689 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690 }
2691 break;
2692
2693 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2694 /*
2695 * Zigbee ZCL time stamps, little-endian.
2696 * Only supported for absolute times.
2697 */
2698 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2698, "!is_relative"
))))
;
2699
2700 if (length == 8) {
2701 tmp64secs = tvb_get_letoh64(tvb, start);
2702 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else if (length == 4) {
2705 tmpsecs = tvb_get_letohl(tvb, start);
2706 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 time_stamp->nsecs = 0;
2708 } else {
2709 time_stamp->secs = 0;
2710 time_stamp->nsecs = 0;
2711 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 }
2713 break;
2714
2715 default:
2716 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2716))
;
2717 break;
2718 }
2719}
2720
2721static void
2722tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723{
2724 const header_field_info *hfinfo = fi->hfinfo;
2725
2726 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727 GPtrArray *ptrs = NULL((void*)0);
2728
2729 if (tree_data->interesting_hfids == NULL((void*)0)) {
2730 /* Initialize the hash because we now know that it is needed */
2731 tree_data->interesting_hfids =
2732 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2733 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2736 }
2737
2738 if (!ptrs) {
2739 /* First element triggers the creation of pointer array */
2740 ptrs = g_ptr_array_new();
2741 g_hash_table_insert(tree_data->interesting_hfids,
2742 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2743 }
2744
2745 g_ptr_array_add(ptrs, fi);
2746 }
2747}
2748
2749
2750/*
2751 * Validates that field length bytes are available starting from
2752 * start (pos/neg). Throws an exception if they aren't.
2753 */
2754static void
2755test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756 int start, int length, const unsigned encoding)
2757{
2758 int size = length;
2759
2760 if (!tvb)
2761 return;
2762
2763 if ((hfinfo->type == FT_STRINGZ) ||
2764 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2765 (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
))
))) {
2766 /* If we're fetching until the end of the TVB, only validate
2767 * that the offset is within range.
2768 */
2769 if (length == -1)
2770 size = 0;
2771 }
2772
2773 tvb_ensure_bytes_exist(tvb, start, size);
2774}
2775
2776static void
2777detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778{
2779 bool_Bool found_stray_character = false0;
2780
2781 if (!string)
2782 return;
2783
2784 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2785 case ENC_ASCII0x00000000:
2786 case ENC_UTF_80x00000002:
2787 for (int i = (int)strlen(string); i < length; i++) {
2788 if (string[i] != '\0') {
2789 found_stray_character = true1;
2790 break;
2791 }
2792 }
2793 break;
2794
2795 default:
2796 break;
2797 }
2798
2799 if (found_stray_character) {
2800 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2801 }
2802}
2803
2804static void
2805free_fvalue_cb(void *data)
2806{
2807 fvalue_t *fv = (fvalue_t*)data;
2808 fvalue_free(fv);
2809}
2810
2811/* Add an item to a proto_tree, using the text label registered to that item;
2812 the item is extracted from the tvbuff handed to it. */
2813static proto_item *
2814proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815 tvbuff_t *tvb, int start, int length,
2816 unsigned encoding)
2817{
2818 proto_item *pi;
2819 uint32_t value, n;
2820 uint64_t value64;
2821 ws_in4_addr ipv4_value;
2822 float floatval;
2823 double doubleval;
2824 const char *stringval = NULL((void*)0);
2825 nstime_t time_stamp;
2826 bool_Bool length_error;
2827
2828 /* Ensure that the newly created fvalue_t is freed if we throw an
2829 * exception before adding it to the tree. (gcc creates clobbering
2830 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831 * XXX: Move the new_field_info() call inside here?
2832 */
2833 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2834
2835 switch (new_fi->hfinfo->type) {
2836 case FT_NONE:
2837 /* no value to set for FT_NONE */
2838 break;
2839
2840 case FT_PROTOCOL:
2841 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2842 break;
2843
2844 case FT_BYTES:
2845 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2846 break;
2847
2848 case FT_UINT_BYTES:
2849 n = get_uint_value(tree, tvb, start, length, encoding);
2850 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2851
2852 /* Instead of calling proto_item_set_len(), since we don't yet
2853 * have a proto_item, we set the field_info's length ourselves. */
2854 new_fi->length = n + length;
2855 break;
2856
2857 case FT_BOOLEAN:
2858 /*
2859 * Map all non-zero values to little-endian for
2860 * backwards compatibility.
2861 */
2862 if (encoding)
2863 encoding = ENC_LITTLE_ENDIAN0x80000000;
2864 proto_tree_set_boolean(new_fi,
2865 get_uint64_value(tree, tvb, start, length, encoding));
2866 break;
2867
2868 case FT_CHAR:
2869 /* XXX - make these just FT_UINT? */
2870 case FT_UINT8:
2871 case FT_UINT16:
2872 case FT_UINT24:
2873 case FT_UINT32:
2874 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2875 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2876 value = (uint32_t)value64;
2877 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2878 new_fi->flags |= FI_VARINT0x00040000;
2879 }
2880 }
2881 else {
2882 /*
2883 * Map all non-zero values to little-endian for
2884 * backwards compatibility.
2885 */
2886 if (encoding)
2887 encoding = ENC_LITTLE_ENDIAN0x80000000;
2888
2889 value = get_uint_value(tree, tvb, start, length, encoding);
2890 }
2891 proto_tree_set_uint(new_fi, value);
2892 break;
2893
2894 case FT_UINT40:
2895 case FT_UINT48:
2896 case FT_UINT56:
2897 case FT_UINT64:
2898 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2899 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2900 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2901 new_fi->flags |= FI_VARINT0x00040000;
2902 }
2903 }
2904 else {
2905 /*
2906 * Map all other non-zero values to little-endian for
2907 * backwards compatibility.
2908 */
2909 if (encoding)
2910 encoding = ENC_LITTLE_ENDIAN0x80000000;
2911
2912 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2913 }
2914 proto_tree_set_uint64(new_fi, value64);
2915 break;
2916
2917 /* XXX - make these just FT_INT? */
2918 case FT_INT8:
2919 case FT_INT16:
2920 case FT_INT24:
2921 case FT_INT32:
2922 /*
2923 * Map all non-zero values to little-endian for
2924 * backwards compatibility.
2925 */
2926 if (encoding)
2927 encoding = ENC_LITTLE_ENDIAN0x80000000;
2928 proto_tree_set_int(new_fi,
2929 get_int_value(tree, tvb, start, length, encoding));
2930 break;
2931
2932 case FT_INT40:
2933 case FT_INT48:
2934 case FT_INT56:
2935 case FT_INT64:
2936 /*
2937 * Map all non-zero values to little-endian for
2938 * backwards compatibility.
2939 */
2940 if (encoding)
2941 encoding = ENC_LITTLE_ENDIAN0x80000000;
2942 proto_tree_set_int64(new_fi,
2943 get_int64_value(tree, tvb, start, length, encoding));
2944 break;
2945
2946 case FT_IPv4:
2947 /*
2948 * Map all non-zero values to little-endian for
2949 * backwards compatibility.
2950 */
2951 if (encoding)
2952 encoding = ENC_LITTLE_ENDIAN0x80000000;
2953 if (length != FT_IPv4_LEN4) {
2954 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2955 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2956 }
2957 ipv4_value = tvb_get_ipv4(tvb, start);
2958 /*
2959 * NOTE: to support code written when
2960 * proto_tree_add_item() took a bool as its
2961 * last argument, with false meaning "big-endian"
2962 * and true meaning "little-endian", we treat any
2963 * non-zero value of "encoding" as meaning
2964 * "little-endian".
2965 */
2966 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);
2967 break;
2968
2969 case FT_IPXNET:
2970 if (length != FT_IPXNET_LEN4) {
2971 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2972 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2973 }
2974 proto_tree_set_ipxnet(new_fi,
2975 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2976 break;
2977
2978 case FT_IPv6:
2979 if (length != FT_IPv6_LEN16) {
2980 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2981 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2982 }
2983 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2984 break;
2985
2986 case FT_FCWWN:
2987 if (length != FT_FCWWN_LEN8) {
2988 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2989 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2990 }
2991 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2992 break;
2993
2994 case FT_AX25:
2995 if (length != 7) {
2996 length_error = length < 7 ? true1 : false0;
2997 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2998 }
2999 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3000 break;
3001
3002 case FT_VINES:
3003 if (length != VINES_ADDR_LEN6) {
3004 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3005 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3006 }
3007 proto_tree_set_vines_tvb(new_fi, tvb, start);
3008 break;
3009
3010 case FT_ETHER:
3011 if (length != FT_ETHER_LEN6) {
3012 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3013 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3014 }
3015 proto_tree_set_ether_tvb(new_fi, tvb, start);
3016 break;
3017
3018 case FT_EUI64:
3019 /*
3020 * Map all non-zero values to little-endian for
3021 * backwards compatibility.
3022 */
3023 if (encoding)
3024 encoding = ENC_LITTLE_ENDIAN0x80000000;
3025 if (length != FT_EUI64_LEN8) {
3026 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3027 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3028 }
3029 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3030 break;
3031 case FT_GUID:
3032 /*
3033 * Map all non-zero values to little-endian for
3034 * backwards compatibility.
3035 */
3036 if (encoding)
3037 encoding = ENC_LITTLE_ENDIAN0x80000000;
3038 if (length != FT_GUID_LEN16) {
3039 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3040 report_type_length_mismatch(tree, "a GUID", length, length_error);
3041 }
3042 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3043 break;
3044
3045 case FT_OID:
3046 case FT_REL_OID:
3047 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3048 break;
3049
3050 case FT_SYSTEM_ID:
3051 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3052 break;
3053
3054 case FT_FLOAT:
3055 /*
3056 * NOTE: to support code written when
3057 * proto_tree_add_item() took a bool as its
3058 * last argument, with false meaning "big-endian"
3059 * and true meaning "little-endian", we treat any
3060 * non-zero value of "encoding" as meaning
3061 * "little-endian".
3062 *
3063 * At some point in the future, we might
3064 * support non-IEEE-binary floating-point
3065 * formats in the encoding as well
3066 * (IEEE decimal, System/3x0, VAX).
3067 */
3068 if (encoding)
3069 encoding = ENC_LITTLE_ENDIAN0x80000000;
3070 if (length != 4) {
3071 length_error = length < 4 ? true1 : false0;
3072 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3073 }
3074 if (encoding)
3075 floatval = tvb_get_letohieee_float(tvb, start);
3076 else
3077 floatval = tvb_get_ntohieee_float(tvb, start);
3078 proto_tree_set_float(new_fi, floatval);
3079 break;
3080
3081 case FT_DOUBLE:
3082 /*
3083 * NOTE: to support code written when
3084 * proto_tree_add_item() took a bool as its
3085 * last argument, with false meaning "big-endian"
3086 * and true meaning "little-endian", we treat any
3087 * non-zero value of "encoding" as meaning
3088 * "little-endian".
3089 *
3090 * At some point in the future, we might
3091 * support non-IEEE-binary floating-point
3092 * formats in the encoding as well
3093 * (IEEE decimal, System/3x0, VAX).
3094 */
3095 if (encoding == true1)
3096 encoding = ENC_LITTLE_ENDIAN0x80000000;
3097 if (length != 8) {
3098 length_error = length < 8 ? true1 : false0;
3099 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3100 }
3101 if (encoding)
3102 doubleval = tvb_get_letohieee_double(tvb, start);
3103 else
3104 doubleval = tvb_get_ntohieee_double(tvb, start);
3105 proto_tree_set_double(new_fi, doubleval);
3106 break;
3107
3108 case FT_STRING:
3109 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3110 tvb, start, length, &length, encoding);
3111 proto_tree_set_string(new_fi, stringval);
3112
3113 /* Instead of calling proto_item_set_len(), since we
3114 * don't yet have a proto_item, we set the
3115 * field_info's length ourselves.
3116 *
3117 * XXX - our caller can't use that length to
3118 * advance an offset unless they arrange that
3119 * there always be a protocol tree into which
3120 * we're putting this item.
3121 */
3122 new_fi->length = length;
3123 break;
3124
3125 case FT_STRINGZ:
3126 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3127 tree, tvb, start, length, &length, encoding);
3128 proto_tree_set_string(new_fi, stringval);
3129
3130 /* Instead of calling proto_item_set_len(),
3131 * since we don't yet have a proto_item, we
3132 * set the field_info's length ourselves.
3133 *
3134 * XXX - our caller can't use that length to
3135 * advance an offset unless they arrange that
3136 * there always be a protocol tree into which
3137 * we're putting this item.
3138 */
3139 new_fi->length = length;
3140 break;
3141
3142 case FT_UINT_STRING:
3143 /*
3144 * NOTE: to support code written when
3145 * proto_tree_add_item() took a bool as its
3146 * last argument, with false meaning "big-endian"
3147 * and true meaning "little-endian", if the
3148 * encoding value is true, treat that as
3149 * ASCII with a little-endian length.
3150 *
3151 * This won't work for code that passes
3152 * arbitrary non-zero values; that code
3153 * will need to be fixed.
3154 */
3155 if (encoding == true1)
3156 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3157 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3158 tree, tvb, start, length, &length, encoding);
3159 proto_tree_set_string(new_fi, stringval);
3160
3161 /* Instead of calling proto_item_set_len(), since we
3162 * don't yet have a proto_item, we set the
3163 * field_info's length ourselves.
3164 *
3165 * XXX - our caller can't use that length to
3166 * advance an offset unless they arrange that
3167 * there always be a protocol tree into which
3168 * we're putting this item.
3169 */
3170 new_fi->length = length;
3171 break;
3172
3173 case FT_STRINGZPAD:
3174 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3175 tvb, start, length, &length, encoding);
3176 proto_tree_set_string(new_fi, stringval);
3177
3178 /* Instead of calling proto_item_set_len(), since we
3179 * don't yet have a proto_item, we set the
3180 * field_info's length ourselves.
3181 *
3182 * XXX - our caller can't use that length to
3183 * advance an offset unless they arrange that
3184 * there always be a protocol tree into which
3185 * we're putting this item.
3186 */
3187 new_fi->length = length;
3188 break;
3189
3190 case FT_STRINGZTRUNC:
3191 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3192 tvb, start, length, &length, encoding);
3193 proto_tree_set_string(new_fi, stringval);
3194
3195 /* Instead of calling proto_item_set_len(), since we
3196 * don't yet have a proto_item, we set the
3197 * field_info's length ourselves.
3198 *
3199 * XXX - our caller can't use that length to
3200 * advance an offset unless they arrange that
3201 * there always be a protocol tree into which
3202 * we're putting this item.
3203 */
3204 new_fi->length = length;
3205 break;
3206
3207 case FT_ABSOLUTE_TIME:
3208 /*
3209 * Absolute times can be in any of a number of
3210 * formats, and they can be big-endian or
3211 * little-endian.
3212 *
3213 * Historically FT_TIMEs were only timespecs;
3214 * the only question was whether they were stored
3215 * in big- or little-endian format.
3216 *
3217 * For backwards compatibility, we interpret an
3218 * encoding of 1 as meaning "little-endian timespec",
3219 * so that passing true is interpreted as that.
3220 */
3221 if (encoding == true1)
3222 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3223
3224 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3225
3226 proto_tree_set_time(new_fi, &time_stamp);
3227 break;
3228
3229 case FT_RELATIVE_TIME:
3230 /*
3231 * Relative times can be in any of a number of
3232 * formats, and they can be big-endian or
3233 * little-endian.
3234 *
3235 * Historically FT_TIMEs were only timespecs;
3236 * the only question was whether they were stored
3237 * in big- or little-endian format.
3238 *
3239 * For backwards compatibility, we interpret an
3240 * encoding of 1 as meaning "little-endian timespec",
3241 * so that passing true is interpreted as that.
3242 */
3243 if (encoding == true1)
3244 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3245
3246 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3247
3248 proto_tree_set_time(new_fi, &time_stamp);
3249 break;
3250 case FT_IEEE_11073_SFLOAT:
3251 if (encoding)
3252 encoding = ENC_LITTLE_ENDIAN0x80000000;
3253 if (length != 2) {
3254 length_error = length < 2 ? true1 : false0;
3255 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3256 }
3257
3258 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3259
3260 break;
3261 case FT_IEEE_11073_FLOAT:
3262 if (encoding)
3263 encoding = ENC_LITTLE_ENDIAN0x80000000;
3264 if (length != 4) {
3265 length_error = length < 4 ? true1 : false0;
3266 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3267 }
3268 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3269
3270 break;
3271 default:
3272 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))
3273 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))
3274 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))
3275 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))
;
3276 break;
3277 }
3278 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)
;
3279
3280 /* Don't add new node to proto_tree until now so that any exceptions
3281 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3282 /* XXX. wouldn't be better to add this item to tree, with some special
3283 * flag (FI_EXCEPTION?) to know which item caused exception? For
3284 * strings and bytes, we would have to set new_fi->value to something
3285 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3286 * could handle NULL values. */
3287 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3288 pi = proto_tree_add_node(tree, new_fi);
3289
3290 switch (new_fi->hfinfo->type) {
3291
3292 case FT_STRING:
3293 /* XXX: trailing stray character detection should be done
3294 * _before_ conversion to UTF-8, because conversion can change
3295 * the length, or else get_string_length should return a value
3296 * for the "length in bytes of the string after conversion
3297 * including internal nulls." (Noting that we do, for other
3298 * reasons, still need the "length in bytes in the field",
3299 * especially for FT_STRINGZ.)
3300 *
3301 * This is true even for ASCII and UTF-8, because
3302 * substituting REPLACEMENT CHARACTERS for illegal characters
3303 * can also do so (and for UTF-8 possibly even make the
3304 * string _shorter_).
3305 */
3306 detect_trailing_stray_characters(encoding, stringval, length, pi);
3307 break;
3308
3309 default:
3310 break;
3311 }
3312
3313 return pi;
3314}
3315
3316proto_item *
3317proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3318 const int start, int length,
3319 const unsigned encoding, int32_t *retval)
3320{
3321 header_field_info *hfinfo;
3322 field_info *new_fi;
3323 int32_t value;
3324
3325 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", 3325, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3325,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3325, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3326
3327 switch (hfinfo->type) {
3328 case FT_INT8:
3329 case FT_INT16:
3330 case FT_INT24:
3331 case FT_INT32:
3332 break;
3333 case FT_INT64:
3334 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)
3335 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3336 default:
3337 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)
3338 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3339 }
3340
3341 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3342 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3343 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3344 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3345 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3346 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3347 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3348
3349 if (encoding & ENC_STRING0x03000000) {
3350 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3351 }
3352 /* I believe it's ok if this is called with a NULL tree */
3353 value = get_int_value(tree, tvb, start, length, encoding);
3354
3355 if (retval) {
3356 int no_of_bits;
3357 *retval = value;
3358 if (hfinfo->bitmask) {
3359 /* Mask out irrelevant portions */
3360 *retval &= (uint32_t)(hfinfo->bitmask);
3361 /* Shift bits */
3362 *retval >>= hfinfo_bitshift(hfinfo);
3363 }
3364 no_of_bits = ws_count_ones(hfinfo->bitmask);
3365 *retval = ws_sign_ext32(*retval, no_of_bits);
3366 }
3367
3368 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3369
3370 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", 3370
, __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", 3370, "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", 3370, "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", 3370, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3371
3372 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3373
3374 proto_tree_set_int(new_fi, value);
3375
3376 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3377
3378 return proto_tree_add_node(tree, new_fi);
3379}
3380
3381proto_item *
3382proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3383 const int start, int length,
3384 const unsigned encoding, uint32_t *retval)
3385{
3386 header_field_info *hfinfo;
3387 field_info *new_fi;
3388 uint32_t value;
3389
3390 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", 3390, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3390,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3390, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3391
3392 switch (hfinfo->type) {
3393 case FT_CHAR:
3394 case FT_UINT8:
3395 case FT_UINT16:
3396 case FT_UINT24:
3397 case FT_UINT32:
3398 break;
3399 default:
3400 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)
3401 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)
;
3402 }
3403
3404 if (length == 0) {
3405 if (retval) {
3406 *retval = 0;
3407 }
3408 return NULL((void*)0);
3409 }
3410
3411 if (encoding & ENC_STRING0x03000000) {
3412 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3413 }
3414 /* I believe it's ok if this is called with a NULL tree */
3415 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3416 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3417 uint64_t temp64;
3418 tvb_get_varint(tvb, start, length, &temp64, encoding);
3419 value = (uint32_t)temp64;
3420 } else {
3421 value = get_uint_value(tree, tvb, start, length, encoding);
3422 }
3423
3424 if (retval) {
3425 *retval = value;
3426 if (hfinfo->bitmask) {
3427 /* Mask out irrelevant portions */
3428 *retval &= (uint32_t)(hfinfo->bitmask);
3429 /* Shift bits */
3430 *retval >>= hfinfo_bitshift(hfinfo);
3431 }
3432 }
3433
3434 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3435
3436 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", 3436
, __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", 3436, "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", 3436, "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", 3436, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3437
3438 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3439
3440 proto_tree_set_uint(new_fi, value);
3441
3442 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3443 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3444 new_fi->flags |= FI_VARINT0x00040000;
3445 }
3446 return proto_tree_add_node(tree, new_fi);
3447}
3448
3449proto_item *
3450proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3451 const int start, int length,
3452 const unsigned encoding, uint32_t *retval)
3453{
3454 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3455}
3456
3457proto_item *
3458proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3459 const int start, int length,
3460 const unsigned encoding, uint8_t *retval)
3461{
3462 /* TODO: further restrict by hfinfo->type ? */
3463 uint32_t val32;
3464 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3465 *retval = (uint8_t)val32;
3466 return item;
3467}
3468
3469proto_item *
3470proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3471 const int start, int length,
3472 const unsigned encoding, uint16_t *retval)
3473{
3474 /* TODO: further restrict by hfinfo->type ? */
3475 uint32_t val32;
3476 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3477 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3478 return item;
3479}
3480
3481
3482/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3483 * and returns proto_item* and uint value retrieved*/
3484proto_item *
3485ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3486 const unsigned encoding, uint32_t *retval)
3487{
3488 field_info *new_fi;
3489 header_field_info *hfinfo;
3490 unsigned item_length;
3491 unsigned offset;
3492 uint32_t value;
3493
3494 offset = ptvc->offset;
3495 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", 3495, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3495,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3495, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3496
3497 switch (hfinfo->type) {
3498 case FT_CHAR:
3499 case FT_UINT8:
3500 case FT_UINT16:
3501 case FT_UINT24:
3502 case FT_UINT32:
3503 break;
3504 default:
3505 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)
3506 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)
;
3507 }
3508
3509 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3510 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3511
3512 /* I believe it's ok if this is called with a NULL tree */
3513 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3514 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3515
3516 if (retval) {
3517 *retval = value;
3518 if (hfinfo->bitmask) {
3519 /* Mask out irrelevant portions */
3520 *retval &= (uint32_t)(hfinfo->bitmask);
3521 /* Shift bits */
3522 *retval >>= hfinfo_bitshift(hfinfo);
3523 }
3524 }
3525
3526 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3527
3528 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3529
3530 /* Coast clear. Try and fake it */
3531 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", 3531
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3531, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3531, "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", 3531, __func__, "Adding %s would put more than %d 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); } } }
;
3532
3533 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3534
3535 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3536 offset, length, encoding);
3537}
3538
3539/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3540 * and returns proto_item* and int value retrieved*/
3541proto_item *
3542ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3543 const unsigned encoding, int32_t *retval)
3544{
3545 field_info *new_fi;
3546 header_field_info *hfinfo;
3547 unsigned item_length;
3548 unsigned offset;
3549 uint32_t value;
3550
3551 offset = ptvc->offset;
3552 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", 3552, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3552,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3552, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3553
3554 switch (hfinfo->type) {
3555 case FT_INT8:
3556 case FT_INT16:
3557 case FT_INT24:
3558 case FT_INT32:
3559 break;
3560 default:
3561 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)
3562 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3563 }
3564
3565 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3566 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3567
3568 /* I believe it's ok if this is called with a NULL tree */
3569 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3570 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3571
3572 if (retval) {
3573 int no_of_bits;
3574 *retval = value;
3575 if (hfinfo->bitmask) {
3576 /* Mask out irrelevant portions */
3577 *retval &= (uint32_t)(hfinfo->bitmask);
3578 /* Shift bits */
3579 *retval >>= hfinfo_bitshift(hfinfo);
3580 }
3581 no_of_bits = ws_count_ones(hfinfo->bitmask);
3582 *retval = ws_sign_ext32(*retval, no_of_bits);
3583 }
3584
3585 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3586
3587 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3588
3589 /* Coast clear. Try and fake it */
3590 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", 3590
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3590, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3590, "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", 3590, __func__, "Adding %s would put more than %d 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); } } }
;
3591
3592 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3593
3594 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3595 offset, length, encoding);
3596}
3597
3598/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3599 * and returns proto_item* and string value retrieved */
3600proto_item*
3601ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3602{
3603 header_field_info *hfinfo;
3604 field_info *new_fi;
3605 const uint8_t *value;
3606 unsigned item_length;
3607 unsigned offset;
3608
3609 offset = ptvc->offset;
3610
3611 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", 3611
, __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", 3611, "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", 3611, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3612
3613 switch (hfinfo->type) {
3614 case FT_STRING:
3615 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3616 break;
3617 case FT_STRINGZ:
3618 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3619 break;
3620 case FT_UINT_STRING:
3621 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3622 break;
3623 case FT_STRINGZPAD:
3624 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3625 break;
3626 case FT_STRINGZTRUNC:
3627 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3628 break;
3629 default:
3630 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)
3631 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)
;
3632 }
3633
3634 if (retval)
3635 *retval = value;
3636
3637 ptvcursor_advance(ptvc, item_length);
3638
3639 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3640
3641 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", 3641, __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", 3641,
"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", 3641, "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", 3641
, __func__, "Adding %s would put more than %d 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); } } }
;
3642
3643 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3644
3645 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3646 offset, length, encoding);
3647}
3648
3649/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3650 * and returns proto_item* and boolean value retrieved */
3651proto_item*
3652ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3653{
3654 header_field_info *hfinfo;
3655 field_info *new_fi;
3656 unsigned item_length;
3657 unsigned offset;
3658 uint64_t value, bitval;
3659
3660 offset = ptvc->offset;
3661 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", 3661, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3661,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3661, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3662
3663 if (hfinfo->type != FT_BOOLEAN) {
3664 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)
3665 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3666 }
3667
3668 if (length == 0) {
3669 if (retval) {
3670 *retval = 0;
3671 }
3672 return NULL((void*)0);
3673 }
3674 if (encoding & ENC_STRING0x03000000) {
3675 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3676 }
3677
3678 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3679 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3680
3681 /* I believe it's ok if this is called with a NULL tree */
3682 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3683
3684 if (retval) {
3685 bitval = value;
3686 if (hfinfo->bitmask) {
3687 /* Mask out irrelevant portions */
3688 bitval &= hfinfo->bitmask;
3689 }
3690 *retval = (bitval != 0);
3691 }
3692
3693 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3694
3695 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3696
3697 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", 3697, __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", 3697,
"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", 3697, "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", 3697
, __func__, "Adding %s would put more than %d 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); } } }
;
3698
3699 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3700
3701 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3702 offset, length, encoding);
3703}
3704
3705proto_item *
3706proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3707 const int start, int length, const unsigned encoding, uint64_t *retval)
3708{
3709 header_field_info *hfinfo;
3710 field_info *new_fi;
3711 uint64_t value;
3712
3713 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", 3713, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3713,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3713, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3714
3715 switch (hfinfo->type) {
3716 case FT_UINT40:
3717 case FT_UINT48:
3718 case FT_UINT56:
3719 case FT_UINT64:
3720 break;
3721 default:
3722 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)
3723 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3724 }
3725
3726 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3727 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3728 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3729 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3730 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3731 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3732 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3733
3734 if (encoding & ENC_STRING0x03000000) {
3735 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3736 }
3737 /* I believe it's ok if this is called with a NULL tree */
3738 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3739 tvb_get_varint(tvb, start, length, &value, encoding);
3740 } else {
3741 value = get_uint64_value(tree, tvb, start, length, encoding);
3742 }
3743
3744 if (retval) {
3745 *retval = value;
3746 if (hfinfo->bitmask) {
3747 /* Mask out irrelevant portions */
3748 *retval &= hfinfo->bitmask;
3749 /* Shift bits */
3750 *retval >>= hfinfo_bitshift(hfinfo);
3751 }
3752 }
3753
3754 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3755
3756 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", 3756
, __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", 3756, "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", 3756, "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", 3756, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3757
3758 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3759
3760 proto_tree_set_uint64(new_fi, value);
3761
3762 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3763 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3764 new_fi->flags |= FI_VARINT0x00040000;
3765 }
3766
3767 return proto_tree_add_node(tree, new_fi);
3768}
3769
3770proto_item *
3771proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3772 const int start, int length, const unsigned encoding, int64_t *retval)
3773{
3774 header_field_info *hfinfo;
3775 field_info *new_fi;
3776 int64_t value;
3777
3778 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", 3778, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3778,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3778, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3779
3780 switch (hfinfo->type) {
3781 case FT_INT40:
3782 case FT_INT48:
3783 case FT_INT56:
3784 case FT_INT64:
3785 break;
3786 default:
3787 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)
3788 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3789 }
3790
3791 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3792 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3793 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3794 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3795 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3796 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3797 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3798
3799 if (encoding & ENC_STRING0x03000000) {
3800 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3801 }
3802 /* I believe it's ok if this is called with a NULL tree */
3803 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3804 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3805 }
3806 else {
3807 value = get_int64_value(tree, tvb, start, length, encoding);
3808 }
3809
3810 if (retval) {
3811 *retval = value;
3812 }
3813
3814 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3815
3816 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", 3816
, __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", 3816, "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", 3816, "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", 3816, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3817
3818 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3819
3820 proto_tree_set_int64(new_fi, value);
3821
3822 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3823 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3824 new_fi->flags |= FI_VARINT0x00040000;
3825 }
3826
3827 return proto_tree_add_node(tree, new_fi);
3828}
3829
3830proto_item *
3831proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3832 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3833{
3834 header_field_info *hfinfo;
3835 field_info *new_fi;
3836 uint64_t value;
3837
3838 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", 3838, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3838,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3838, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3839
3840 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
))
)) {
3841 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)
3842 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3843 }
3844
3845 /* length validation for native number encoding caught by get_uint64_value() */
3846 /* length has to be -1 or > 0 regardless of encoding */
3847 if (length == 0)
3848 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
3849 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3850
3851 if (encoding & ENC_STRING0x03000000) {
3852 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3853 }
3854
3855 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3856
3857 if (retval) {
3858 *retval = value;
3859 if (hfinfo->bitmask) {
3860 /* Mask out irrelevant portions */
3861 *retval &= hfinfo->bitmask;
3862 /* Shift bits */
3863 *retval >>= hfinfo_bitshift(hfinfo);
3864 }
3865 }
3866
3867 if (lenretval) {
3868 *lenretval = length;
3869 }
3870
3871 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3872
3873 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", 3873
, __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", 3873, "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", 3873, "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", 3873, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3874
3875 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3876
3877 proto_tree_set_uint64(new_fi, value);
3878
3879 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3880 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3881 new_fi->flags |= FI_VARINT0x00040000;
3882 }
3883
3884 return proto_tree_add_node(tree, new_fi);
3885
3886}
3887
3888proto_item *
3889proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3890 const int start, int length,
3891 const unsigned encoding, bool_Bool *retval)
3892{
3893 header_field_info *hfinfo;
3894 field_info *new_fi;
3895 uint64_t value, bitval;
3896
3897 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", 3897, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3897,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3897, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3898
3899 if (hfinfo->type != FT_BOOLEAN) {
3900 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)
3901 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3902 }
3903
3904 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3905 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3906 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3907 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3908 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3909 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3910 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3911
3912 if (encoding & ENC_STRING0x03000000) {
3913 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3914 }
3915 /* I believe it's ok if this is called with a NULL tree */
3916 value = get_uint64_value(tree, tvb, start, length, encoding);
3917
3918 if (retval) {
3919 bitval = value;
3920 if (hfinfo->bitmask) {
3921 /* Mask out irrelevant portions */
3922 bitval &= hfinfo->bitmask;
3923 }
3924 *retval = (bitval != 0);
3925 }
3926
3927 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3928
3929 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", 3929
, __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", 3929, "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", 3929, "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", 3929, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3930
3931 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3932
3933 proto_tree_set_boolean(new_fi, value);
3934
3935 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3936
3937 return proto_tree_add_node(tree, new_fi);
3938}
3939
3940proto_item *
3941proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3942 const int start, int length,
3943 const unsigned encoding, float *retval)
3944{
3945 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3946 field_info *new_fi;
3947 float value;
3948
3949 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", 3949,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3950
3951 if (hfinfo->type != FT_FLOAT) {
3952 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)
;
3953 }
3954
3955 if (length != 4) {
3956 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3957 }
3958
3959 /* treat any nonzero encoding as little endian for backwards compatibility */
3960 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3961 if (retval) {
3962 *retval = value;
3963 }
3964
3965 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3966
3967 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", 3967
, __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", 3967, "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", 3967, "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", 3967, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3968
3969 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3970 if (encoding) {
3971 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3972 }
3973
3974 proto_tree_set_float(new_fi, value);
3975
3976 return proto_tree_add_node(tree, new_fi);
3977}
3978
3979proto_item *
3980proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3981 const int start, int length,
3982 const unsigned encoding, double *retval)
3983{
3984 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3985 field_info *new_fi;
3986 double value;
3987
3988 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", 3988,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3989
3990 if (hfinfo->type != FT_DOUBLE) {
3991 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)
;
3992 }
3993
3994 if (length != 8) {
3995 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3996 }
3997
3998 /* treat any nonzero encoding as little endian for backwards compatibility */
3999 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4000 if (retval) {
4001 *retval = value;
4002 }
4003
4004 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4005
4006 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", 4006
, __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", 4006, "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", 4006, "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", 4006, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4007
4008 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4009 if (encoding) {
4010 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4011 }
4012
4013 proto_tree_set_double(new_fi, value);
4014
4015 return proto_tree_add_node(tree, new_fi);
4016}
4017
4018proto_item *
4019proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4020 const int start, int length,
4021 const unsigned encoding, ws_in4_addr *retval)
4022{
4023 header_field_info *hfinfo;
4024 field_info *new_fi;
4025 ws_in4_addr value;
4026
4027 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", 4027, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4027,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4027, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4028
4029 switch (hfinfo->type) {
4030 case FT_IPv4:
4031 break;
4032 default:
4033 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)
4034 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4035 }
4036
4037 if (length != FT_IPv4_LEN4)
4038 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)
4039 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4040
4041 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4042 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4043 }
4044
4045 /*
4046 * NOTE: to support code written when proto_tree_add_item() took
4047 * a bool as its last argument, with false meaning "big-endian"
4048 * and true meaning "little-endian", we treat any non-zero value
4049 * of "encoding" as meaning "little-endian".
4050 */
4051 value = tvb_get_ipv4(tvb, start);
4052 if (encoding)
4053 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))))
;
4054
4055 if (retval) {
4056 *retval = value;
4057 }
4058
4059 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4060
4061 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", 4061
, __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", 4061, "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", 4061, "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", 4061, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4062
4063 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4064
4065 proto_tree_set_ipv4(new_fi, value);
4066
4067 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4068 return proto_tree_add_node(tree, new_fi);
4069}
4070
4071proto_item *
4072proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4073 const int start, int length,
4074 const unsigned encoding, ws_in6_addr *addr)
4075{
4076 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4077 field_info *new_fi;
4078
4079 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", 4079,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4080
4081 switch (hfinfo->type) {
4082 case FT_IPv6:
4083 break;
4084 default:
4085 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)
4086 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4087 }
4088
4089 if (length != FT_IPv6_LEN16)
4090 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)
4091 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4092
4093 if (encoding) {
4094 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"
)
;
4095 }
4096
4097 tvb_get_ipv6(tvb, start, addr);
4098
4099 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4100
4101 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", 4101
, __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", 4101, "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", 4101, "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", 4101, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4102
4103 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4104
4105 proto_tree_set_ipv6(new_fi, addr);
4106
4107 return proto_tree_add_node(tree, new_fi);
4108}
4109
4110proto_item *
4111proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4112 const int start, int length, const unsigned encoding, uint8_t *retval) {
4113
4114 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4115 field_info *new_fi;
4116
4117 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", 4117,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4118
4119 switch (hfinfo->type) {
4120 case FT_ETHER:
4121 break;
4122 default:
4123 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)
4124 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4125 }
4126
4127 if (length != FT_ETHER_LEN6)
4128 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)
4129 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4130
4131 if (encoding) {
4132 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"
)
;
4133 }
4134
4135 tvb_memcpy(tvb, retval, start, length);
4136
4137 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4138
4139 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", 4139
, __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", 4139, "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", 4139, "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", 4139, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4140
4141 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4142
4143 proto_tree_set_ether(new_fi, retval);
4144
4145 return proto_tree_add_node(tree, new_fi);
4146}
4147
4148
4149proto_item *
4150proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4151 tvbuff_t *tvb,
4152 const int start, int length,
4153 const unsigned encoding,
4154 wmem_allocator_t *scope,
4155 const uint8_t **retval,
4156 int *lenretval)
4157{
4158 proto_item *pi;
4159 header_field_info *hfinfo;
4160 field_info *new_fi;
4161 const uint8_t *value;
4162
4163 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", 4163, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4163,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4163, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4164
4165 switch (hfinfo->type) {
4166 case FT_STRING:
4167 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4168 break;
4169 case FT_STRINGZ:
4170 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4171 break;
4172 case FT_UINT_STRING:
4173 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4174 break;
4175 case FT_STRINGZPAD:
4176 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4177 break;
4178 case FT_STRINGZTRUNC:
4179 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4180 break;
4181 default:
4182 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)
4183 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)
;
4184 }
4185
4186 if (retval)
4187 *retval = value;
4188
4189 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4190
4191 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", 4191
, __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", 4191, "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", 4191, "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", 4191, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4192
4193 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4194
4195 proto_tree_set_string(new_fi, (const char*)value);
4196
4197 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4198
4199 pi = proto_tree_add_node(tree, new_fi);
4200
4201 switch (hfinfo->type) {
4202
4203 case FT_STRINGZ:
4204 case FT_STRINGZPAD:
4205 case FT_STRINGZTRUNC:
4206 case FT_UINT_STRING:
4207 break;
4208
4209 case FT_STRING:
4210 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4211 break;
4212
4213 default:
4214 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4214
, __func__, "assertion \"not reached\" failed")
;
4215 }
4216
4217 return pi;
4218}
4219
4220proto_item *
4221proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4222 const int start, int length,
4223 const unsigned encoding, wmem_allocator_t *scope,
4224 const uint8_t **retval)
4225{
4226 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4227 tvb, start, length, encoding, scope, retval, &length);
4228}
4229
4230proto_item *
4231proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4232 tvbuff_t *tvb,
4233 const int start, int length,
4234 const unsigned encoding,
4235 wmem_allocator_t *scope,
4236 char **retval,
4237 int *lenretval)
4238{
4239 proto_item *pi;
4240 header_field_info *hfinfo;
4241 field_info *new_fi;
4242 const uint8_t *value;
4243 uint32_t n = 0;
4244
4245 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", 4245, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4245,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4245, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4246
4247 switch (hfinfo->type) {
4248 case FT_STRING:
4249 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4250 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4251 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4252 break;
4253 case FT_STRINGZ:
4254 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4255 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4256 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4257 break;
4258 case FT_UINT_STRING:
4259 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4260 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4261 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4262 break;
4263 case FT_STRINGZPAD:
4264 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4265 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4266 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4267 break;
4268 case FT_STRINGZTRUNC:
4269 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4270 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4271 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4272 break;
4273 case FT_BYTES:
4274 tvb_ensure_bytes_exist(tvb, start, length);
4275 value = tvb_get_ptr(tvb, start, length);
4276 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4277 *lenretval = length;
4278 break;
4279 case FT_UINT_BYTES:
4280 n = get_uint_value(tree, tvb, start, length, encoding);
4281 tvb_ensure_bytes_exist(tvb, start + length, n);
4282 value = tvb_get_ptr(tvb, start + length, n);
4283 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4284 *lenretval = length + n;
4285 break;
4286 default:
4287 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)
4288 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)
;
4289 }
4290
4291 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4292
4293 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", 4293
, __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", 4293, "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", 4293, "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", 4293, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4294
4295 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4296
4297 switch (hfinfo->type) {
4298
4299 case FT_STRING:
4300 case FT_STRINGZ:
4301 case FT_UINT_STRING:
4302 case FT_STRINGZPAD:
4303 case FT_STRINGZTRUNC:
4304 proto_tree_set_string(new_fi, (const char*)value);
4305 break;
4306
4307 case FT_BYTES:
4308 proto_tree_set_bytes(new_fi, value, length);
4309 break;
4310
4311 case FT_UINT_BYTES:
4312 proto_tree_set_bytes(new_fi, value, n);
4313 break;
4314
4315 default:
4316 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4316
, __func__, "assertion \"not reached\" failed")
;
4317 }
4318
4319 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4320
4321 pi = proto_tree_add_node(tree, new_fi);
4322
4323 switch (hfinfo->type) {
4324
4325 case FT_STRINGZ:
4326 case FT_STRINGZPAD:
4327 case FT_STRINGZTRUNC:
4328 case FT_UINT_STRING:
4329 break;
4330
4331 case FT_STRING:
4332 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4333 break;
4334
4335 case FT_BYTES:
4336 case FT_UINT_BYTES:
4337 break;
4338
4339 default:
4340 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4340
, __func__, "assertion \"not reached\" failed")
;
4341 }
4342
4343 return pi;
4344}
4345
4346proto_item *
4347proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4348 tvbuff_t *tvb,
4349 const int start, int length,
4350 const unsigned encoding,
4351 wmem_allocator_t *scope,
4352 char **retval)
4353{
4354 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4355 tvb, start, length, encoding, scope, retval, &length);
4356}
4357
4358proto_item *
4359proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4360 tvbuff_t *tvb,
4361 const int start, int length, const unsigned encoding,
4362 wmem_allocator_t *scope, char **retval)
4363{
4364 header_field_info *hfinfo;
4365 field_info *new_fi;
4366 nstime_t time_stamp;
4367 int flags;
4368
4369 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", 4369, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4369,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4369, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4370
4371 switch (hfinfo->type) {
4372 case FT_ABSOLUTE_TIME:
4373 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4374 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4375 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4376 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4377 }
4378 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4379 break;
4380 case FT_RELATIVE_TIME:
4381 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4382 *retval = rel_time_to_secs_str(scope, &time_stamp);
4383 break;
4384 default:
4385 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)
4386 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4387 }
4388
4389 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4390
4391 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", 4391
, __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", 4391, "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", 4391, "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", 4391, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4392
4393 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4394
4395 switch (hfinfo->type) {
4396
4397 case FT_ABSOLUTE_TIME:
4398 case FT_RELATIVE_TIME:
4399 proto_tree_set_time(new_fi, &time_stamp);
4400 break;
4401 default:
4402 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4402
, __func__, "assertion \"not reached\" failed")
;
4403 }
4404
4405 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4406
4407 return proto_tree_add_node(tree, new_fi);
4408}
4409
4410/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4411 and returns proto_item* */
4412proto_item *
4413ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4414 const unsigned encoding)
4415{
4416 field_info *new_fi;
4417 header_field_info *hfinfo;
4418 int item_length;
4419 unsigned offset;
4420
4421 offset = ptvc->offset;
4422 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", 4422, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4422,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4423 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4424 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4425
4426 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4427
4428 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4429
4430 /* Coast clear. Try and fake it */
4431 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", 4431
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4431, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4431, "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", 4431, __func__, "Adding %s would put more than %d 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); } } }
;
4432
4433 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4434
4435 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4436 offset, length, encoding);
4437}
4438
4439/* Add an item to a proto_tree, using the text label registered to that item;
4440 the item is extracted from the tvbuff handed to it. */
4441proto_item *
4442proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4443 const int start, int length, const unsigned encoding)
4444{
4445 field_info *new_fi;
4446 int item_length;
4447
4448 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", 4448,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4449
4450 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4451 test_length(hfinfo, tvb, start, item_length, encoding);
4452
4453 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4454
4455 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", 4455
, __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", 4455, "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", 4455, "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", 4455, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4456
4457 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4458
4459 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4460}
4461
4462proto_item *
4463proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4464 const int start, int length, const unsigned encoding)
4465{
4466 register header_field_info *hfinfo;
4467
4468 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", 4468, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4468,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4468, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4469 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4470}
4471
4472/* Add an item to a proto_tree, using the text label registered to that item;
4473 the item is extracted from the tvbuff handed to it.
4474
4475 Return the length of the item through the pointer. */
4476proto_item *
4477proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4478 tvbuff_t *tvb, const int start,
4479 int length, const unsigned encoding,
4480 int *lenretval)
4481{
4482 field_info *new_fi;
4483 int item_length;
4484 proto_item *item;
4485
4486 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", 4486,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4487
4488 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4489 test_length(hfinfo, tvb, start, item_length, encoding);
4490
4491 if (!tree) {
4492 /*
4493 * We need to get the correct item length here.
4494 * That's normally done by proto_tree_new_item(),
4495 * but we won't be calling it.
4496 */
4497 *lenretval = get_full_length(hfinfo, tvb, start, length,
4498 item_length, encoding);
4499 return NULL((void*)0);
4500 }
4501
4502 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", 4509
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4503 /*((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4509
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4504 * 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", 4509
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4505 * 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", 4509
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4506 */((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4509
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4507 *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", 4509
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4508 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", 4509
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4509 })((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4509
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4509, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *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", 4509
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
;
4510
4511 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4512
4513 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4514 *lenretval = new_fi->length;
4515 return item;
4516}
4517
4518proto_item *
4519proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4520 const int start, int length,
4521 const unsigned encoding, int *lenretval)
4522{
4523 register header_field_info *hfinfo;
4524
4525 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", 4525, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4525,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4525, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4526 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4527}
4528
4529/* which FT_ types can use proto_tree_add_bytes_item() */
4530static inline bool_Bool
4531validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4532{
4533 return (type == FT_BYTES ||
4534 type == FT_UINT_BYTES ||
4535 type == FT_OID ||
4536 type == FT_REL_OID ||
4537 type == FT_SYSTEM_ID );
4538}
4539
4540/* Note: this does no validation that the byte array of an FT_OID or
4541 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4542 so I think it's ok to continue not validating it?
4543 */
4544proto_item *
4545proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4546 const unsigned start, unsigned length,
4547 const unsigned encoding,
4548 GByteArray *retval, unsigned *endoff, int *err)
4549{
4550 field_info *new_fi;
4551 GByteArray *bytes = retval;
4552 GByteArray *created_bytes = NULL((void*)0);
4553 bool_Bool failed = false0;
4554 uint32_t n = 0;
4555 header_field_info *hfinfo;
4556 bool_Bool generate = (bytes || tree) ? true1 : false0;
4557
4558 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", 4558, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4558,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4558, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4559
4560 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", 4560,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4561
4562 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", 4563, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4563 "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", 4563, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4564
4565 if (length == 0) {
4566 return NULL((void*)0);
4567 }
4568
4569 if (encoding & ENC_STR_NUM0x01000000) {
4570 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"
)
;
4571 }
4572
4573 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4574 if (hfinfo->type == FT_UINT_BYTES) {
4575 /* can't decode FT_UINT_BYTES from strings */
4576 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")
4577 "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")
;
4578 }
4579
4580 unsigned hex_encoding = encoding;
4581 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4582 /* If none of the separator values are used,
4583 * assume no separator (the common case). */
4584 hex_encoding |= ENC_SEP_NONE0x00010000;
4585#if 0
4586 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")
4587 "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")
;
4588#endif
4589 }
4590
4591 if (!bytes) {
4592 /* caller doesn't care about return value, but we need it to
4593 call tvb_get_string_bytes() and set the tree later */
4594 bytes = created_bytes = g_byte_array_new();
4595 }
4596
4597 /*
4598 * bytes might be NULL after this, but can't add expert
4599 * error until later; if it's NULL, just note that
4600 * it failed.
4601 */
4602 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4603 if (bytes == NULL((void*)0))
4604 failed = true1;
4605 }
4606 else if (generate) {
4607 tvb_ensure_bytes_exist(tvb, start, length);
4608
4609 if (hfinfo->type == FT_UINT_BYTES) {
4610 n = length; /* n is now the "header" length */
4611 length = get_uint_value(tree, tvb, start, n, encoding);
4612 /* length is now the value's length; only store the value in the array */
4613 tvb_ensure_bytes_exist(tvb, start + n, length);
4614 if (!bytes) {
4615 /* caller doesn't care about return value, but
4616 * we may need it to set the tree later */
4617 bytes = created_bytes = g_byte_array_new();
4618 }
4619 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4620 }
4621 else if (length > 0) {
4622 if (!bytes) {
4623 /* caller doesn't care about return value, but
4624 * we may need it to set the tree later */
4625 bytes = created_bytes = g_byte_array_new();
4626 }
4627 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4628 }
4629
4630 if (endoff)
4631 *endoff = start + n + length;
4632 }
4633
4634 if (err)
4635 *err = failed ? EINVAL22 : 0;
4636
4637 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); }
4638 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4639 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); }
4640 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); }
4641 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); }
4642 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4643 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4644
4645 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4646 {((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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4647 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4648 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4649 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4650 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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4651 } )((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", 4651
, __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", 4651, "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", 4651, "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", 4651
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4652
4653 /* n will be zero except when it's a FT_UINT_BYTES */
4654 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4655
4656 if (encoding & ENC_STRING0x03000000) {
4657 if (failed)
4658 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4659
4660 if (bytes)
4661 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4662 else
4663 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4664
4665 if (created_bytes)
4666 g_byte_array_free(created_bytes, true1);
4667 }
4668 else {
4669 /* n will be zero except when it's a FT_UINT_BYTES */
4670 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4671
4672 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4673 * use the byte array created above in this case.
4674 */
4675 if (created_bytes)
4676 g_byte_array_free(created_bytes, true1);
4677
4678 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4679 (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)
;
4680 }
4681
4682 return proto_tree_add_node(tree, new_fi);
4683}
4684
4685
4686proto_item *
4687proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4688 const unsigned start, const unsigned length,
4689 const unsigned encoding,
4690 nstime_t *retval, unsigned *endoff, int *err)
4691{
4692 field_info *new_fi;
4693 nstime_t time_stamp;
4694 int saved_err = 0;
4695 header_field_info *hfinfo;
4696
4697 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", 4697, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4697,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4697, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4698
4699 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", 4699,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4700
4701 if (length == 0) {
4702 if(retval) {
4703 nstime_set_zero(retval);
4704 }
4705 return NULL((void*)0);
4706 }
4707
4708 nstime_set_zero(&time_stamp);
4709
4710 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4711 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", 4711, ((hfinfo))->abbrev))))
;
4712 /* The only string format that could be a relative time is
4713 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4714 * relative to "now" currently.
4715 */
4716 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4717 saved_err = EINVAL22;
4718 }
4719 else {
4720 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", 4720, ((hfinfo))->abbrev))))
;
4721 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4722
4723 tvb_ensure_bytes_exist(tvb, start, length);
4724 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4725 if (endoff) *endoff = start + length;
4726 }
4727
4728 if (err) *err = saved_err;
4729
4730 if (retval) {
4731 retval->secs = time_stamp.secs;
4732 retval->nsecs = time_stamp.nsecs;
4733 }
4734
4735 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4736
4737 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", 4737
, __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", 4737, "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", 4737, "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", 4737, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4738
4739 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4740
4741 proto_tree_set_time(new_fi, &time_stamp);
4742
4743 if (encoding & ENC_STRING0x03000000) {
4744 if (saved_err)
4745 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4746 }
4747 else {
4748 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4749 (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)
;
4750 }
4751
4752 return proto_tree_add_node(tree, new_fi);
4753}
4754
4755/* Add a FT_NONE to a proto_tree */
4756proto_item *
4757proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4758 const int start, int length, const char *format,
4759 ...)
4760{
4761 proto_item *pi;
4762 va_list ap;
4763 header_field_info *hfinfo;
4764
4765 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4766
4767 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", 4767
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4767, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4767, "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", 4767, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4768
4769 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", 4769
, ((hfinfo))->abbrev))))
;
4770
4771 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4772
4773 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4773, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4774
4775 va_start(ap, format)__builtin_va_start(ap, format);
4776 proto_tree_set_representation(pi, format, ap);
4777 va_end(ap)__builtin_va_end(ap);
4778
4779 /* no value to set for FT_NONE */
4780 return pi;
4781}
4782
4783/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4784 * offset, and returns proto_item* */
4785proto_item *
4786ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4787 const unsigned encoding)
4788{
4789 proto_item *item;
4790
4791 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4792 length, encoding);
4793
4794 return item;
4795}
4796
4797/* Advance the ptvcursor's offset within its tvbuff without
4798 * adding anything to the proto_tree. */
4799void
4800ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4801{
4802 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4803 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4804 }
4805}
4806
4807
4808static void
4809proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4810{
4811 fvalue_set_protocol(fi->value, tvb, field_data, length);
4812}
4813
4814/* Add a FT_PROTOCOL to a proto_tree */
4815proto_item *
4816proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4817 int start, int length, const char *format, ...)
4818{
4819 proto_item *pi;
4820 tvbuff_t *protocol_tvb;
4821 va_list ap;
4822 header_field_info *hfinfo;
4823 char* protocol_rep;
4824
4825 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4826
4827 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", 4827
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4827, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4827, "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", 4827, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4828
4829 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"
, 4829, ((hfinfo))->abbrev))))
;
4830
4831 /*
4832 * This can throw an exception, so do it before we allocate anything.
4833 */
4834 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4835
4836 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4837
4838 va_start(ap, format)__builtin_va_start(ap, format);
4839 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4840 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4841 g_free(protocol_rep);
4842 va_end(ap)__builtin_va_end(ap);
4843
4844 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4844, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4845
4846 va_start(ap, format)__builtin_va_start(ap, format);
4847 proto_tree_set_representation(pi, format, ap);
4848 va_end(ap)__builtin_va_end(ap);
4849
4850 return pi;
4851}
4852
4853/* Add a FT_BYTES to a proto_tree */
4854proto_item *
4855proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4856 int length, const uint8_t *start_ptr)
4857{
4858 proto_item *pi;
4859 header_field_info *hfinfo;
4860 int item_length;
4861
4862 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", 4862, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4862,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4862, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4863 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4864 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4865
4866 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4867
4868 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", 4868
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4868, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4868, "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", 4868, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4869
4870 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",
4870, ((hfinfo))->abbrev))))
;
4871
4872 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4873 start_ptr = tvb_get_ptr(tvb, start, length);
4874
4875 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4876 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4877
4878 return pi;
4879}
4880
4881/* Add a FT_BYTES to a proto_tree */
4882proto_item *
4883proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4884 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4885{
4886 proto_item *pi;
4887 header_field_info *hfinfo;
4888 int item_length;
4889
4890 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", 4890, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4890,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4890, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4891 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4892 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4893
4894 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4895
4896 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", 4896
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4896, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4896, "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", 4896, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4897
4898 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",
4898, ((hfinfo))->abbrev))))
;
4899
4900 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4901 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4902
4903 return pi;
4904}
4905
4906proto_item *
4907proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4908 int start, int length,
4909 const uint8_t *start_ptr,
4910 const char *format, ...)
4911{
4912 proto_item *pi;
4913 va_list ap;
4914
4915 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4916
4917 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; }
;
4918
4919 va_start(ap, format)__builtin_va_start(ap, format);
4920 proto_tree_set_representation_value(pi, format, ap);
4921 va_end(ap)__builtin_va_end(ap);
4922
4923 return pi;
4924}
4925
4926proto_item *
4927proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4928 int start, int length, const uint8_t *start_ptr,
4929 const char *format, ...)
4930{
4931 proto_item *pi;
4932 va_list ap;
4933
4934 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4935
4936 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; }
;
4937
4938 va_start(ap, format)__builtin_va_start(ap, format);
4939 proto_tree_set_representation(pi, format, ap);
4940 va_end(ap)__builtin_va_end(ap);
4941
4942 return pi;
4943}
4944
4945static void
4946proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4947{
4948 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4948, "length >= 0"
))))
;
4949 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", 4949, "start_ptr != ((void*)0) || length == 0"
))))
;
4950
4951 fvalue_set_bytes_data(fi->value, start_ptr, length);
4952}
4953
4954
4955static void
4956proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4957{
4958 tvb_ensure_bytes_exist(tvb, offset, length);
4959 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4960}
4961
4962static void
4963proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4964{
4965 GByteArray *bytes;
4966
4967 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4967, "value != ((void*)0)"
))))
;
4968
4969 bytes = byte_array_dup(value);
4970
4971 fvalue_set_byte_array(fi->value, bytes);
4972}
4973
4974/* Add a FT_*TIME to a proto_tree */
4975proto_item *
4976proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4977 int length, const nstime_t *value_ptr)
4978{
4979 proto_item *pi;
4980 header_field_info *hfinfo;
4981
4982 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4983
4984 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", 4984
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4984, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4984, "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", 4984, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4985
4986 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", 4986, ((hfinfo))->abbrev))))
;
4987
4988 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4989 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4990
4991 return pi;
4992}
4993
4994proto_item *
4995proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4996 int start, int length, nstime_t *value_ptr,
4997 const char *format, ...)
4998{
4999 proto_item *pi;
5000 va_list ap;
5001
5002 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5003 if (pi != tree) {
5004 va_start(ap, format)__builtin_va_start(ap, format);
5005 proto_tree_set_representation_value(pi, format, ap);
5006 va_end(ap)__builtin_va_end(ap);
5007 }
5008
5009 return pi;
5010}
5011
5012proto_item *
5013proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5014 int start, int length, nstime_t *value_ptr,
5015 const char *format, ...)
5016{
5017 proto_item *pi;
5018 va_list ap;
5019
5020 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5021 if (pi != tree) {
5022 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5022, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5023
5024 va_start(ap, format)__builtin_va_start(ap, format);
5025 proto_tree_set_representation(pi, format, ap);
5026 va_end(ap)__builtin_va_end(ap);
5027 }
5028
5029 return pi;
5030}
5031
5032/* Set the FT_*TIME value */
5033static void
5034proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5035{
5036 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5036, "value_ptr != ((void*)0)"
))))
;
5037
5038 fvalue_set_time(fi->value, value_ptr);
5039}
5040
5041/* Add a FT_IPXNET to a proto_tree */
5042proto_item *
5043proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5044 int length, uint32_t value)
5045{
5046 proto_item *pi;
5047 header_field_info *hfinfo;
5048
5049 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5050
5051 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", 5051
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5051, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5051, "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", 5051, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5052
5053 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"
, 5053, ((hfinfo))->abbrev))))
;
5054
5055 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5056 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5057
5058 return pi;
5059}
5060
5061proto_item *
5062proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5063 int start, int length, uint32_t value,
5064 const char *format, ...)
5065{
5066 proto_item *pi;
5067 va_list ap;
5068
5069 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5070 if (pi != tree) {
5071 va_start(ap, format)__builtin_va_start(ap, format);
5072 proto_tree_set_representation_value(pi, format, ap);
5073 va_end(ap)__builtin_va_end(ap);
5074 }
5075
5076 return pi;
5077}
5078
5079proto_item *
5080proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5081 int start, int length, uint32_t value,
5082 const char *format, ...)
5083{
5084 proto_item *pi;
5085 va_list ap;
5086
5087 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5088 if (pi != tree) {
5089 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5089, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5090
5091 va_start(ap, format)__builtin_va_start(ap, format);
5092 proto_tree_set_representation(pi, format, ap);
5093 va_end(ap)__builtin_va_end(ap);
5094 }
5095
5096 return pi;
5097}
5098
5099/* Set the FT_IPXNET value */
5100static void
5101proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5102{
5103 fvalue_set_uinteger(fi->value, value);
5104}
5105
5106/* Add a FT_IPv4 to a proto_tree */
5107proto_item *
5108proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5109 int length, ws_in4_addr value)
5110{
5111 proto_item *pi;
5112 header_field_info *hfinfo;
5113
5114 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5115
5116 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", 5116
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5116, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5116, "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", 5116, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5117
5118 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", 5118
, ((hfinfo))->abbrev))))
;
5119
5120 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5121 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5122
5123 return pi;
5124}
5125
5126proto_item *
5127proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5128 int start, int length, ws_in4_addr value,
5129 const char *format, ...)
5130{
5131 proto_item *pi;
5132 va_list ap;
5133
5134 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5135 if (pi != tree) {
5136 va_start(ap, format)__builtin_va_start(ap, format);
5137 proto_tree_set_representation_value(pi, format, ap);
5138 va_end(ap)__builtin_va_end(ap);
5139 }
5140
5141 return pi;
5142}
5143
5144proto_item *
5145proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5146 int start, int length, ws_in4_addr value,
5147 const char *format, ...)
5148{
5149 proto_item *pi;
5150 va_list ap;
5151
5152 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5153 if (pi != tree) {
5154 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5154, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5155
5156 va_start(ap, format)__builtin_va_start(ap, format);
5157 proto_tree_set_representation(pi, format, ap);
5158 va_end(ap)__builtin_va_end(ap);
5159 }
5160
5161 return pi;
5162}
5163
5164/* Set the FT_IPv4 value */
5165static void
5166proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5167{
5168 ipv4_addr_and_mask ipv4;
5169 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5170 fvalue_set_ipv4(fi->value, &ipv4);
5171}
5172
5173/* Add a FT_IPv6 to a proto_tree */
5174proto_item *
5175proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5176 int length, const ws_in6_addr *value)
5177{
5178 proto_item *pi;
5179 header_field_info *hfinfo;
5180
5181 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5182
5183 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", 5183
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5183, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5183, "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", 5183, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5184
5185 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", 5185
, ((hfinfo))->abbrev))))
;
5186
5187 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5188 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5189
5190 return pi;
5191}
5192
5193proto_item *
5194proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5195 int start, int length,
5196 const ws_in6_addr *value_ptr,
5197 const char *format, ...)
5198{
5199 proto_item *pi;
5200 va_list ap;
5201
5202 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5203 if (pi != tree) {
5204 va_start(ap, format)__builtin_va_start(ap, format);
5205 proto_tree_set_representation_value(pi, format, ap);
5206 va_end(ap)__builtin_va_end(ap);
5207 }
5208
5209 return pi;
5210}
5211
5212proto_item *
5213proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5214 int start, int length,
5215 const ws_in6_addr *value_ptr,
5216 const char *format, ...)
5217{
5218 proto_item *pi;
5219 va_list ap;
5220
5221 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5222 if (pi != tree) {
5223 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5223, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5224
5225 va_start(ap, format)__builtin_va_start(ap, format);
5226 proto_tree_set_representation(pi, format, ap);
5227 va_end(ap)__builtin_va_end(ap);
5228 }
5229
5230 return pi;
5231}
5232
5233/* Set the FT_IPv6 value */
5234static void
5235proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5236{
5237 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5237, "value != ((void*)0)"
))))
;
5238 ipv6_addr_and_prefix ipv6;
5239 ipv6.addr = *value;
5240 ipv6.prefix = 128;
5241 fvalue_set_ipv6(fi->value, &ipv6);
5242}
5243
5244static void
5245proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5246{
5247 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5248}
5249
5250/* Set the FT_FCWWN value */
5251static void
5252proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5253{
5254 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5254, "value_ptr != ((void*)0)"
))))
;
5255 fvalue_set_fcwwn(fi->value, value_ptr);
5256}
5257
5258static void
5259proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5260{
5261 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5262}
5263
5264/* Add a FT_GUID to a proto_tree */
5265proto_item *
5266proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5267 int length, const e_guid_t *value_ptr)
5268{
5269 proto_item *pi;
5270 header_field_info *hfinfo;
5271
5272 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5273
5274 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", 5274
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5274, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5274, "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", 5274, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5275
5276 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", 5276
, ((hfinfo))->abbrev))))
;
5277
5278 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5279 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5280
5281 return pi;
5282}
5283
5284proto_item *
5285proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5286 int start, int length,
5287 const e_guid_t *value_ptr,
5288 const char *format, ...)
5289{
5290 proto_item *pi;
5291 va_list ap;
5292
5293 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5294 if (pi != tree) {
5295 va_start(ap, format)__builtin_va_start(ap, format);
5296 proto_tree_set_representation_value(pi, format, ap);
5297 va_end(ap)__builtin_va_end(ap);
5298 }
5299
5300 return pi;
5301}
5302
5303proto_item *
5304proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5305 int start, int length, const e_guid_t *value_ptr,
5306 const char *format, ...)
5307{
5308 proto_item *pi;
5309 va_list ap;
5310
5311 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5312 if (pi != tree) {
5313 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5313, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5314
5315 va_start(ap, format)__builtin_va_start(ap, format);
5316 proto_tree_set_representation(pi, format, ap);
5317 va_end(ap)__builtin_va_end(ap);
5318 }
5319
5320 return pi;
5321}
5322
5323/* Set the FT_GUID value */
5324static void
5325proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5326{
5327 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5327, "value_ptr != ((void*)0)"
))))
;
5328 fvalue_set_guid(fi->value, value_ptr);
5329}
5330
5331static void
5332proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5333 const unsigned encoding)
5334{
5335 e_guid_t guid;
5336
5337 tvb_get_guid(tvb, start, &guid, encoding);
5338 proto_tree_set_guid(fi, &guid);
5339}
5340
5341/* Add a FT_OID to a proto_tree */
5342proto_item *
5343proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5344 int length, const uint8_t* value_ptr)
5345{
5346 proto_item *pi;
5347 header_field_info *hfinfo;
5348
5349 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5350
5351 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", 5351
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5351, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5351, "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", 5351, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5352
5353 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", 5353
, ((hfinfo))->abbrev))))
;
5354
5355 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5356 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5357
5358 return pi;
5359}
5360
5361proto_item *
5362proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5363 int start, int length,
5364 const uint8_t* value_ptr,
5365 const char *format, ...)
5366{
5367 proto_item *pi;
5368 va_list ap;
5369
5370 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5371 if (pi != tree) {
5372 va_start(ap, format)__builtin_va_start(ap, format);
5373 proto_tree_set_representation_value(pi, format, ap);
5374 va_end(ap)__builtin_va_end(ap);
5375 }
5376
5377 return pi;
5378}
5379
5380proto_item *
5381proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5382 int start, int length, const uint8_t* value_ptr,
5383 const char *format, ...)
5384{
5385 proto_item *pi;
5386 va_list ap;
5387
5388 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5389 if (pi != tree) {
5390 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5390, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5391
5392 va_start(ap, format)__builtin_va_start(ap, format);
5393 proto_tree_set_representation(pi, format, ap);
5394 va_end(ap)__builtin_va_end(ap);
5395 }
5396
5397 return pi;
5398}
5399
5400/* Set the FT_OID value */
5401static void
5402proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5403{
5404 GByteArray *bytes;
5405
5406 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", 5406, "value_ptr != ((void*)0) || length == 0"
))))
;
5407
5408 bytes = g_byte_array_new();
5409 if (length > 0) {
5410 g_byte_array_append(bytes, value_ptr, length);
5411 }
5412 fvalue_set_byte_array(fi->value, bytes);
5413}
5414
5415static void
5416proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5417{
5418 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5419}
5420
5421/* Set the FT_SYSTEM_ID value */
5422static void
5423proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5424{
5425 GByteArray *bytes;
5426
5427 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", 5427, "value_ptr != ((void*)0) || length == 0"
))))
;
5428
5429 bytes = g_byte_array_new();
5430 if (length > 0) {
5431 g_byte_array_append(bytes, value_ptr, length);
5432 }
5433 fvalue_set_byte_array(fi->value, bytes);
5434}
5435
5436static void
5437proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5438{
5439 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5440}
5441
5442/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5443 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5444 * is destroyed. */
5445proto_item *
5446proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5447 int length, const char* value)
5448{
5449 proto_item *pi;
5450 header_field_info *hfinfo;
5451 int item_length;
5452
5453 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", 5453, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5453,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5453, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5454 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5455 /*
5456 * Special case - if the length is 0, skip the test, so that
5457 * we can have an empty string right after the end of the
5458 * packet. (This handles URL-encoded forms where the last field
5459 * has no value so the form ends right after the =.)
5460 *
5461 * XXX - length zero makes sense for FT_STRING, and more or less
5462 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5463 * for FT_STRINGZ (except that a number of fields that should be
5464 * one of the others are actually registered as FT_STRINGZ.)
5465 */
5466 if (item_length != 0)
5467 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5468
5469 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5470
5471 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", 5471
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5471, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5471, "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", 5471, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5472
5473 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", 5473, ((hfinfo))->abbrev))))
;
5474
5475 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5476 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5476, "length >= 0"
))))
;
5477
5478 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", 5478, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5479 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5480
5481 return pi;
5482}
5483
5484proto_item *
5485proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5486 int start, int length, const char* value,
5487 const char *format,
5488 ...)
5489{
5490 proto_item *pi;
5491 va_list ap;
5492
5493 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5494 if (pi != tree) {
5495 va_start(ap, format)__builtin_va_start(ap, format);
5496 proto_tree_set_representation_value(pi, format, ap);
5497 va_end(ap)__builtin_va_end(ap);
5498 }
5499
5500 return pi;
5501}
5502
5503proto_item *
5504proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5505 int start, int length, const char* value,
5506 const char *format, ...)
5507{
5508 proto_item *pi;
5509 va_list ap;
5510
5511 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5512 if (pi != tree) {
5513 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5513, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5514
5515 va_start(ap, format)__builtin_va_start(ap, format);
5516 proto_tree_set_representation(pi, format, ap);
5517 va_end(ap)__builtin_va_end(ap);
5518 }
5519
5520 return pi;
5521}
5522
5523/* Set the FT_STRING value */
5524static void
5525proto_tree_set_string(field_info *fi, const char* value)
5526{
5527 if (value) {
5528 fvalue_set_string(fi->value, value);
5529 } else {
5530 /*
5531 * XXX - why is a null value for a string field
5532 * considered valid?
5533 */
5534 fvalue_set_string(fi->value, "[ Null ]");
5535 }
5536}
5537
5538/* Set the FT_AX25 value */
5539static void
5540proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5541{
5542 fvalue_set_ax25(fi->value, value);
5543}
5544
5545static void
5546proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5547{
5548 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5549}
5550
5551/* Set the FT_VINES value */
5552static void
5553proto_tree_set_vines(field_info *fi, const uint8_t* value)
5554{
5555 fvalue_set_vines(fi->value, value);
5556}
5557
5558static void
5559proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5560{
5561 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5562}
5563
5564/* Add a FT_ETHER to a proto_tree */
5565proto_item *
5566proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5567 int length, const uint8_t* value)
5568{
5569 proto_item *pi;
5570 header_field_info *hfinfo;
5571
5572 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5573
5574 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", 5574
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5574, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5574, "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", 5574, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5575
5576 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",
5576, ((hfinfo))->abbrev))))
;
5577
5578 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5579 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5580
5581 return pi;
5582}
5583
5584proto_item *
5585proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5586 int start, int length, const uint8_t* value,
5587 const char *format, ...)
5588{
5589 proto_item *pi;
5590 va_list ap;
5591
5592 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5593 if (pi != tree) {
5594 va_start(ap, format)__builtin_va_start(ap, format);
5595 proto_tree_set_representation_value(pi, format, ap);
5596 va_end(ap)__builtin_va_end(ap);
5597 }
5598
5599 return pi;
5600}
5601
5602proto_item *
5603proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5604 int start, int length, const uint8_t* value,
5605 const char *format, ...)
5606{
5607 proto_item *pi;
5608 va_list ap;
5609
5610 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5611 if (pi != tree) {
5612 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5612, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5613
5614 va_start(ap, format)__builtin_va_start(ap, format);
5615 proto_tree_set_representation(pi, format, ap);
5616 va_end(ap)__builtin_va_end(ap);
5617 }
5618
5619 return pi;
5620}
5621
5622/* Set the FT_ETHER value */
5623static void
5624proto_tree_set_ether(field_info *fi, const uint8_t* value)
5625{
5626 fvalue_set_ether(fi->value, value);
5627}
5628
5629static void
5630proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5631{
5632 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5633}
5634
5635/* Add a FT_BOOLEAN to a proto_tree */
5636proto_item *
5637proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5638 int length, uint64_t value)
5639{
5640 proto_item *pi;
5641 header_field_info *hfinfo;
5642
5643 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5644
5645 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", 5645
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5645, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5645, "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", 5645, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5646
5647 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"
, 5647, ((hfinfo))->abbrev))))
;
5648
5649 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5650 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5651
5652 return pi;
5653}
5654
5655proto_item *
5656proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5657 tvbuff_t *tvb, int start, int length,
5658 uint64_t value, const char *format, ...)
5659{
5660 proto_item *pi;
5661 va_list ap;
5662
5663 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5664 if (pi != tree) {
5665 va_start(ap, format)__builtin_va_start(ap, format);
5666 proto_tree_set_representation_value(pi, format, ap);
5667 va_end(ap)__builtin_va_end(ap);
5668 }
5669
5670 return pi;
5671}
5672
5673proto_item *
5674proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5675 int start, int length, uint64_t value,
5676 const char *format, ...)
5677{
5678 proto_item *pi;
5679 va_list ap;
5680
5681 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5682 if (pi != tree) {
5683 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5683, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5684
5685 va_start(ap, format)__builtin_va_start(ap, format);
5686 proto_tree_set_representation(pi, format, ap);
5687 va_end(ap)__builtin_va_end(ap);
5688 }
5689
5690 return pi;
5691}
5692
5693/* Set the FT_BOOLEAN value */
5694static void
5695proto_tree_set_boolean(field_info *fi, uint64_t value)
5696{
5697 proto_tree_set_uint64(fi, value);
5698}
5699
5700/* Generate, into "buf", a string showing the bits of a bitfield.
5701 Return a pointer to the character after that string. */
5702static char *
5703other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5704{
5705 int i = 0;
5706 uint64_t bit;
5707 char *p;
5708
5709 p = buf;
5710
5711 /* This is a devel error. It is safer to stop here. */
5712 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5712, "width >= 1"
))))
;
5713
5714 bit = UINT64_C(1)1UL << (width - 1);
5715 for (;;) {
5716 if (mask & bit) {
5717 /* This bit is part of the field. Show its value. */
5718 if (val & bit)
5719 *p++ = '1';
5720 else
5721 *p++ = '0';
5722 } else {
5723 /* This bit is not part of the field. */
5724 *p++ = '.';
5725 }
5726 bit >>= 1;
5727 i++;
5728 if (i >= width)
5729 break;
5730 if (i % 4 == 0)
5731 *p++ = ' ';
5732 }
5733 *p = '\0';
5734 return p;
5735}
5736
5737static char *
5738decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5739{
5740 char *p;
5741
5742 p = other_decode_bitfield_value(buf, val, mask, width);
5743 p = g_stpcpy(p, " = ");
5744
5745 return p;
5746}
5747
5748static char *
5749other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5750{
5751 int i = 0;
5752 uint64_t bit;
5753 char *p;
5754
5755 p = buf;
5756
5757 /* This is a devel error. It is safer to stop here. */
5758 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5758, "width >= 1"
))))
;
5759
5760 bit = UINT64_C(1)1UL << (width - 1);
5761 for (;;) {
5762 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5763 (mask & bit)) {
5764 /* This bit is part of the field. Show its value. */
5765 if (val & bit)
5766 *p++ = '1';
5767 else
5768 *p++ = '0';
5769 } else {
5770 /* This bit is not part of the field. */
5771 *p++ = '.';
5772 }
5773 bit >>= 1;
5774 i++;
5775 if (i >= width)
5776 break;
5777 if (i % 4 == 0)
5778 *p++ = ' ';
5779 }
5780
5781 *p = '\0';
5782 return p;
5783}
5784
5785static char *
5786decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5787{
5788 char *p;
5789
5790 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5791 p = g_stpcpy(p, " = ");
5792
5793 return p;
5794}
5795
5796/* Add a FT_FLOAT to a proto_tree */
5797proto_item *
5798proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5799 int length, float value)
5800{
5801 proto_item *pi;
5802 header_field_info *hfinfo;
5803
5804 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5805
5806 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", 5806
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5806, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5806, "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", 5806, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5807
5808 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",
5808, ((hfinfo))->abbrev))))
;
5809
5810 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5811 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5812
5813 return pi;
5814}
5815
5816proto_item *
5817proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5818 int start, int length, float value,
5819 const char *format, ...)
5820{
5821 proto_item *pi;
5822 va_list ap;
5823
5824 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5825 if (pi != tree) {
5826 va_start(ap, format)__builtin_va_start(ap, format);
5827 proto_tree_set_representation_value(pi, format, ap);
5828 va_end(ap)__builtin_va_end(ap);
5829 }
5830
5831 return pi;
5832}
5833
5834proto_item *
5835proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5836 int start, int length, float value,
5837 const char *format, ...)
5838{
5839 proto_item *pi;
5840 va_list ap;
5841
5842 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5843 if (pi != tree) {
5844 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5844, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5845
5846 va_start(ap, format)__builtin_va_start(ap, format);
5847 proto_tree_set_representation(pi, format, ap);
5848 va_end(ap)__builtin_va_end(ap);
5849 }
5850
5851 return pi;
5852}
5853
5854/* Set the FT_FLOAT value */
5855static void
5856proto_tree_set_float(field_info *fi, float value)
5857{
5858 fvalue_set_floating(fi->value, value);
5859}
5860
5861/* Add a FT_DOUBLE to a proto_tree */
5862proto_item *
5863proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5864 int length, double value)
5865{
5866 proto_item *pi;
5867 header_field_info *hfinfo;
5868
5869 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5870
5871 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", 5871
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5871, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5871, "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", 5871, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5872
5873 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"
, 5873, ((hfinfo))->abbrev))))
;
5874
5875 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5876 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5877
5878 return pi;
5879}
5880
5881proto_item *
5882proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5883 int start, int length, double value,
5884 const char *format, ...)
5885{
5886 proto_item *pi;
5887 va_list ap;
5888
5889 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5890 if (pi != tree) {
5891 va_start(ap, format)__builtin_va_start(ap, format);
5892 proto_tree_set_representation_value(pi, format, ap);
5893 va_end(ap)__builtin_va_end(ap);
5894 }
5895
5896 return pi;
5897}
5898
5899proto_item *
5900proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5901 int start, int length, double value,
5902 const char *format, ...)
5903{
5904 proto_item *pi;
5905 va_list ap;
5906
5907 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5908 if (pi != tree) {
5909 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5909, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5910
5911 va_start(ap, format)__builtin_va_start(ap, format);
5912 proto_tree_set_representation(pi, format, ap);
5913 va_end(ap)__builtin_va_end(ap);
5914 }
5915
5916 return pi;
5917}
5918
5919/* Set the FT_DOUBLE value */
5920static void
5921proto_tree_set_double(field_info *fi, double value)
5922{
5923 fvalue_set_floating(fi->value, value);
5924}
5925
5926/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5927proto_item *
5928proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5929 int length, uint32_t value)
5930{
5931 proto_item *pi = NULL((void*)0);
5932 header_field_info *hfinfo;
5933
5934 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5935
5936 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", 5936
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5936, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5936, "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", 5936, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5937
5938 switch (hfinfo->type) {
5939 case FT_CHAR:
5940 case FT_UINT8:
5941 case FT_UINT16:
5942 case FT_UINT24:
5943 case FT_UINT32:
5944 case FT_FRAMENUM:
5945 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5946 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5947 break;
5948
5949 default:
5950 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)
5951 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)
;
5952 }
5953
5954 return pi;
5955}
5956
5957proto_item *
5958proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5959 int start, int length, uint32_t value,
5960 const char *format, ...)
5961{
5962 proto_item *pi;
5963 va_list ap;
5964
5965 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5966 if (pi != tree) {
5967 va_start(ap, format)__builtin_va_start(ap, format);
5968 proto_tree_set_representation_value(pi, format, ap);
5969 va_end(ap)__builtin_va_end(ap);
5970 }
5971
5972 return pi;
5973}
5974
5975proto_item *
5976proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5977 int start, int length, uint32_t value,
5978 const char *format, ...)
5979{
5980 proto_item *pi;
5981 va_list ap;
5982
5983 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5984 if (pi != tree) {
5985 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5985, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5986
5987 va_start(ap, format)__builtin_va_start(ap, format);
5988 proto_tree_set_representation(pi, format, ap);
5989 va_end(ap)__builtin_va_end(ap);
5990 }
5991
5992 return pi;
5993}
5994
5995/* Set the FT_UINT{8,16,24,32} value */
5996static void
5997proto_tree_set_uint(field_info *fi, uint32_t value)
5998{
5999 const header_field_info *hfinfo;
6000 uint32_t integer;
6001
6002 hfinfo = fi->hfinfo;
6003 integer = value;
6004
6005 if (hfinfo->bitmask) {
6006 /* Mask out irrelevant portions */
6007 integer &= (uint32_t)(hfinfo->bitmask);
6008
6009 /* Shift bits */
6010 integer >>= hfinfo_bitshift(hfinfo);
6011
6012 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6013 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)
;
6014 }
6015
6016 fvalue_set_uinteger(fi->value, integer);
6017}
6018
6019/* Add FT_UINT{40,48,56,64} to a proto_tree */
6020proto_item *
6021proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6022 int length, uint64_t value)
6023{
6024 proto_item *pi = NULL((void*)0);
6025 header_field_info *hfinfo;
6026
6027 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6028
6029 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", 6029
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6029, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6029, "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", 6029, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6030
6031 switch (hfinfo->type) {
6032 case FT_UINT40:
6033 case FT_UINT48:
6034 case FT_UINT56:
6035 case FT_UINT64:
6036 case FT_FRAMENUM:
6037 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6038 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6039 break;
6040
6041 default:
6042 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)
6043 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)
;
6044 }
6045
6046 return pi;
6047}
6048
6049proto_item *
6050proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6051 int start, int length, uint64_t value,
6052 const char *format, ...)
6053{
6054 proto_item *pi;
6055 va_list ap;
6056
6057 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6058 if (pi != tree) {
6059 va_start(ap, format)__builtin_va_start(ap, format);
6060 proto_tree_set_representation_value(pi, format, ap);
6061 va_end(ap)__builtin_va_end(ap);
6062 }
6063
6064 return pi;
6065}
6066
6067proto_item *
6068proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6069 int start, int length, uint64_t value,
6070 const char *format, ...)
6071{
6072 proto_item *pi;
6073 va_list ap;
6074
6075 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6076 if (pi != tree) {
6077 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6077, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6078
6079 va_start(ap, format)__builtin_va_start(ap, format);
6080 proto_tree_set_representation(pi, format, ap);
6081 va_end(ap)__builtin_va_end(ap);
6082 }
6083
6084 return pi;
6085}
6086
6087/* Set the FT_UINT{40,48,56,64} value */
6088static void
6089proto_tree_set_uint64(field_info *fi, uint64_t value)
6090{
6091 const header_field_info *hfinfo;
6092 uint64_t integer;
6093
6094 hfinfo = fi->hfinfo;
6095 integer = value;
6096
6097 if (hfinfo->bitmask) {
6098 /* Mask out irrelevant portions */
6099 integer &= hfinfo->bitmask;
6100
6101 /* Shift bits */
6102 integer >>= hfinfo_bitshift(hfinfo);
6103
6104 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6105 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)
;
6106 }
6107
6108 fvalue_set_uinteger64(fi->value, integer);
6109}
6110
6111/* Add FT_INT{8,16,24,32} to a proto_tree */
6112proto_item *
6113proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6114 int length, int32_t value)
6115{
6116 proto_item *pi = NULL((void*)0);
6117 header_field_info *hfinfo;
6118
6119 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6120
6121 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", 6121
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6121, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6121, "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", 6121, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6122
6123 switch (hfinfo->type) {
6124 case FT_INT8:
6125 case FT_INT16:
6126 case FT_INT24:
6127 case FT_INT32:
6128 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6129 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6130 break;
6131
6132 default:
6133 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)
6134 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6135 }
6136
6137 return pi;
6138}
6139
6140proto_item *
6141proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6142 int start, int length, int32_t value,
6143 const char *format, ...)
6144{
6145 proto_item *pi;
6146 va_list ap;
6147
6148 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6149 if (pi != tree) {
6150 va_start(ap, format)__builtin_va_start(ap, format);
6151 proto_tree_set_representation_value(pi, format, ap);
6152 va_end(ap)__builtin_va_end(ap);
6153 }
6154
6155 return pi;
6156}
6157
6158proto_item *
6159proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6160 int start, int length, int32_t value,
6161 const char *format, ...)
6162{
6163 proto_item *pi;
6164 va_list ap;
6165
6166 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6167 if (pi != tree) {
6168 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6168, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6169
6170 va_start(ap, format)__builtin_va_start(ap, format);
6171 proto_tree_set_representation(pi, format, ap);
6172 va_end(ap)__builtin_va_end(ap);
6173 }
6174
6175 return pi;
6176}
6177
6178/* Set the FT_INT{8,16,24,32} value */
6179static void
6180proto_tree_set_int(field_info *fi, int32_t value)
6181{
6182 const header_field_info *hfinfo;
6183 uint32_t integer;
6184 int no_of_bits;
6185
6186 hfinfo = fi->hfinfo;
6187 integer = (uint32_t) value;
6188
6189 if (hfinfo->bitmask) {
6190 /* Mask out irrelevant portions */
6191 integer &= (uint32_t)(hfinfo->bitmask);
6192
6193 /* Shift bits */
6194 integer >>= hfinfo_bitshift(hfinfo);
6195
6196 no_of_bits = ws_count_ones(hfinfo->bitmask);
6197 integer = ws_sign_ext32(integer, no_of_bits);
6198
6199 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6200 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)
;
6201 }
6202
6203 fvalue_set_sinteger(fi->value, integer);
6204}
6205
6206/* Add FT_INT{40,48,56,64} to a proto_tree */
6207proto_item *
6208proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6209 int length, int64_t value)
6210{
6211 proto_item *pi = NULL((void*)0);
6212 header_field_info *hfinfo;
6213
6214 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6215
6216 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", 6216
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6216, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6216, "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", 6216, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6217
6218 switch (hfinfo->type) {
6219 case FT_INT40:
6220 case FT_INT48:
6221 case FT_INT56:
6222 case FT_INT64:
6223 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6224 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6225 break;
6226
6227 default:
6228 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)
6229 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6230 }
6231
6232 return pi;
6233}
6234
6235proto_item *
6236proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6237 int start, int length, int64_t value,
6238 const char *format, ...)
6239{
6240 proto_item *pi;
6241 va_list ap;
6242
6243 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6244 if (pi != tree) {
6245 va_start(ap, format)__builtin_va_start(ap, format);
6246 proto_tree_set_representation_value(pi, format, ap);
6247 va_end(ap)__builtin_va_end(ap);
6248 }
6249
6250 return pi;
6251}
6252
6253/* Set the FT_INT{40,48,56,64} value */
6254static void
6255proto_tree_set_int64(field_info *fi, int64_t value)
6256{
6257 const header_field_info *hfinfo;
6258 uint64_t integer;
6259 int no_of_bits;
6260
6261 hfinfo = fi->hfinfo;
6262 integer = value;
6263
6264 if (hfinfo->bitmask) {
6265 /* Mask out irrelevant portions */
6266 integer &= hfinfo->bitmask;
6267
6268 /* Shift bits */
6269 integer >>= hfinfo_bitshift(hfinfo);
6270
6271 no_of_bits = ws_count_ones(hfinfo->bitmask);
6272 integer = ws_sign_ext64(integer, no_of_bits);
6273
6274 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6275 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)
;
6276 }
6277
6278 fvalue_set_sinteger64(fi->value, integer);
6279}
6280
6281proto_item *
6282proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6283 int start, int length, int64_t value,
6284 const char *format, ...)
6285{
6286 proto_item *pi;
6287 va_list ap;
6288
6289 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6290 if (pi != tree) {
6291 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6291, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6292
6293 va_start(ap, format)__builtin_va_start(ap, format);
6294 proto_tree_set_representation(pi, format, ap);
6295 va_end(ap)__builtin_va_end(ap);
6296 }
6297
6298 return pi;
6299}
6300
6301/* Add a FT_EUI64 to a proto_tree */
6302proto_item *
6303proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6304 int length, const uint64_t value)
6305{
6306 proto_item *pi;
6307 header_field_info *hfinfo;
6308
6309 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6310
6311 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", 6311
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6311, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6311, "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", 6311, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6312
6313 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",
6313, ((hfinfo))->abbrev))))
;
6314
6315 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6316 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6317
6318 return pi;
6319}
6320
6321proto_item *
6322proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6323 int start, int length, const uint64_t value,
6324 const char *format, ...)
6325{
6326 proto_item *pi;
6327 va_list ap;
6328
6329 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6330 if (pi != tree) {
6331 va_start(ap, format)__builtin_va_start(ap, format);
6332 proto_tree_set_representation_value(pi, format, ap);
6333 va_end(ap)__builtin_va_end(ap);
6334 }
6335
6336 return pi;
6337}
6338
6339proto_item *
6340proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6341 int start, int length, const uint64_t value,
6342 const char *format, ...)
6343{
6344 proto_item *pi;
6345 va_list ap;
6346
6347 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6348 if (pi != tree) {
6349 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6349, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6350
6351 va_start(ap, format)__builtin_va_start(ap, format);
6352 proto_tree_set_representation(pi, format, ap);
6353 va_end(ap)__builtin_va_end(ap);
6354 }
6355
6356 return pi;
6357}
6358
6359/* Set the FT_EUI64 value */
6360static void
6361proto_tree_set_eui64(field_info *fi, const uint64_t value)
6362{
6363 uint8_t v[FT_EUI64_LEN8];
6364 phtonu64(v, value);
6365 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6366}
6367
6368static void
6369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6370{
6371 if (encoding)
6372 {
6373 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6374 } else {
6375 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6376 }
6377}
6378
6379proto_item *
6380proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6381 const mac_hf_list_t *list_generic,
6382 int idx, tvbuff_t *tvb,
6383 proto_tree *tree, int offset)
6384{
6385 uint8_t addr[6];
6386 const char *addr_name = NULL((void*)0);
6387 const char *oui_name = NULL((void*)0);
6388 proto_item *addr_item = NULL((void*)0);
6389 proto_tree *addr_tree = NULL((void*)0);
6390 proto_item *ret_val = NULL((void*)0);
6391
6392 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6393 return NULL((void*)0);
6394 }
6395
6396 /* Resolve what we can of the address */
6397 tvb_memcpy(tvb, addr, offset, sizeof addr);
6398 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6399 addr_name = get_ether_name(addr);
6400 }
6401 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6402 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6403 }
6404
6405 /* Add the item for the specific address type */
6406 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6407 if (idx >= 0) {
6408 addr_tree = proto_item_add_subtree(ret_val, idx);
6409 }
6410 else {
6411 addr_tree = tree;
6412 }
6413
6414 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6415 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6416 tvb, offset, 6, addr_name);
6417 proto_item_set_generated(addr_item);
6418 proto_item_set_hidden(addr_item);
6419 }
6420
6421 if (list_specific->hf_oui != NULL((void*)0)) {
6422 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6423 proto_item_set_generated(addr_item);
6424 proto_item_set_hidden(addr_item);
6425
6426 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6427 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6428 proto_item_set_generated(addr_item);
6429 proto_item_set_hidden(addr_item);
6430 }
6431 }
6432
6433 if (list_specific->hf_lg != NULL((void*)0)) {
6434 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6435 }
6436 if (list_specific->hf_ig != NULL((void*)0)) {
6437 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6438 }
6439
6440 /* Were we given a list for generic address fields? If not, stop here */
6441 if (list_generic == NULL((void*)0)) {
6442 return ret_val;
6443 }
6444
6445 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6446 proto_item_set_hidden(addr_item);
6447
6448 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6449 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6450 tvb, offset, 6, addr_name);
6451 proto_item_set_generated(addr_item);
6452 proto_item_set_hidden(addr_item);
6453 }
6454
6455 if (list_generic->hf_oui != NULL((void*)0)) {
6456 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6457 proto_item_set_generated(addr_item);
6458 proto_item_set_hidden(addr_item);
6459
6460 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6461 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6462 proto_item_set_generated(addr_item);
6463 proto_item_set_hidden(addr_item);
6464 }
6465 }
6466
6467 if (list_generic->hf_lg != NULL((void*)0)) {
6468 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6469 proto_item_set_hidden(addr_item);
6470 }
6471 if (list_generic->hf_ig != NULL((void*)0)) {
6472 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6473 proto_item_set_hidden(addr_item);
6474 }
6475 return ret_val;
6476}
6477
6478static proto_item *
6479proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6480{
6481 proto_node *pnode, *tnode, *sibling;
6482 field_info *tfi;
6483 unsigned depth = 1;
6484
6485 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6485, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6486
6487 /*
6488 * Restrict our depth. proto_tree_traverse_pre_order and
6489 * proto_tree_traverse_post_order (and possibly others) are recursive
6490 * so we need to be mindful of our stack size.
6491 */
6492 if (tree->first_child == NULL((void*)0)) {
6493 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6494 depth++;
6495 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6496 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__)), 6499)))
6497 "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__)), 6499)))
6498 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__)), 6499)))
6499 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__)), 6499)))
;
6500 }
6501 }
6502 }
6503
6504 /*
6505 * Make sure "tree" is ready to have subtrees under it, by
6506 * checking whether it's been given an ett_ value.
6507 *
6508 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6509 * node of the protocol tree. That node is not displayed,
6510 * so it doesn't need an ett_ value to remember whether it
6511 * was expanded.
6512 */
6513 tnode = tree;
6514 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6515 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6516 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"
, 6517)
6517 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"
, 6517)
;
6518 /* XXX - is it safe to continue here? */
6519 }
6520
6521 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6522 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6523 pnode->parent = tnode;
6524 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6525 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6526 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6527
6528 if (tnode->last_child != NULL((void*)0)) {
6529 sibling = tnode->last_child;
6530 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6530, "sibling->next == ((void*)0)"
))))
;
6531 sibling->next = pnode;
6532 } else
6533 tnode->first_child = pnode;
6534 tnode->last_child = pnode;
6535
6536 /* We should not be adding a fake node for an interesting field */
6537 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", 6537, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6538
6539 /* XXX - Should the proto_item have a header_field_info member, at least
6540 * for faked items, to know what hfi was faked? (Some dissectors look at
6541 * the tree items directly.)
6542 */
6543 return (proto_item *)pnode;
6544}
6545
6546/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6547static proto_item *
6548proto_tree_add_node(proto_tree *tree, field_info *fi)
6549{
6550 proto_node *pnode, *tnode, *sibling;
6551 field_info *tfi;
6552 unsigned depth = 1;
6553
6554 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6554, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6555
6556 /*
6557 * Restrict our depth. proto_tree_traverse_pre_order and
6558 * proto_tree_traverse_post_order (and possibly others) are recursive
6559 * so we need to be mindful of our stack size.
6560 */
6561 if (tree->first_child == NULL((void*)0)) {
6562 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6563 depth++;
6564 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6565 fvalue_free(fi->value);
6566 fi->value = NULL((void*)0);
6567 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__)), 6570)))
6568 "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__)), 6570)))
6569 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__)), 6570)))
6570 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__)), 6570)))
;
6571 }
6572 }
6573 }
6574
6575 /*
6576 * Make sure "tree" is ready to have subtrees under it, by
6577 * checking whether it's been given an ett_ value.
6578 *
6579 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6580 * node of the protocol tree. That node is not displayed,
6581 * so it doesn't need an ett_ value to remember whether it
6582 * was expanded.
6583 */
6584 tnode = tree;
6585 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6586 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6587 /* Since we are not adding fi to a node, its fvalue won't get
6588 * freed by proto_tree_free_node(), so free it now.
6589 */
6590 fvalue_free(fi->value);
6591 fi->value = NULL((void*)0);
6592 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", 6593)
6593 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", 6593)
;
6594 /* XXX - is it safe to continue here? */
6595 }
6596
6597 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6598 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6599 pnode->parent = tnode;
6600 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6601 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6602 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6603
6604 if (tnode->last_child != NULL((void*)0)) {
6605 sibling = tnode->last_child;
6606 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6606, "sibling->next == ((void*)0)"
))))
;
6607 sibling->next = pnode;
6608 } else
6609 tnode->first_child = pnode;
6610 tnode->last_child = pnode;
6611
6612 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6613
6614 return (proto_item *)pnode;
6615}
6616
6617
6618/* Generic way to allocate field_info and add to proto_tree.
6619 * Sets *pfi to address of newly-allocated field_info struct */
6620static proto_item *
6621proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6622 int *length)
6623{
6624 proto_item *pi;
6625 field_info *fi;
6626 int item_length;
6627
6628 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6629 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6630 pi = proto_tree_add_node(tree, fi);
6631
6632 return pi;
6633}
6634
6635
6636static void
6637get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6638 int *item_length, const unsigned encoding)
6639{
6640 int length_remaining;
6641
6642 /*
6643 * We only allow a null tvbuff if the item has a zero length,
6644 * i.e. if there's no data backing it.
6645 */
6646 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", 6646, "tvb != ((void*)0) || *length == 0"
))))
;
6647
6648 /*
6649 * XXX - in some protocols, there are 32-bit unsigned length
6650 * fields, so lengths in protocol tree and tvbuff routines
6651 * should really be unsigned. We should have, for those
6652 * field types for which "to the end of the tvbuff" makes sense,
6653 * additional routines that take no length argument and
6654 * add fields that run to the end of the tvbuff.
6655 */
6656 if (*length == -1) {
6657 /*
6658 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6659 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6660 * of -1 means "set the length to what remains in the
6661 * tvbuff".
6662 *
6663 * The assumption is either that
6664 *
6665 * 1) the length of the item can only be determined
6666 * by dissection (typically true of items with
6667 * subitems, which are probably FT_NONE or
6668 * FT_PROTOCOL)
6669 *
6670 * or
6671 *
6672 * 2) if the tvbuff is "short" (either due to a short
6673 * snapshot length or due to lack of reassembly of
6674 * fragments/segments/whatever), we want to display
6675 * what's available in the field (probably FT_BYTES
6676 * or FT_STRING) and then throw an exception later
6677 *
6678 * or
6679 *
6680 * 3) the field is defined to be "what's left in the
6681 * packet"
6682 *
6683 * so we set the length to what remains in the tvbuff so
6684 * that, if we throw an exception while dissecting, it
6685 * has what is probably the right value.
6686 *
6687 * For FT_STRINGZ, it means "the string is null-terminated,
6688 * not null-padded; set the length to the actual length
6689 * of the string", and if the tvbuff if short, we just
6690 * throw an exception.
6691 *
6692 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6693 * it means "find the end of the string",
6694 * and if the tvbuff if short, we just throw an exception.
6695 *
6696 * It's not valid for any other type of field. For those
6697 * fields, we treat -1 the same way we treat other
6698 * negative values - we assume the length is a Really
6699 * Big Positive Number, and throw a ReportedBoundsError
6700 * exception, under the assumption that the Really Big
6701 * Length would run past the end of the packet.
6702 */
6703 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
))
)) {
6704 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6705 /*
6706 * Leave the length as -1, so our caller knows
6707 * it was -1.
6708 */
6709 *item_length = *length;
6710 return;
6711 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6712 switch (tvb_get_uint8(tvb, start) >> 6)
6713 {
6714 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6715 *item_length = 1;
6716 break;
6717 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6718 *item_length = 2;
6719 break;
6720 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6721 *item_length = 4;
6722 break;
6723 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6724 *item_length = 8;
6725 break;
6726 }
6727 }
6728 }
6729
6730 switch (hfinfo->type) {
6731
6732 case FT_PROTOCOL:
6733 case FT_NONE:
6734 case FT_BYTES:
6735 case FT_STRING:
6736 case FT_STRINGZPAD:
6737 case FT_STRINGZTRUNC:
6738 /*
6739 * We allow FT_PROTOCOLs to be zero-length -
6740 * for example, an ONC RPC NULL procedure has
6741 * neither arguments nor reply, so the
6742 * payload for that protocol is empty.
6743 *
6744 * We also allow the others to be zero-length -
6745 * because that's the way the code has been for a
6746 * long, long time.
6747 *
6748 * However, we want to ensure that the start
6749 * offset is not *past* the byte past the end
6750 * of the tvbuff: we throw an exception in that
6751 * case.
6752 */
6753 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6754 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6754, "*length >= 0"
))))
;
6755 break;
6756
6757 case FT_STRINGZ:
6758 /*
6759 * Leave the length as -1, so our caller knows
6760 * it was -1.
6761 */
6762 break;
6763
6764 default:
6765 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6766 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6766))
;
6767 }
6768 *item_length = *length;
6769 } else {
6770 *item_length = *length;
6771 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6772 /*
6773 * These types are for interior nodes of the
6774 * tree, and don't have data associated with
6775 * them; if the length is negative (XXX - see
6776 * above) or goes past the end of the tvbuff,
6777 * cut it short at the end of the tvbuff.
6778 * That way, if this field is selected in
6779 * Wireshark, we don't highlight stuff past
6780 * the end of the data.
6781 */
6782 /* XXX - what to do, if we don't have a tvb? */
6783 if (tvb) {
6784 length_remaining = tvb_captured_length_remaining(tvb, start);
6785 if (*item_length < 0 ||
6786 (*item_length > 0 &&
6787 (length_remaining < *item_length)))
6788 *item_length = length_remaining;
6789 }
6790 }
6791 if (*item_length < 0) {
6792 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6793 }
6794 }
6795}
6796
6797static void
6798get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6799 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6800{
6801 unsigned length_remaining;
6802
6803 /*
6804 * We only allow a null tvbuff if the item has a zero length,
6805 * i.e. if there's no data backing it.
6806 */
6807 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", 6807, "tvb != ((void*)0) || *length == 0"
))))
;
6808
6809
6810 *item_length = *length;
6811 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6812 /*
6813 * These types are for interior nodes of the
6814 * tree, and don't have data associated with
6815 * them; if the length is negative (XXX - see
6816 * above) or goes past the end of the tvbuff,
6817 * cut it short at the end of the tvbuff.
6818 * That way, if this field is selected in
6819 * Wireshark, we don't highlight stuff past
6820 * the end of the data.
6821 */
6822 /* XXX - what to do, if we don't have a tvb? */
6823 if (tvb) {
6824 length_remaining = tvb_captured_length_remaining(tvb, start);
6825 if (*item_length > 0 && (length_remaining < *item_length)) {
6826 *item_length = length_remaining;
6827 }
6828 }
6829 }
6830}
6831
6832static int
6833get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6834 int length, unsigned item_length, const int encoding)
6835{
6836 uint32_t n;
6837
6838 /*
6839 * We need to get the correct item length here.
6840 * That's normally done by proto_tree_new_item(),
6841 * but we won't be calling it.
6842 */
6843 switch (hfinfo->type) {
6844
6845 case FT_NONE:
6846 case FT_PROTOCOL:
6847 case FT_BYTES:
6848 /*
6849 * The length is the specified length.
6850 */
6851 break;
6852
6853 case FT_UINT_BYTES:
6854 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6855 item_length += n;
6856 if ((int)item_length < length) {
6857 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6858 }
6859 break;
6860
6861 /* XXX - make these just FT_UINT? */
6862 case FT_UINT8:
6863 case FT_UINT16:
6864 case FT_UINT24:
6865 case FT_UINT32:
6866 case FT_UINT40:
6867 case FT_UINT48:
6868 case FT_UINT56:
6869 case FT_UINT64:
6870 /* XXX - make these just FT_INT? */
6871 case FT_INT8:
6872 case FT_INT16:
6873 case FT_INT24:
6874 case FT_INT32:
6875 case FT_INT40:
6876 case FT_INT48:
6877 case FT_INT56:
6878 case FT_INT64:
6879 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6880 if (length < -1) {
6881 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6882 }
6883 if (length == -1) {
6884 uint64_t dummy;
6885 /* This can throw an exception */
6886 /* XXX - do this without fetching the varint? */
6887 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6888 if (length == 0) {
6889 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6890 }
6891 }
6892 item_length = length;
6893 break;
6894 }
6895
6896 /*
6897 * The length is the specified length.
6898 */
6899 break;
6900
6901 case FT_BOOLEAN:
6902 case FT_CHAR:
6903 case FT_IPv4:
6904 case FT_IPXNET:
6905 case FT_IPv6:
6906 case FT_FCWWN:
6907 case FT_AX25:
6908 case FT_VINES:
6909 case FT_ETHER:
6910 case FT_EUI64:
6911 case FT_GUID:
6912 case FT_OID:
6913 case FT_REL_OID:
6914 case FT_SYSTEM_ID:
6915 case FT_FLOAT:
6916 case FT_DOUBLE:
6917 case FT_STRING:
6918 /*
6919 * The length is the specified length.
6920 */
6921 break;
6922
6923 case FT_STRINGZ:
6924 if (length < -1) {
6925 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6926 }
6927 if (length == -1) {
6928 /* This can throw an exception */
6929 item_length = tvb_strsize_enc(tvb, start, encoding);
6930 }
6931 break;
6932
6933 case FT_UINT_STRING:
6934 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6935 item_length += n;
6936 if ((int)item_length < length) {
6937 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6938 }
6939 break;
6940
6941 case FT_STRINGZPAD:
6942 case FT_STRINGZTRUNC:
6943 case FT_ABSOLUTE_TIME:
6944 case FT_RELATIVE_TIME:
6945 case FT_IEEE_11073_SFLOAT:
6946 case FT_IEEE_11073_FLOAT:
6947 /*
6948 * The length is the specified length.
6949 */
6950 break;
6951
6952 default:
6953 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
))
6954 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
))
6955 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
))
6956 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
))
;
6957 break;
6958 }
6959 return item_length;
6960}
6961
6962// This was arbitrarily chosen, but if you're adding 50K items to the tree
6963// without advancing the offset you should probably take a long, hard look
6964// at what you're doing.
6965// We *could* make this a configurable option, but I (Gerald) would like to
6966// avoid adding yet another nerd knob.
6967# define PROTO_TREE_MAX_IDLE50000 50000
6968static field_info *
6969new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6970 const int start, const int item_length)
6971{
6972 field_info *fi;
6973
6974 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6975
6976 fi->hfinfo = hfinfo;
6977 fi->start = start;
6978 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6979 /* add the data source tvbuff */
6980 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6981
6982 // If our start offset hasn't advanced after adding many items it probably
6983 // means we're in a large or infinite loop.
6984 if (fi->start > 0) {
6985 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6986 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6987 DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6987, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6988 } else {
6989 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6990 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6991 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6992 }
6993 }
6994 fi->length = item_length;
6995 fi->tree_type = -1;
6996 fi->flags = 0;
6997 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6998 /* If the tree is not visible, set the item hidden, unless we
6999 * need the representation or length and can't fake them.
7000 */
7001 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7002 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7003 }
7004 }
7005 fi->value = fvalue_new(fi->hfinfo->type);
7006 fi->rep = NULL((void*)0);
7007
7008 fi->appendix_start = 0;
7009 fi->appendix_length = 0;
7010
7011 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7012 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7013
7014 return fi;
7015}
7016
7017static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7018{
7019 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7020 return 0;
7021 }
7022
7023 /* Search for field name */
7024 char *ptr = strstr(representation, hfinfo->name);
7025 if (!ptr) {
7026 return 0;
7027 }
7028
7029 /* Check if field name ends with the ": " delimiter */
7030 ptr += strlen(hfinfo->name);
7031 if (strncmp(ptr, ": ", 2) == 0) {
7032 ptr += 2;
7033 }
7034
7035 /* Return offset to after field name */
7036 return ptr - representation;
7037}
7038
7039static size_t label_find_name_pos(const item_label_t *rep)
7040{
7041 size_t name_pos = 0;
7042
7043 /* If the value_pos is too small or too large, we can't find the expected format */
7044 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7045 return 0;
7046 }
7047
7048 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7049 if (rep->representation[rep->value_pos-2] == ':') {
7050 name_pos = rep->value_pos - 2;
7051 }
7052
7053 return name_pos;
7054}
7055
7056/* If the protocol tree is to be visible, set the representation of a
7057 proto_tree entry with the name of the field for the item and with
7058 the value formatted with the supplied printf-style format and
7059 argument list. */
7060static void
7061proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7062{
7063 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7063, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7064
7065 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7066 * items string representation */
7067 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7068 size_t name_pos, ret = 0;
7069 char *str;
7070 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7071 const header_field_info *hf;
7072
7073 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7073, "fi"))))
;
7074
7075 hf = fi->hfinfo;
7076
7077 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;
;
7078 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))
)) {
7079 uint64_t val;
7080 char *p;
7081
7082 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)
)
7083 val = fvalue_get_uinteger(fi->value);
7084 else
7085 val = fvalue_get_uinteger64(fi->value);
7086
7087 val <<= hfinfo_bitshift(hf);
7088
7089 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7090 ret = (p - fi->rep->representation);
7091 }
7092
7093 /* put in the hf name */
7094 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)
;
7095
7096 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7097 /* If possible, Put in the value of the string */
7098 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7099 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"
, 7099, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7100 fi->rep->value_pos = ret;
7101 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7102 if (ret >= ITEM_LABEL_LENGTH240) {
7103 /* Uh oh, we don't have enough room. Tell the user
7104 * that the field is truncated.
7105 */
7106 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7107 }
7108 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7109 }
7110}
7111
7112/* If the protocol tree is to be visible, set the representation of a
7113 proto_tree entry with the representation formatted with the supplied
7114 printf-style format and argument list. */
7115static void
7116proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7117{
7118 size_t ret; /*tmp return value */
7119 char *str;
7120 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7121
7122 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7122, "fi"))))
;
7123
7124 if (!proto_item_is_hidden(pi)) {
7125 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;
;
7126
7127 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7128 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"
, 7128, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7129 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7130 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7131 if (ret >= ITEM_LABEL_LENGTH240) {
7132 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7133 size_t name_pos = label_find_name_pos(fi->rep);
7134 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7135 }
7136 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7137 }
7138}
7139
7140static int
7141proto_strlcpy(char *dest, const char *src, size_t dest_size)
7142{
7143 if (dest_size == 0) return 0;
7144
7145 size_t res = g_strlcpy(dest, src, dest_size);
7146
7147 /* At most dest_size - 1 characters will be copied
7148 * (unless dest_size is 0). */
7149 if (res >= dest_size)
7150 res = dest_size - 1;
7151 return (int) res;
7152}
7153
7154static header_field_info *
7155hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7156{
7157 header_field_info *dup_hfinfo;
7158
7159 if (hfinfo->same_name_prev_id == -1)
7160 return NULL((void*)0);
7161 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", 7161
, __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", 7161, "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", 7161,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7162 return dup_hfinfo;
7163}
7164
7165static void
7166hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7167{
7168 g_free(last_field_name);
7169 last_field_name = NULL((void*)0);
7170
7171 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7172 /* No hfinfo with the same name */
7173 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7174 return;
7175 }
7176
7177 if (hfinfo->same_name_next) {
7178 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7179 }
7180
7181 if (hfinfo->same_name_prev_id != -1) {
7182 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7183 same_name_prev->same_name_next = hfinfo->same_name_next;
7184 if (!hfinfo->same_name_next) {
7185 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7186 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7187 }
7188 }
7189}
7190
7191int
7192proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7193{
7194 const header_field_info *hfinfo = finfo->hfinfo;
7195 int label_len = 0;
7196 char *tmp_str;
7197 const char *str;
7198 const uint8_t *bytes;
7199 uint32_t number;
7200 uint64_t number64;
7201 const char *hf_str_val;
7202 char number_buf[NUMBER_LABEL_LENGTH80];
7203 const char *number_out;
7204 address addr;
7205 const ipv4_addr_and_mask *ipv4;
7206 const ipv6_addr_and_prefix *ipv6;
7207
7208 switch (hfinfo->type) {
7209
7210 case FT_NONE:
7211 case FT_PROTOCOL:
7212 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7213
7214 case FT_UINT_BYTES:
7215 case FT_BYTES:
7216 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7217 hfinfo,
7218 fvalue_get_bytes_data(finfo->value),
7219 (unsigned)fvalue_length2(finfo->value),
7220 label_str_size);
7221 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7222 wmem_free(NULL((void*)0), tmp_str);
7223 break;
7224
7225 case FT_ABSOLUTE_TIME:
7226 {
7227 const nstime_t *value = fvalue_get_time(finfo->value);
7228 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7229 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7230 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7231 }
7232 if (hfinfo->strings) {
7233 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7234 if (time_string != NULL((void*)0)) {
7235 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7236 break;
7237 }
7238 }
7239 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7240 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7241 wmem_free(NULL((void*)0), tmp_str);
7242 break;
7243 }
7244
7245 case FT_RELATIVE_TIME:
7246 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7247 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7248 wmem_free(NULL((void*)0), tmp_str);
7249 break;
7250
7251 case FT_BOOLEAN:
7252 number64 = fvalue_get_uinteger64(finfo->value);
7253 label_len = proto_strlcpy(display_label_str,
7254 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7255 break;
7256
7257 case FT_CHAR:
7258 number = fvalue_get_uinteger(finfo->value);
7259
7260 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7261 char tmp[ITEM_LABEL_LENGTH240];
7262 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7263
7264 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7264, "fmtfunc"))))
;
7265 fmtfunc(tmp, number);
7266
7267 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7268
7269 } else if (hfinfo->strings) {
7270 number_out = hf_try_val_to_str(number, hfinfo);
7271
7272 if (!number_out) {
7273 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7274 }
7275
7276 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7277
7278 } else {
7279 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7280
7281 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7282 }
7283
7284 break;
7285
7286 /* XXX - make these just FT_NUMBER? */
7287 case FT_INT8:
7288 case FT_INT16:
7289 case FT_INT24:
7290 case FT_INT32:
7291 case FT_UINT8:
7292 case FT_UINT16:
7293 case FT_UINT24:
7294 case FT_UINT32:
7295 case FT_FRAMENUM:
7296 hf_str_val = NULL((void*)0);
7297 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
))
?
7298 (uint32_t) fvalue_get_sinteger(finfo->value) :
7299 fvalue_get_uinteger(finfo->value);
7300
7301 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7302 char tmp[ITEM_LABEL_LENGTH240];
7303 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7304
7305 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7305, "fmtfunc"))))
;
7306 fmtfunc(tmp, number);
7307
7308 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7309
7310 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7311 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7312 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7313 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7314 hf_str_val = hf_try_val_to_str(number, hfinfo);
7315 if (hf_str_val)
7316 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7317 } else {
7318 number_out = hf_try_val_to_str(number, hfinfo);
7319
7320 if (!number_out) {
7321 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7322 }
7323
7324 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7325 }
7326 } else {
7327 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7328
7329 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7330 }
7331
7332 break;
7333
7334 case FT_INT40:
7335 case FT_INT48:
7336 case FT_INT56:
7337 case FT_INT64:
7338 case FT_UINT40:
7339 case FT_UINT48:
7340 case FT_UINT56:
7341 case FT_UINT64:
7342 hf_str_val = NULL((void*)0);
7343 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
))
?
7344 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7345 fvalue_get_uinteger64(finfo->value);
7346
7347 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7348 char tmp[ITEM_LABEL_LENGTH240];
7349 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7350
7351 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7351, "fmtfunc64"
))))
;
7352 fmtfunc64(tmp, number64);
7353
7354 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7355 } else if (hfinfo->strings) {
7356 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7357 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7358 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7359 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7360 if (hf_str_val)
7361 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7362 } else {
7363 number_out = hf_try_val64_to_str(number64, hfinfo);
7364
7365 if (!number_out)
7366 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7367
7368 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7369 }
7370 } else {
7371 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7372
7373 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7374 }
7375
7376 break;
7377
7378 case FT_EUI64:
7379 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7380 tmp_str = address_to_display(NULL((void*)0), &addr);
7381 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7382 wmem_free(NULL((void*)0), tmp_str);
7383 break;
7384
7385 case FT_IPv4:
7386 ipv4 = fvalue_get_ipv4(finfo->value);
7387 //XXX: Should we ignore the mask?
7388 set_address_ipv4(&addr, ipv4);
7389 tmp_str = address_to_display(NULL((void*)0), &addr);
7390 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7391 wmem_free(NULL((void*)0), tmp_str);
7392 free_address(&addr);
7393 break;
7394
7395 case FT_IPv6:
7396 ipv6 = fvalue_get_ipv6(finfo->value);
7397 set_address_ipv6(&addr, ipv6);
7398 tmp_str = address_to_display(NULL((void*)0), &addr);
7399 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7400 wmem_free(NULL((void*)0), tmp_str);
7401 free_address(&addr);
7402 break;
7403
7404 case FT_FCWWN:
7405 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7406 tmp_str = address_to_display(NULL((void*)0), &addr);
7407 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7408 wmem_free(NULL((void*)0), tmp_str);
7409 break;
7410
7411 case FT_ETHER:
7412 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7413 tmp_str = address_to_display(NULL((void*)0), &addr);
7414 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7415 wmem_free(NULL((void*)0), tmp_str);
7416 break;
7417
7418 case FT_GUID:
7419 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7420 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7421 wmem_free(NULL((void*)0), tmp_str);
7422 break;
7423
7424 case FT_REL_OID:
7425 bytes = fvalue_get_bytes_data(finfo->value);
7426 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7427 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7428 wmem_free(NULL((void*)0), tmp_str);
7429 break;
7430
7431 case FT_OID:
7432 bytes = fvalue_get_bytes_data(finfo->value);
7433 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7434 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7435 wmem_free(NULL((void*)0), tmp_str);
7436 break;
7437
7438 case FT_SYSTEM_ID:
7439 bytes = fvalue_get_bytes_data(finfo->value);
7440 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7441 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7442 wmem_free(NULL((void*)0), tmp_str);
7443 break;
7444
7445 case FT_FLOAT:
7446 case FT_DOUBLE:
7447 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7448 break;
7449
7450 case FT_IEEE_11073_SFLOAT:
7451 case FT_IEEE_11073_FLOAT:
7452 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7453 break;
7454
7455 case FT_STRING:
7456 case FT_STRINGZ:
7457 case FT_UINT_STRING:
7458 case FT_STRINGZPAD:
7459 case FT_STRINGZTRUNC:
7460 str = fvalue_get_string(finfo->value);
7461 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7462 if (label_len >= label_str_size) {
7463 /* Truncation occurred. Get the real length
7464 * copied (not including '\0') */
7465 label_len = label_str_size ? label_str_size - 1 : 0;
7466 }
7467 break;
7468
7469 default:
7470 /* First try ftype string representation */
7471 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7472 if (!tmp_str) {
7473 /* Default to show as bytes */
7474 bytes = fvalue_get_bytes_data(finfo->value);
7475 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7476 }
7477 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7478 wmem_free(NULL((void*)0), tmp_str);
7479 break;
7480 }
7481 return label_len;
7482}
7483
7484const char *
7485proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7486 char *result, char *expr, const int size)
7487{
7488 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7489 GPtrArray *finfos;
7490 field_info *finfo = NULL((void*)0);
7491 header_field_info* hfinfo;
7492 const char *abbrev = NULL((void*)0);
7493
7494 char *str;
7495 col_custom_t *field_idx;
7496 int field_id;
7497 int ii = 0;
7498
7499 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7499, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7500 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7501 field_id = field_idx->field_id;
7502 if (field_id == 0) {
7503 GPtrArray *fvals = NULL((void*)0);
7504 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7505 if (fvals != NULL((void*)0)) {
7506
7507 // XXX - Handling occurrences is unusual when more
7508 // than one field is involved, e.g. there's four
7509 // results for tcp.port + tcp.port. We may really
7510 // want to apply it to the operands, not the output.
7511 // Note that occurrences are not quite the same as
7512 // the layer operator (should the grammar support
7513 // both?)
7514 /* Calculate single index or set outer boundaries */
7515 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7516 if (occurrence < 0) {
7517 i = occurrence + len;
7518 last = i;
7519 } else if (occurrence > 0) {
7520 i = occurrence - 1;
7521 last = i;
7522 } else {
7523 i = 0;
7524 last = len - 1;
7525 }
7526 if (i < 0 || i >= len) {
7527 g_ptr_array_unref(fvals);
7528 continue;
7529 }
7530 for (; i <= last; i++) {
7531 /* XXX - We could have a "resolved" result
7532 * for types where the value depends only
7533 * on the type, e.g. FT_IPv4, and not on
7534 * hfinfo->strings. Supporting the latter
7535 * requires knowing which hfinfo matched
7536 * if there are multiple with the same
7537 * abbreviation. In any case, we need to
7538 * know the expected return type of the
7539 * field expression.
7540 */
7541 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7542 if (offset_r && (offset_r < (size - 1)))
7543 result[offset_r++] = ',';
7544 if (offset_e && (offset_e < (size - 1)))
7545 expr[offset_e++] = ',';
7546 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7547 // col_{add,append,set}_* calls ws_label_strcpy
7548 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7549
7550 g_free(str);
7551 }
7552 g_ptr_array_unref(fvals);
7553 } else if (passed) {
7554 // XXX - Occurrence doesn't make sense for a test
7555 // output, it should be applied to the operands.
7556 if (offset_r && (offset_r < (size - 1)))
7557 result[offset_r++] = ',';
7558 if (offset_e && (offset_e < (size - 1)))
7559 expr[offset_e++] = ',';
7560 /* Prevent multiple check marks */
7561 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7562 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7563 } else {
7564 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7565 }
7566 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7567 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7568 } else {
7569 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7570 }
7571 }
7572 continue;
7573 }
7574 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", 7574
, __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", 7574,
"(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", 7574,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7575
7576 /* do we need to rewind ? */
7577 if (!hfinfo)
7578 return "";
7579
7580 if (occurrence < 0) {
7581 /* Search other direction */
7582 while (hfinfo->same_name_prev_id != -1) {
7583 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", 7583
, __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", 7583, "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", 7583,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7584 }
7585 }
7586
7587 prev_len = 0; /* Reset handled occurrences */
7588
7589 while (hfinfo) {
7590 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7591
7592 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7593 if (occurrence < 0) {
7594 hfinfo = hfinfo->same_name_next;
7595 } else {
7596 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7597 }
7598 continue;
7599 }
7600
7601 /* Are there enough occurrences of the field? */
7602 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7603 if (occurrence < 0) {
7604 hfinfo = hfinfo->same_name_next;
7605 } else {
7606 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7607 }
7608 prev_len += len;
7609 continue;
7610 }
7611
7612 /* Calculate single index or set outer boundaries */
7613 if (occurrence < 0) {
7614 i = occurrence + len + prev_len;
7615 last = i;
7616 } else if (occurrence > 0) {
7617 i = occurrence - 1 - prev_len;
7618 last = i;
7619 } else {
7620 i = 0;
7621 last = len - 1;
7622 }
7623
7624 prev_len += len; /* Count handled occurrences */
7625
7626 while (i <= last) {
7627 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7628
7629 if (offset_r && (offset_r < (size - 1)))
7630 result[offset_r++] = ',';
7631
7632 if (display_details) {
7633 char representation[ITEM_LABEL_LENGTH240];
7634 size_t offset = 0;
7635
7636 if (finfo->rep && finfo->rep->value_len) {
7637 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7638 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7639 } else {
7640 proto_item_fill_label(finfo, representation, &offset);
7641 }
7642 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7643 } else {
7644 switch (hfinfo->type) {
7645
7646 case FT_NONE:
7647 case FT_PROTOCOL:
7648 /* Prevent multiple check marks */
7649 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7650 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7651 } else {
7652 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7653 }
7654 break;
7655
7656 default:
7657 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7658 break;
7659 }
7660 }
7661
7662 if (offset_e && (offset_e < (size - 1)))
7663 expr[offset_e++] = ',';
7664
7665 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
))
)) {
7666 const char *hf_str_val;
7667 /* Integer types with BASE_NONE never get the numeric value. */
7668 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7669 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7670 } 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
)
) {
7671 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7672 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7673 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7674 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7675 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7676 }
7677 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7678 offset_e = (int)strlen(expr);
7679 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7680 /* Prevent multiple check marks */
7681 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7682 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7683 } else {
7684 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7685 }
7686 } else {
7687 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7688 // col_{add,append,set}_* calls ws_label_strcpy
7689 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7690 wmem_free(NULL((void*)0), str);
7691 }
7692 i++;
7693 }
7694
7695 /* XXX: Why is only the first abbreviation returned for a multifield
7696 * custom column? */
7697 if (!abbrev) {
7698 /* Store abbrev for return value */
7699 abbrev = hfinfo->abbrev;
7700 }
7701
7702 if (occurrence == 0) {
7703 /* Fetch next hfinfo with same name (abbrev) */
7704 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7705 } else {
7706 hfinfo = NULL((void*)0);
7707 }
7708 }
7709 }
7710
7711 if (offset_r >= (size - 1)) {
7712 mark_truncated(result, 0, size, NULL((void*)0));
7713 }
7714 if (offset_e >= (size - 1)) {
7715 mark_truncated(expr, 0, size, NULL((void*)0));
7716 }
7717 return abbrev ? abbrev : "";
7718}
7719
7720char *
7721proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7722{
7723 int len, prev_len, last, i;
7724 GPtrArray *finfos;
7725 field_info *finfo = NULL((void*)0);
7726 header_field_info* hfinfo;
7727
7728 char *filter = NULL((void*)0);
7729 GPtrArray *filter_array;
7730
7731 col_custom_t *col_custom;
7732 int field_id;
7733
7734 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7734, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7735 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7736 for (GSList *iter = field_ids; iter; iter = iter->next) {
7737 col_custom = (col_custom_t*)iter->data;
7738 field_id = col_custom->field_id;
7739 if (field_id == 0) {
7740 GPtrArray *fvals = NULL((void*)0);
7741 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7742 if (fvals != NULL((void*)0)) {
7743 // XXX - Handling occurrences is unusual when more
7744 // than one field is involved, e.g. there's four
7745 // results for tcp.port + tcp.port. We really
7746 // want to apply it to the operands, not the output.
7747 /* Calculate single index or set outer boundaries */
7748 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7749 if (occurrence < 0) {
7750 i = occurrence + len;
7751 last = i;
7752 } else if (occurrence > 0) {
7753 i = occurrence - 1;
7754 last = i;
7755 } else {
7756 i = 0;
7757 last = len - 1;
7758 }
7759 if (i < 0 || i >= len) {
7760 g_ptr_array_unref(fvals);
7761 continue;
7762 }
7763 for (; i <= last; i++) {
7764 /* XXX - Should multiple values for one
7765 * field use set membership to reduce
7766 * verbosity, here and below? */
7767 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7768 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7769 wmem_free(NULL((void*)0), str);
7770 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7771 g_ptr_array_add(filter_array, filter);
7772 }
7773 }
7774 g_ptr_array_unref(fvals);
7775 } else if (passed) {
7776 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7777 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7778 g_ptr_array_add(filter_array, filter);
7779 }
7780 } else {
7781 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7782 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7783 g_ptr_array_add(filter_array, filter);
7784 }
7785 }
7786 continue;
7787 }
7788
7789 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", 7789
, __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", 7789,
"(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", 7789,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7790
7791 /* do we need to rewind ? */
7792 if (!hfinfo)
7793 return NULL((void*)0);
7794
7795 if (occurrence < 0) {
7796 /* Search other direction */
7797 while (hfinfo->same_name_prev_id != -1) {
7798 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", 7798
, __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", 7798, "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", 7798,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7799 }
7800 }
7801
7802 prev_len = 0; /* Reset handled occurrences */
7803
7804 while (hfinfo) {
7805 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7806
7807 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7808 if (occurrence < 0) {
7809 hfinfo = hfinfo->same_name_next;
7810 } else {
7811 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7812 }
7813 continue;
7814 }
7815
7816 /* Are there enough occurrences of the field? */
7817 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7818 if (occurrence < 0) {
7819 hfinfo = hfinfo->same_name_next;
7820 } else {
7821 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7822 }
7823 prev_len += len;
7824 continue;
7825 }
7826
7827 /* Calculate single index or set outer boundaries */
7828 if (occurrence < 0) {
7829 i = occurrence + len + prev_len;
7830 last = i;
7831 } else if (occurrence > 0) {
7832 i = occurrence - 1 - prev_len;
7833 last = i;
7834 } else {
7835 i = 0;
7836 last = len - 1;
7837 }
7838
7839 prev_len += len; /* Count handled occurrences */
7840
7841 while (i <= last) {
7842 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7843
7844 filter = proto_construct_match_selected_string(finfo, edt);
7845 if (filter) {
7846 /* Only add the same expression once (especially for FT_PROTOCOL).
7847 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7848 */
7849 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7850 g_ptr_array_add(filter_array, filter);
7851 }
7852 }
7853 i++;
7854 }
7855
7856 if (occurrence == 0) {
7857 /* Fetch next hfinfo with same name (abbrev) */
7858 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7859 } else {
7860 hfinfo = NULL((void*)0);
7861 }
7862 }
7863 }
7864
7865 g_ptr_array_add(filter_array, NULL((void*)0));
7866
7867 /* XXX: Should this be || or && ? */
7868 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7869
7870 g_ptr_array_free(filter_array, true1);
7871
7872 return output;
7873}
7874
7875/* Set text of proto_item after having already been created. */
7876void
7877proto_item_set_text(proto_item *pi, const char *format, ...)
7878{
7879 field_info *fi = NULL((void*)0);
7880 va_list ap;
7881
7882 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7883
7884 fi = PITEM_FINFO(pi)((pi)->finfo);
7885 if (fi == NULL((void*)0))
7886 return;
7887
7888 if (fi->rep) {
7889 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7890 fi->rep = NULL((void*)0);
7891 }
7892
7893 va_start(ap, format)__builtin_va_start(ap, format);
7894 proto_tree_set_representation(pi, format, ap);
7895 va_end(ap)__builtin_va_end(ap);
7896}
7897
7898/* Append to text of proto_item after having already been created. */
7899void
7900proto_item_append_text(proto_item *pi, const char *format, ...)
7901{
7902 field_info *fi = NULL((void*)0);
7903 size_t curlen;
7904 char *str;
7905 va_list ap;
7906
7907 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7908
7909 fi = PITEM_FINFO(pi)((pi)->finfo);
7910 if (fi == NULL((void*)0)) {
7911 return;
7912 }
7913
7914 if (!proto_item_is_hidden(pi)) {
7915 /*
7916 * If we don't already have a representation,
7917 * generate the default representation.
7918 */
7919 if (fi->rep == NULL((void*)0)) {
7920 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;
;
7921 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7922 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7923 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7924 (strncmp(format, ": ", 2) == 0)) {
7925 fi->rep->value_pos += 2;
7926 }
7927 }
7928 if (fi->rep) {
7929 curlen = strlen(fi->rep->representation);
7930 /* curlen doesn't include the \0 byte.
7931 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7932 * the representation has already been truncated (of an up
7933 * to 4 byte UTF-8 character) or is just at the maximum length
7934 * unless we search for " [truncated]" (which may not be
7935 * at the start.)
7936 * It's safer to do nothing.
7937 */
7938 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7939 va_start(ap, format)__builtin_va_start(ap, format);
7940 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7941 va_end(ap)__builtin_va_end(ap);
7942 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"
, 7942, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7943 /* Keep fi->rep->value_pos */
7944 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7945 if (curlen >= ITEM_LABEL_LENGTH240) {
7946 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7947 size_t name_pos = label_find_name_pos(fi->rep);
7948 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7949 }
7950 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7951 }
7952 }
7953 }
7954}
7955
7956/* Prepend to text of proto_item after having already been created. */
7957void
7958proto_item_prepend_text(proto_item *pi, const char *format, ...)
7959{
7960 field_info *fi = NULL((void*)0);
7961 size_t pos;
7962 char representation[ITEM_LABEL_LENGTH240];
7963 char *str;
7964 va_list ap;
7965
7966 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7967
7968 fi = PITEM_FINFO(pi)((pi)->finfo);
7969 if (fi == NULL((void*)0)) {
7970 return;
7971 }
7972
7973 if (!proto_item_is_hidden(pi)) {
7974 /*
7975 * If we don't already have a representation,
7976 * generate the default representation.
7977 */
7978 if (fi->rep == NULL((void*)0)) {
7979 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;
;
7980 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7981 } else
7982 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7983
7984 va_start(ap, format)__builtin_va_start(ap, format);
7985 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7986 va_end(ap)__builtin_va_end(ap);
7987 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"
, 7987, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7988 fi->rep->value_pos += strlen(str);
7989 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7990 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7991 /* XXX: As above, if the old representation is close to the label
7992 * length, it might already be marked as truncated. */
7993 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7994 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7995 size_t name_pos = label_find_name_pos(fi->rep);
7996 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7997 }
7998 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7999 }
8000}
8001
8002static void
8003finfo_set_len(field_info *fi, const int length)
8004{
8005 int length_remaining;
8006
8007 DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 8007,
"length >= 0", fi->hfinfo->abbrev))))
;
8008 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
8009 if (length > length_remaining)
8010 fi->length = length_remaining;
8011 else
8012 fi->length = length;
8013
8014 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8015 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8016 fvalue_set_protocol_length(fi->value, fi->length);
8017 }
8018
8019 /*
8020 * You cannot just make the "len" field of a GByteArray
8021 * larger, if there's no data to back that length;
8022 * you can only make it smaller.
8023 */
8024 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8025 GBytes *bytes = fvalue_get_bytes(fi->value);
8026 size_t size;
8027 const void *data = g_bytes_get_data(bytes, &size);
8028 if ((size_t)fi->length <= size) {
8029 fvalue_set_bytes_data(fi->value, data, fi->length);
8030 }
8031 g_bytes_unref(bytes);
8032 }
8033}
8034
8035void
8036proto_item_set_len(proto_item *pi, const int length)
8037{
8038 field_info *fi;
8039
8040 if (pi == NULL((void*)0))
8041 return;
8042
8043 fi = PITEM_FINFO(pi)((pi)->finfo);
8044 if (fi == NULL((void*)0))
8045 return;
8046
8047 finfo_set_len(fi, length);
8048}
8049
8050/*
8051 * Sets the length of the item based on its start and on the specified
8052 * offset, which is the offset past the end of the item; as the start
8053 * in the item is relative to the beginning of the data source tvbuff,
8054 * we need to pass in a tvbuff - the end offset is relative to the beginning
8055 * of that tvbuff.
8056 */
8057void
8058proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8059{
8060 field_info *fi;
8061 int length;
8062
8063 if (pi == NULL((void*)0))
8064 return;
8065
8066 fi = PITEM_FINFO(pi)((pi)->finfo);
8067 if (fi == NULL((void*)0))
8068 return;
8069
8070 end += tvb_raw_offset(tvb);
8071 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8071, "end >= fi->start"
))))
;
8072 length = end - fi->start;
8073
8074 finfo_set_len(fi, length);
8075}
8076
8077int
8078proto_item_get_len(const proto_item *pi)
8079{
8080 field_info *fi;
8081
8082 if (!pi)
8083 return -1;
8084 fi = PITEM_FINFO(pi)((pi)->finfo);
8085 if (fi) {
8086 return fi->length;
8087 }
8088 return -1;
8089}
8090
8091void
8092proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8093 if (!ti) {
8094 return;
8095 }
8096 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)
;
8097 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)
;
8098}
8099
8100char *
8101proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8102{
8103 field_info *fi;
8104
8105 if (!pi)
8106 return wmem_strdup(scope, "");
8107 fi = PITEM_FINFO(pi)((pi)->finfo);
8108 if (!fi)
8109 return wmem_strdup(scope, "");
8110 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8110, "fi->hfinfo != ((void*)0)"
))))
;
8111 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8112}
8113
8114proto_tree *
8115proto_tree_create_root(packet_info *pinfo)
8116{
8117 proto_node *pnode;
8118
8119 /* Initialize the proto_node */
8120 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8121 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8122 pnode->parent = NULL((void*)0);
8123 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8124 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8125
8126 /* Make sure we can access pinfo everywhere */
8127 pnode->tree_data->pinfo = pinfo;
8128
8129 /* Don't initialize the tree_data_t. Wait until we know we need it */
8130 pnode->tree_data->interesting_hfids = NULL((void*)0);
8131
8132 /* Set the default to false so it's easier to
8133 * find errors; if we expect to see the protocol tree
8134 * but for some reason the default 'visible' is not
8135 * changed, then we'll find out very quickly. */
8136 pnode->tree_data->visible = false0;
8137
8138 /* Make sure that we fake protocols (if possible) */
8139 pnode->tree_data->fake_protocols = true1;
8140
8141 /* Keep track of the number of children */
8142 pnode->tree_data->count = 0;
8143
8144 /* Initialize our loop checks */
8145 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8146 pnode->tree_data->max_start = 0;
8147 pnode->tree_data->start_idle_count = 0;
8148
8149 return (proto_tree *)pnode;
8150}
8151
8152
8153/* "prime" a proto_tree with a single hfid that a dfilter
8154 * is interested in. */
8155void
8156proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8157{
8158 header_field_info *hfinfo;
8159
8160 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", 8160, __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", 8160, "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", 8160, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8161 /* this field is referenced by a filter so increase the refcount.
8162 also increase the refcount for the parent, i.e the protocol.
8163 Don't increase the refcount if we're already printing the
8164 type, as that is a superset of direct reference.
8165 */
8166 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8167 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8168 }
8169 /* only increase the refcount if there is a parent.
8170 if this is a protocol and not a field then parent will be -1
8171 and there is no parent to add any refcounting for.
8172 */
8173 if (hfinfo->parent != -1) {
8174 header_field_info *parent_hfinfo;
8175 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", 8175
, __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", 8175,
"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", 8175,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8176
8177 /* Mark parent as indirectly referenced unless it is already directly
8178 * referenced, i.e. the user has specified the parent in a filter.
8179 */
8180 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8181 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8182 }
8183}
8184
8185/* "prime" a proto_tree with a single hfid that a dfilter
8186 * is interested in. */
8187void
8188proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8189{
8190 header_field_info *hfinfo;
8191
8192 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", 8192, __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", 8192, "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", 8192, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8193 /* this field is referenced by an (output) filter so increase the refcount.
8194 also increase the refcount for the parent, i.e the protocol.
8195 */
8196 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8197 /* only increase the refcount if there is a parent.
8198 if this is a protocol and not a field then parent will be -1
8199 and there is no parent to add any refcounting for.
8200 */
8201 if (hfinfo->parent != -1) {
8202 header_field_info *parent_hfinfo;
8203 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", 8203
, __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", 8203,
"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", 8203,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8204
8205 /* Mark parent as indirectly referenced unless it is already directly
8206 * referenced, i.e. the user has specified the parent in a filter.
8207 */
8208 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8209 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8210 }
8211}
8212
8213proto_tree *
8214proto_item_add_subtree(proto_item *pi, const int idx) {
8215 field_info *fi;
8216
8217 if (!pi)
8218 return NULL((void*)0);
8219
8220 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", 8220, "idx >= 0 && idx < num_tree_types"
))))
;
8221
8222 fi = PITEM_FINFO(pi)((pi)->finfo);
8223 if (!fi)
8224 return (proto_tree *)pi;
8225
8226 fi->tree_type = idx;
8227
8228 return (proto_tree *)pi;
8229}
8230
8231proto_tree *
8232proto_item_get_subtree(proto_item *pi) {
8233 field_info *fi;
8234
8235 if (!pi)
8236 return NULL((void*)0);
8237 fi = PITEM_FINFO(pi)((pi)->finfo);
8238 if ( (fi) && (fi->tree_type == -1) )
8239 return NULL((void*)0);
8240 return (proto_tree *)pi;
8241}
8242
8243proto_item *
8244proto_item_get_parent(const proto_item *ti) {
8245 if (!ti)
8246 return NULL((void*)0);
8247 return ti->parent;
8248}
8249
8250proto_item *
8251proto_item_get_parent_nth(proto_item *ti, int gen) {
8252 if (!ti)
8253 return NULL((void*)0);
8254 while (gen--) {
8255 ti = ti->parent;
8256 if (!ti)
8257 return NULL((void*)0);
8258 }
8259 return ti;
8260}
8261
8262
8263proto_item *
8264proto_tree_get_parent(proto_tree *tree) {
8265 if (!tree)
8266 return NULL((void*)0);
8267 return (proto_item *)tree;
8268}
8269
8270proto_tree *
8271proto_tree_get_parent_tree(proto_tree *tree) {
8272 if (!tree)
8273 return NULL((void*)0);
8274
8275 /* we're the root tree, there's no parent
8276 return ourselves so the caller has at least a tree to attach to */
8277 if (!tree->parent)
8278 return tree;
8279
8280 return (proto_tree *)tree->parent;
8281}
8282
8283proto_tree *
8284proto_tree_get_root(proto_tree *tree) {
8285 if (!tree)
8286 return NULL((void*)0);
8287 while (tree->parent) {
8288 tree = tree->parent;
8289 }
8290 return tree;
8291}
8292
8293void
8294proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8295 proto_item *item_to_move)
8296{
8297 /* This function doesn't generate any values. It only reorganizes the protocol tree
8298 * so we can bail out immediately if it isn't visible. */
8299 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8300 return;
8301
8302 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", 8302, "item_to_move->parent == tree"
))))
;
8303 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", 8303, "fixed_item->parent == tree"
))))
;
8304
8305 /*** cut item_to_move out ***/
8306
8307 /* is item_to_move the first? */
8308 if (tree->first_child == item_to_move) {
8309 /* simply change first child to next */
8310 tree->first_child = item_to_move->next;
8311
8312 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", 8312, "tree->last_child != item_to_move"
))))
;
8313 } else {
8314 proto_item *curr_item;
8315 /* find previous and change it's next */
8316 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8317 if (curr_item->next == item_to_move) {
8318 break;
8319 }
8320 }
8321
8322 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8322, "curr_item"
))))
;
8323
8324 curr_item->next = item_to_move->next;
8325
8326 /* fix last_child if required */
8327 if (tree->last_child == item_to_move) {
8328 tree->last_child = curr_item;
8329 }
8330 }
8331
8332 /*** insert to_move after fixed ***/
8333 item_to_move->next = fixed_item->next;
8334 fixed_item->next = item_to_move;
8335 if (tree->last_child == fixed_item) {
8336 tree->last_child = item_to_move;
8337 }
8338}
8339
8340void
8341proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8342 const int length)
8343{
8344 field_info *fi;
8345
8346 if (tree == NULL((void*)0))
8347 return;
8348
8349 fi = PTREE_FINFO(tree)((tree)->finfo);
8350 if (fi == NULL((void*)0))
8351 return;
8352
8353 start += tvb_raw_offset(tvb);
8354 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8354, "start >= 0"
))))
;
8355 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8355, "length >= 0"
))))
;
8356
8357 fi->appendix_start = start;
8358 fi->appendix_length = length;
8359}
8360
8361static void
8362check_protocol_filter_name_or_fail(const char *filter_name)
8363{
8364 /* Require at least two characters. */
8365 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8366 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)
;
8367 }
8368
8369 if (proto_check_field_name(filter_name) != '\0') {
8370 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)
8371 " 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)
8372 " 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)
;
8373 }
8374
8375 /* Check that it doesn't match some very common numeric forms. */
8376 if (filter_name[0] == '0' &&
8377 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8378 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8379 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])
8380 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])
;
8381 }
8382
8383 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8384
8385 /* Check that it contains at least one letter. */
8386 bool_Bool have_letter = false0;
8387 for (const char *s = filter_name; *s != '\0'; s++) {
8388 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8389 have_letter = true1;
8390 break;
8391 }
8392 }
8393 if (!have_letter) {
8394 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)
8395 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8396 }
8397
8398 /* Check for reserved keywords. */
8399 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8400 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)
8401 " 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)
;
8402 }
8403}
8404
8405int
8406proto_register_protocol(const char *name, const char *short_name,
8407 const char *filter_name)
8408{
8409 protocol_t *protocol;
8410 header_field_info *hfinfo;
8411
8412 check_protocol_filter_name_or_fail(filter_name);
8413
8414 /*
8415 * Add this protocol to the list of known protocols;
8416 * the list is sorted by protocol short name.
8417 */
8418 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8419 protocol->name = name;
8420 protocol->short_name = short_name;
8421 protocol->filter_name = filter_name;
8422 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8423 protocol->is_enabled = true1; /* protocol is enabled by default */
8424 protocol->enabled_by_default = true1; /* see previous comment */
8425 protocol->can_toggle = true1;
8426 protocol->parent_proto_id = -1;
8427 protocol->heur_list = NULL((void*)0);
8428
8429 /* List will be sorted later by name, when all protocols completed registering */
8430 protocols = g_list_prepend(protocols, protocol);
8431 /*
8432 * Make sure there's not already a protocol with any of those
8433 * names. Crash if there is, as that's an error in the code
8434 * or an inappropriate plugin.
8435 * This situation has to be fixed to not register more than one
8436 * protocol with the same name.
8437 */
8438 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8439 /* ws_error will terminate the program */
8440 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)
8441 " 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)
;
8442 }
8443 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8444 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)
8445 " 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)
;
8446 }
8447 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8448 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)
8449 " 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)
;
8450 }
8451
8452 /* Here we allocate a new header_field_info struct */
8453 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8454 hfinfo->name = name;
8455 hfinfo->abbrev = filter_name;
8456 hfinfo->type = FT_PROTOCOL;
8457 hfinfo->display = BASE_NONE;
8458 hfinfo->strings = protocol;
8459 hfinfo->bitmask = 0;
8460 hfinfo->ref_type = HF_REF_TYPE_NONE;
8461 hfinfo->blurb = NULL((void*)0);
8462 hfinfo->parent = -1; /* This field differentiates protos and fields */
8463
8464 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8465 return protocol->proto_id;
8466}
8467
8468int
8469proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8470{
8471 protocol_t *protocol;
8472 header_field_info *hfinfo;
8473
8474 /*
8475 * Helper protocols don't need the strict rules as a "regular" protocol
8476 * Just register it in a list and make a hf_ field from it
8477 */
8478 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8479 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)
;
8480 }
8481
8482 if (parent_proto <= 0) {
8483 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)
8484 " 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)
;
8485 }
8486
8487 check_protocol_filter_name_or_fail(filter_name);
8488
8489 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8490 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8491 protocol->name = name;
8492 protocol->short_name = short_name;
8493 protocol->filter_name = filter_name;
8494 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8495
8496 /* Enabling and toggling is really determined by parent protocol,
8497 but provide default values here */
8498 protocol->is_enabled = true1;
8499 protocol->enabled_by_default = true1;
8500 protocol->can_toggle = true1;
8501
8502 protocol->parent_proto_id = parent_proto;
8503 protocol->heur_list = NULL((void*)0);
8504
8505 /* List will be sorted later by name, when all protocols completed registering */
8506 protocols = g_list_prepend(protocols, protocol);
8507
8508 /* Here we allocate a new header_field_info struct */
8509 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8510 hfinfo->name = name;
8511 hfinfo->abbrev = filter_name;
8512 hfinfo->type = field_type;
8513 hfinfo->display = BASE_NONE;
8514 if (field_type == FT_BYTES) {
8515 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8516 }
8517 hfinfo->strings = protocol;
8518 hfinfo->bitmask = 0;
8519 hfinfo->ref_type = HF_REF_TYPE_NONE;
8520 hfinfo->blurb = NULL((void*)0);
8521 hfinfo->parent = -1; /* This field differentiates protos and fields */
8522
8523 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8524 return protocol->proto_id;
8525}
8526
8527bool_Bool
8528proto_deregister_protocol(const char *short_name)
8529{
8530 protocol_t *protocol;
8531 header_field_info *hfinfo;
8532 int proto_id;
8533 unsigned i;
8534
8535 proto_id = proto_get_id_by_short_name(short_name);
8536 protocol = find_protocol_by_id(proto_id);
8537 if (protocol == NULL((void*)0))
8538 return false0;
8539
8540 g_hash_table_remove(proto_names, protocol->name);
8541 g_hash_table_remove(proto_short_names, (void *)short_name);
8542 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8543
8544 if (protocol->fields) {
8545 for (i = 0; i < protocol->fields->len; i++) {
8546 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8547 hfinfo_remove_from_gpa_name_map(hfinfo);
8548 expert_deregister_expertinfo(hfinfo->abbrev);
8549 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8550 }
8551 g_ptr_array_free(protocol->fields, true1);
8552 protocol->fields = NULL((void*)0);
8553 }
8554
8555 g_list_free(protocol->heur_list);
8556
8557 /* Remove this protocol from the list of known protocols */
8558 protocols = g_list_remove(protocols, protocol);
8559
8560 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8561 wmem_map_remove(gpa_name_map, protocol->filter_name);
8562
8563 g_free(last_field_name);
8564 last_field_name = NULL((void*)0);
8565
8566 return true1;
8567}
8568
8569void
8570proto_register_alias(const int proto_id, const char *alias_name)
8571{
8572 protocol_t *protocol;
8573
8574 protocol = find_protocol_by_id(proto_id);
8575 if (alias_name && protocol) {
8576 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8577 }
8578}
8579
8580/*
8581 * Routines to use to iterate over the protocols.
8582 * The argument passed to the iterator routines is an opaque cookie to
8583 * their callers; it's the GList pointer for the current element in
8584 * the list.
8585 * The ID of the protocol is returned, or -1 if there is no protocol.
8586 */
8587int
8588proto_get_first_protocol(void **cookie)
8589{
8590 protocol_t *protocol;
8591
8592 if (protocols == NULL((void*)0))
8593 return -1;
8594 *cookie = protocols;
8595 protocol = (protocol_t *)protocols->data;
8596 return protocol->proto_id;
8597}
8598
8599int
8600proto_get_data_protocol(void *cookie)
8601{
8602 GList *list_item = (GList *)cookie;
8603
8604 protocol_t *protocol = (protocol_t *)list_item->data;
8605 return protocol->proto_id;
8606}
8607
8608int
8609proto_get_next_protocol(void **cookie)
8610{
8611 GList *list_item = (GList *)*cookie;
8612 protocol_t *protocol;
8613
8614 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8615 if (list_item == NULL((void*)0))
8616 return -1;
8617 *cookie = list_item;
8618 protocol = (protocol_t *)list_item->data;
8619 return protocol->proto_id;
8620}
8621
8622header_field_info *
8623proto_get_first_protocol_field(const int proto_id, void **cookie)
8624{
8625 protocol_t *protocol = find_protocol_by_id(proto_id);
8626
8627 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8628 return NULL((void*)0);
8629
8630 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8631 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8632}
8633
8634header_field_info *
8635proto_get_next_protocol_field(const int proto_id, void **cookie)
8636{
8637 protocol_t *protocol = find_protocol_by_id(proto_id);
8638 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8639
8640 i++;
8641
8642 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8643 return NULL((void*)0);
8644
8645 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8646 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8647}
8648
8649protocol_t *
8650find_protocol_by_id(const int proto_id)
8651{
8652 header_field_info *hfinfo;
8653
8654 if (proto_id <= 0)
8655 return NULL((void*)0);
8656
8657 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", 8657, __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", 8657,
"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", 8657, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8658 if (hfinfo->type != FT_PROTOCOL) {
8659 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", 8659, "hfinfo->display & 0x00004000"
))))
;
8660 }
8661 return (protocol_t *)hfinfo->strings;
8662}
8663
8664int
8665proto_get_id(const protocol_t *protocol)
8666{
8667 return protocol->proto_id;
8668}
8669
8670bool_Bool
8671proto_name_already_registered(const char *name)
8672{
8673 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8673, "name", "No name present"))))
;
8674
8675 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8676 return true1;
8677 return false0;
8678}
8679
8680int
8681proto_get_id_by_filter_name(const char *filter_name)
8682{
8683 const protocol_t *protocol = NULL((void*)0);
8684
8685 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", 8685,
"filter_name", "No filter name present"))))
;
8686
8687 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8688
8689 if (protocol == NULL((void*)0))
8690 return -1;
8691 return protocol->proto_id;
8692}
8693
8694int
8695proto_get_id_by_short_name(const char *short_name)
8696{
8697 const protocol_t *protocol = NULL((void*)0);
8698
8699 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", 8699,
"short_name", "No short name present"))))
;
8700
8701 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8702
8703 if (protocol == NULL((void*)0))
8704 return -1;
8705 return protocol->proto_id;
8706}
8707
8708const char *
8709proto_get_protocol_name(const int proto_id)
8710{
8711 protocol_t *protocol;
8712
8713 protocol = find_protocol_by_id(proto_id);
8714
8715 if (protocol == NULL((void*)0))
8716 return NULL((void*)0);
8717 return protocol->name;
8718}
8719
8720const char *
8721proto_get_protocol_short_name(const protocol_t *protocol)
8722{
8723 if (protocol == NULL((void*)0))
8724 return "(none)";
8725 return protocol->short_name;
8726}
8727
8728const char *
8729proto_get_protocol_long_name(const protocol_t *protocol)
8730{
8731 if (protocol == NULL((void*)0))
8732 return "(none)";
8733 return protocol->name;
8734}
8735
8736const char *
8737proto_get_protocol_filter_name(const int proto_id)
8738{
8739 protocol_t *protocol;
8740
8741 protocol = find_protocol_by_id(proto_id);
8742 if (protocol == NULL((void*)0))
8743 return "(none)";
8744 return protocol->filter_name;
8745}
8746
8747void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8748{
8749 heur_dtbl_entry_t* heuristic_dissector;
8750
8751 if (protocol == NULL((void*)0))
8752 return;
8753
8754 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8755 if (heuristic_dissector != NULL((void*)0))
8756 {
8757 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8758 }
8759}
8760
8761void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8762{
8763 if (protocol == NULL((void*)0))
8764 return;
8765
8766 g_list_foreach(protocol->heur_list, func, user_data);
8767}
8768
8769void
8770proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8771 bool_Bool *is_tcp, bool_Bool *is_udp,
8772 bool_Bool *is_sctp, bool_Bool *is_tls,
8773 bool_Bool *is_rtp,
8774 bool_Bool *is_lte_rlc)
8775{
8776 wmem_list_frame_t *protos = wmem_list_head(layers);
8777 int proto_id;
8778 const char *proto_name;
8779
8780 /* Walk the list of a available protocols in the packet and
8781 attempt to find "major" ones. */
8782 /* It might make more sense to assemble and return a bitfield. */
8783 while (protos != NULL((void*)0))
8784 {
8785 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8786 proto_name = proto_get_protocol_filter_name(proto_id);
8787
8788 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8789 (!strcmp(proto_name, "ipv6")))) {
8790 *is_ip = true1;
8791 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8792 *is_tcp = true1;
8793 } else if (is_udp && !strcmp(proto_name, "udp")) {
8794 *is_udp = true1;
8795 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8796 *is_sctp = true1;
8797 } else if (is_tls && !strcmp(proto_name, "tls")) {
8798 *is_tls = true1;
8799 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8800 *is_rtp = true1;
8801 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8802 *is_lte_rlc = true1;
8803 }
8804
8805 protos = wmem_list_frame_next(protos);
8806 }
8807}
8808
8809bool_Bool
8810proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8811{
8812 wmem_list_frame_t *protos = wmem_list_head(layers);
8813 int proto_id;
8814 const char *name;
8815
8816 /* Walk the list of a available protocols in the packet and
8817 attempt to find the specified protocol. */
8818 while (protos != NULL((void*)0))
8819 {
8820 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8821 name = proto_get_protocol_filter_name(proto_id);
8822
8823 if (!strcmp(name, proto_name))
8824 {
8825 return true1;
8826 }
8827
8828 protos = wmem_list_frame_next(protos);
8829 }
8830
8831 return false0;
8832}
8833
8834char *
8835proto_list_layers(const packet_info *pinfo)
8836{
8837 wmem_strbuf_t *buf;
8838 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8839
8840 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8841
8842 /* Walk the list of layers in the packet and
8843 return a string of all entries. */
8844 while (layers != NULL((void*)0))
8845 {
8846 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8847
8848 layers = wmem_list_frame_next(layers);
8849 if (layers != NULL((void*)0)) {
8850 wmem_strbuf_append_c(buf, ':');
8851 }
8852 }
8853
8854 return wmem_strbuf_finalize(buf);
8855}
8856
8857uint8_t
8858proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8859{
8860 int *proto_layer_num_ptr;
8861
8862 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8863 if (proto_layer_num_ptr == NULL((void*)0)) {
8864 return 0;
8865 }
8866
8867 return (uint8_t)*proto_layer_num_ptr;
8868}
8869
8870bool_Bool
8871proto_is_pino(const protocol_t *protocol)
8872{
8873 return (protocol->parent_proto_id != -1);
8874}
8875
8876bool_Bool
8877// NOLINTNEXTLINE(misc-no-recursion)
8878proto_is_protocol_enabled(const protocol_t *protocol)
8879{
8880 if (protocol == NULL((void*)0))
8881 return false0;
8882
8883 //parent protocol determines enable/disable for helper dissectors
8884 if (proto_is_pino(protocol))
8885 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8886
8887 return protocol->is_enabled;
8888}
8889
8890bool_Bool
8891// NOLINTNEXTLINE(misc-no-recursion)
8892proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8893{
8894 //parent protocol determines enable/disable for helper dissectors
8895 if (proto_is_pino(protocol))
8896 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8897
8898 return protocol->enabled_by_default;
8899}
8900
8901bool_Bool
8902// NOLINTNEXTLINE(misc-no-recursion)
8903proto_can_toggle_protocol(const int proto_id)
8904{
8905 protocol_t *protocol;
8906
8907 protocol = find_protocol_by_id(proto_id);
8908 //parent protocol determines toggling for helper dissectors
8909 if (proto_is_pino(protocol))
8910 return proto_can_toggle_protocol(protocol->parent_proto_id);
8911
8912 return protocol->can_toggle;
8913}
8914
8915void
8916proto_disable_by_default(const int proto_id)
8917{
8918 protocol_t *protocol;
8919
8920 protocol = find_protocol_by_id(proto_id);
8921 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8921, "protocol->can_toggle"
))))
;
8922 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", 8922, "proto_is_pino(protocol) == 0"
))))
;
8923 protocol->is_enabled = false0;
8924 protocol->enabled_by_default = false0;
8925}
8926
8927void
8928proto_set_decoding(const int proto_id, const bool_Bool enabled)
8929{
8930 protocol_t *protocol;
8931
8932 protocol = find_protocol_by_id(proto_id);
8933 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8933, "protocol->can_toggle"
))))
;
8934 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", 8934, "proto_is_pino(protocol) == 0"
))))
;
8935 protocol->is_enabled = enabled;
8936}
8937
8938void
8939proto_disable_all(void)
8940{
8941 /* This doesn't explicitly disable heuristic protocols,
8942 * but the heuristic doesn't get called if the parent
8943 * protocol isn't enabled.
8944 */
8945 protocol_t *protocol;
8946 GList *list_item = protocols;
8947
8948 if (protocols == NULL((void*)0))
8949 return;
8950
8951 while (list_item) {
8952 protocol = (protocol_t *)list_item->data;
8953 if (protocol->can_toggle) {
8954 protocol->is_enabled = false0;
8955 }
8956 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8957 }
8958}
8959
8960static void
8961heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8962{
8963 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8964
8965 heur->enabled = heur->enabled_by_default;
8966}
8967
8968void
8969proto_reenable_all(void)
8970{
8971 protocol_t *protocol;
8972 GList *list_item = protocols;
8973
8974 if (protocols == NULL((void*)0))
8975 return;
8976
8977 while (list_item) {
8978 protocol = (protocol_t *)list_item->data;
8979 if (protocol->can_toggle)
8980 protocol->is_enabled = protocol->enabled_by_default;
8981 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8982 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8983 }
8984}
8985
8986void
8987proto_set_cant_toggle(const int proto_id)
8988{
8989 protocol_t *protocol;
8990
8991 protocol = find_protocol_by_id(proto_id);
8992 protocol->can_toggle = false0;
8993}
8994
8995static int
8996proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8997{
8998 g_ptr_array_add(proto->fields, hfi);
8999
9000 return proto_register_field_init(hfi, parent);
9001}
9002
9003/* for use with static arrays only, since we don't allocate our own copies
9004of the header_field_info struct contained within the hf_register_info struct */
9005void
9006proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9007{
9008 hf_register_info *ptr = hf;
9009 protocol_t *proto;
9010 int i;
9011
9012 proto = find_protocol_by_id(parent);
9013
9014 /* if (proto == NULL) - error or return? */
9015
9016 if (proto->fields == NULL((void*)0)) {
9017 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9018 * GLib introduced g_ptr_array_new_from_array, which might have
9019 * given a reason to actually use it. (#17774)
9020 */
9021 proto->fields = g_ptr_array_sized_new(num_records);
9022 }
9023
9024 for (i = 0; i < num_records; i++, ptr++) {
9025 /*
9026 * Make sure we haven't registered this yet.
9027 * Most fields have variables associated with them that
9028 * are initialized to 0; some are initialized to -1 (which
9029 * was the standard before 4.4).
9030 *
9031 * XXX - Since this is called almost 300000 times at startup,
9032 * it might be nice to compare to only 0 and require
9033 * dissectors to pass in zero for unregistered fields.
9034 */
9035 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9036 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9037 "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)
9038 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9039 return;
9040 }
9041
9042 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9043 }
9044}
9045
9046/* deregister already registered fields */
9047void
9048proto_deregister_field (const int parent, int hf_id)
9049{
9050 header_field_info *hfi;
9051 protocol_t *proto;
9052 unsigned i;
9053
9054 g_free(last_field_name);
9055 last_field_name = NULL((void*)0);
9056
9057 if (hf_id == -1 || hf_id == 0)
9058 return;
9059
9060 proto = find_protocol_by_id (parent);
9061 if (!proto || proto->fields == NULL((void*)0)) {
9062 return;
9063 }
9064
9065 for (i = 0; i < proto->fields->len; i++) {
9066 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9067 if (hfi->id == hf_id) {
9068 /* Found the hf_id in this protocol */
9069 wmem_map_remove(gpa_name_map, hfi->abbrev);
9070 g_ptr_array_remove_index_fast(proto->fields, i);
9071 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9072 return;
9073 }
9074 }
9075}
9076
9077/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9078void
9079proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9080{
9081 header_field_info *hfinfo;
9082 protocol_t *proto;
9083
9084 g_free(last_field_name);
9085 last_field_name = NULL((void*)0);
9086
9087 proto = find_protocol_by_id(parent);
9088 if (proto && proto->fields && proto->fields->len > 0) {
9089 unsigned i = proto->fields->len;
9090 do {
9091 i--;
9092
9093 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9094 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) )
) {
9095 hfinfo_remove_from_gpa_name_map(hfinfo);
9096 expert_deregister_expertinfo(hfinfo->abbrev);
9097 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9098 g_ptr_array_remove_index_fast(proto->fields, i);
9099 }
9100 } while (i > 0);
9101 }
9102}
9103
9104void
9105proto_add_deregistered_data (void *data)
9106{
9107 g_ptr_array_add(deregistered_data, data);
9108}
9109
9110void
9111proto_add_deregistered_slice (size_t block_size, void *mem_block)
9112{
9113 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
)))
;
9114
9115 slice_data->block_size = block_size;
9116 slice_data->mem_block = mem_block;
9117
9118 g_ptr_array_add(deregistered_slice, slice_data);
9119}
9120
9121void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9122{
9123 if (field_strings == NULL((void*)0)) {
9124 return;
9125 }
9126
9127 switch (field_type) {
9128 case FT_FRAMENUM:
9129 /* This is just an integer represented as a pointer */
9130 break;
9131 case FT_PROTOCOL: {
9132 protocol_t *protocol = (protocol_t *)field_strings;
9133 g_free((char *)protocol->short_name);
9134 break;
9135 }
9136 case FT_BOOLEAN: {
9137 true_false_string *tf = (true_false_string *)field_strings;
9138 g_free((char *)tf->true_string);
9139 g_free((char *)tf->false_string);
9140 break;
9141 }
9142 case FT_UINT40:
9143 case FT_INT40:
9144 case FT_UINT48:
9145 case FT_INT48:
9146 case FT_UINT56:
9147 case FT_INT56:
9148 case FT_UINT64:
9149 case FT_INT64: {
9150 if (field_display & BASE_UNIT_STRING0x00001000) {
9151 unit_name_string *unit = (unit_name_string *)field_strings;
9152 g_free((char *)unit->singular);
9153 g_free((char *)unit->plural);
9154 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9155 range_string *rs = (range_string *)field_strings;
9156 while (rs->strptr) {
9157 g_free((char *)rs->strptr);
9158 rs++;
9159 }
9160 } else if (field_display & BASE_EXT_STRING0x00000200) {
9161 val64_string_ext *vse = (val64_string_ext *)field_strings;
9162 val64_string *vs = (val64_string *)vse->_vs_p;
9163 while (vs->strptr) {
9164 g_free((char *)vs->strptr);
9165 vs++;
9166 }
9167 val64_string_ext_free(vse);
9168 field_strings = NULL((void*)0);
9169 } else if (field_display == BASE_CUSTOM) {
9170 /* this will be a pointer to a function, don't free that */
9171 field_strings = NULL((void*)0);
9172 } else {
9173 val64_string *vs64 = (val64_string *)field_strings;
9174 while (vs64->strptr) {
9175 g_free((char *)vs64->strptr);
9176 vs64++;
9177 }
9178 }
9179 break;
9180 }
9181 case FT_CHAR:
9182 case FT_UINT8:
9183 case FT_INT8:
9184 case FT_UINT16:
9185 case FT_INT16:
9186 case FT_UINT24:
9187 case FT_INT24:
9188 case FT_UINT32:
9189 case FT_INT32:
9190 case FT_FLOAT:
9191 case FT_DOUBLE: {
9192 if (field_display & BASE_UNIT_STRING0x00001000) {
9193 unit_name_string *unit = (unit_name_string *)field_strings;
9194 g_free((char *)unit->singular);
9195 g_free((char *)unit->plural);
9196 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9197 range_string *rs = (range_string *)field_strings;
9198 while (rs->strptr) {
9199 g_free((char *)rs->strptr);
9200 rs++;
9201 }
9202 } else if (field_display & BASE_EXT_STRING0x00000200) {
9203 value_string_ext *vse = (value_string_ext *)field_strings;
9204 value_string *vs = (value_string *)vse->_vs_p;
9205 while (vs->strptr) {
9206 g_free((char *)vs->strptr);
9207 vs++;
9208 }
9209 value_string_ext_free(vse);
9210 field_strings = NULL((void*)0);
9211 } else if (field_display == BASE_CUSTOM) {
9212 /* this will be a pointer to a function, don't free that */
9213 field_strings = NULL((void*)0);
9214 } else {
9215 value_string *vs = (value_string *)field_strings;
9216 while (vs->strptr) {
9217 g_free((char *)vs->strptr);
9218 vs++;
9219 }
9220 }
9221 break;
9222 default:
9223 break;
9224 }
9225 }
9226
9227 if (field_type != FT_FRAMENUM) {
9228 g_free((void *)field_strings);
9229 }
9230}
9231
9232static void
9233free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9234{
9235 header_field_info *hfi = (header_field_info *) data;
9236 int hf_id = hfi->id;
9237
9238 g_free((char *)hfi->name);
9239 g_free((char *)hfi->abbrev);
9240 g_free((char *)hfi->blurb);
9241
9242 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9243
9244 if (hfi->parent == -1)
9245 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)
;
9246
9247 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9248}
9249
9250static void
9251free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9252{
9253 g_free (data);
9254}
9255
9256static void
9257free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9258{
9259 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9260
9261 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9262 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)
;
9263}
9264
9265/* free deregistered fields and data */
9266void
9267proto_free_deregistered_fields (void)
9268{
9269 expert_free_deregistered_expertinfos();
9270
9271 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9272 g_ptr_array_free(deregistered_fields, true1);
9273 deregistered_fields = g_ptr_array_new();
9274
9275 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9276 g_ptr_array_free(deregistered_data, true1);
9277 deregistered_data = g_ptr_array_new();
9278
9279 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9280 g_ptr_array_free(deregistered_slice, true1);
9281 deregistered_slice = g_ptr_array_new();
9282}
9283
9284static const value_string hf_display[] = {
9285 { BASE_NONE, "BASE_NONE" },
9286 { BASE_DEC, "BASE_DEC" },
9287 { BASE_HEX, "BASE_HEX" },
9288 { BASE_OCT, "BASE_OCT" },
9289 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9290 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9291 { BASE_CUSTOM, "BASE_CUSTOM" },
9292 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9293 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9294 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9295 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9296 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9297 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9298 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9299 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9300 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9301 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9302 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9303 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9304 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9305 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9306 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9307 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9308 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9309 { BASE_PT_UDP, "BASE_PT_UDP" },
9310 { BASE_PT_TCP, "BASE_PT_TCP" },
9311 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9312 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9313 { BASE_OUI, "BASE_OUI" },
9314 { 0, NULL((void*)0) } };
9315
9316const char* proto_field_display_to_string(int field_display)
9317{
9318 return val_to_str_const(field_display, hf_display, "Unknown");
9319}
9320
9321static inline port_type
9322display_to_port_type(field_display_e e)
9323{
9324 switch (e) {
9325 case BASE_PT_UDP:
9326 return PT_UDP;
9327 case BASE_PT_TCP:
9328 return PT_TCP;
9329 case BASE_PT_DCCP:
9330 return PT_DCCP;
9331 case BASE_PT_SCTP:
9332 return PT_SCTP;
9333 default:
9334 break;
9335 }
9336 return PT_NONE;
9337}
9338
9339/* temporary function containing assert part for easier profiling */
9340static void
9341tmp_fld_check_assert(header_field_info *hfinfo)
9342{
9343 char* tmp_str;
9344
9345 /* The field must have a name (with length > 0) */
9346 if (!hfinfo->name || !hfinfo->name[0]) {
9347 if (hfinfo->abbrev)
9348 /* Try to identify the field */
9349 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)
9350 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9351 else
9352 /* Hum, no luck */
9353 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)"
)
;
9354 }
9355
9356 /* fields with an empty string for an abbreviation aren't filterable */
9357 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9358 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)
;
9359
9360 /* TODO: This check is a significant percentage of startup time (~10%),
9361 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9362 It might be nice to have a way to disable this check when, e.g.,
9363 running TShark many times with the same configuration. */
9364 /* Check that the filter name (abbreviation) is legal;
9365 * it must contain only alphanumerics, '-', "_", and ".". */
9366 unsigned char c;
9367 c = module_check_valid_name(hfinfo->abbrev, false0);
9368 if (c) {
9369 if (c == '.') {
9370 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)
;
9371 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9372 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)
;
9373 } else {
9374 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)
;
9375 }
9376 }
9377
9378 /* These types of fields are allowed to have value_strings,
9379 * true_false_strings or a protocol_t struct
9380 */
9381 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9382 switch (hfinfo->type) {
9383
9384 /*
9385 * These types are allowed to support display value_strings,
9386 * value64_strings, the extended versions of the previous
9387 * two, range strings, or unit strings.
9388 */
9389 case FT_CHAR:
9390 case FT_UINT8:
9391 case FT_UINT16:
9392 case FT_UINT24:
9393 case FT_UINT32:
9394 case FT_UINT40:
9395 case FT_UINT48:
9396 case FT_UINT56:
9397 case FT_UINT64:
9398 case FT_INT8:
9399 case FT_INT16:
9400 case FT_INT24:
9401 case FT_INT32:
9402 case FT_INT40:
9403 case FT_INT48:
9404 case FT_INT56:
9405 case FT_INT64:
9406 case FT_BOOLEAN:
9407 case FT_PROTOCOL:
9408 break;
9409
9410 /*
9411 * This is allowed to have a value of type
9412 * enum ft_framenum_type to indicate what relationship
9413 * the frame in question has to the frame in which
9414 * the field is put.
9415 */
9416 case FT_FRAMENUM:
9417 break;
9418
9419 /*
9420 * These types are allowed to support only unit strings.
9421 */
9422 case FT_FLOAT:
9423 case FT_DOUBLE:
9424 case FT_IEEE_11073_SFLOAT:
9425 case FT_IEEE_11073_FLOAT:
9426 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9427 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))
9428 " (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))
9429 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))
;
9430 }
9431 break;
9432
9433 /*
9434 * These types are allowed to support display
9435 * time_value_strings.
9436 */
9437 case FT_ABSOLUTE_TIME:
9438 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9439 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9440 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9441 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9442 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))
9443 " (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))
9444 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))
;
9445 }
9446 break;
9447
9448 /*
9449 * This type is only allowed to support a string if it's
9450 * a protocol (for pinos).
9451 */
9452 case FT_BYTES:
9453 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9454 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))
9455 " (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))
9456 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))
;
9457 }
9458 break;
9459
9460 default:
9461 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))
9462 " (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))
9463 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))
;
9464 }
9465 }
9466
9467 /* TODO: This check may slow down startup, and output quite a few warnings.
9468 It would be good to be able to enable this (and possibly other checks?)
9469 in non-release builds. */
9470#ifdef ENABLE_CHECK_FILTER
9471 /* Check for duplicate value_string values.
9472 There are lots that have the same value *and* string, so for now only
9473 report those that have same value but different string. */
9474 if ((hfinfo->strings != NULL((void*)0)) &&
9475 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9476 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9477 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9478 (
9479 (hfinfo->type == FT_CHAR) ||
9480 (hfinfo->type == FT_UINT8) ||
9481 (hfinfo->type == FT_UINT16) ||
9482 (hfinfo->type == FT_UINT24) ||
9483 (hfinfo->type == FT_UINT32) ||
9484 (hfinfo->type == FT_INT8) ||
9485 (hfinfo->type == FT_INT16) ||
9486 (hfinfo->type == FT_INT24) ||
9487 (hfinfo->type == FT_INT32) )) {
9488
9489 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9490 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9491 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9492 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9493 } else {
9494 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9495 CHECK_HF_VALUE(value_string, "u", start_values);
9496 }
9497 } else {
9498 const value_string *start_values = (const value_string*)hfinfo->strings;
9499 CHECK_HF_VALUE(value_string, "u", start_values);
9500 }
9501 }
9502
9503 if (hfinfo->type == FT_BOOLEAN) {
9504 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9505 if (tfs) {
9506 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9507 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9509
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9508 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9509
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9509 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9509
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9510 }
9511 }
9512 }
9513
9514 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9515 const range_string *rs = (const range_string*)(hfinfo->strings);
9516 if (rs) {
9517 const range_string *this_it = rs;
9518
9519 do {
9520 if (this_it->value_max < this_it->value_min) {
9521 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"
, 9525, __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)
9522 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9525, __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)
9523 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9525, __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)
9524 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9525, __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)
9525 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9525, __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)
;
9526 ++this_it;
9527 continue;
9528 }
9529
9530 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9531 /* Not OK if this one is completely hidden by an earlier one! */
9532 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9533 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"
, 9539, __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)
9534 "(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"
, 9539, __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)
9535 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
9536 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
9537 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
9538 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
9539 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9539, __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)
;
9540 }
9541 }
9542 ++this_it;
9543 } while (this_it->strptr);
9544 }
9545 }
9546#endif
9547
9548 switch (hfinfo->type) {
9549
9550 case FT_CHAR:
9551 /* Require the char type to have BASE_HEX, BASE_OCT,
9552 * BASE_CUSTOM, or BASE_NONE as its base.
9553 *
9554 * If the display value is BASE_NONE and there is a
9555 * strings conversion then the dissector writer is
9556 * telling us that the field's numerical value is
9557 * meaningless; we'll avoid showing the value to the
9558 * user.
9559 */
9560 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9561 case BASE_HEX:
9562 case BASE_OCT:
9563 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9564 break;
9565 case BASE_NONE:
9566 if (hfinfo->strings == NULL((void*)0))
9567 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
))
9568 " 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
))
9569 " 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
))
9570 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
))
9571 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
))
;
9572 break;
9573 default:
9574 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9575 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)
9576 " 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)
9577 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)
9578 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)
;
9579 //wmem_free(NULL, tmp_str);
9580 }
9581 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9582 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
))
9583 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
))
9584 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
))
;
9585 }
9586 break;
9587 case FT_INT8:
9588 case FT_INT16:
9589 case FT_INT24:
9590 case FT_INT32:
9591 case FT_INT40:
9592 case FT_INT48:
9593 case FT_INT56:
9594 case FT_INT64:
9595 /* Hexadecimal and octal are, in printf() and everywhere
9596 * else, unsigned so don't allow dissectors to register a
9597 * signed field to be displayed unsigned. (Else how would
9598 * we display negative values?)
9599 */
9600 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9601 case BASE_HEX:
9602 case BASE_OCT:
9603 case BASE_DEC_HEX:
9604 case BASE_HEX_DEC:
9605 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9606 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)
9607 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)
9608 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)
;
9609 //wmem_free(NULL, tmp_str);
9610 }
9611 /* FALL THROUGH */
9612 case FT_UINT8:
9613 case FT_UINT16:
9614 case FT_UINT24:
9615 case FT_UINT32:
9616 case FT_UINT40:
9617 case FT_UINT48:
9618 case FT_UINT56:
9619 case FT_UINT64:
9620 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
))
) {
9621 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9622 if (hfinfo->type != FT_UINT16) {
9623 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))
9624 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))
9625 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))
;
9626 }
9627 if (hfinfo->strings != NULL((void*)0)) {
9628 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)
9629 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)
9630 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)
;
9631 }
9632 if (hfinfo->bitmask != 0) {
9633 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)
9634 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)
9635 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)
;
9636 }
9637 wmem_free(NULL((void*)0), tmp_str);
9638 break;
9639 }
9640
9641 if (hfinfo->display == BASE_OUI) {
9642 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9643 if (hfinfo->type != FT_UINT24) {
9644 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))
9645 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))
9646 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))
;
9647 }
9648 if (hfinfo->strings != NULL((void*)0)) {
9649 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)
9650 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)
9651 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)
;
9652 }
9653 if (hfinfo->bitmask != 0) {
9654 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)
9655 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)
9656 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)
;
9657 }
9658 wmem_free(NULL((void*)0), tmp_str);
9659 break;
9660 }
9661
9662 /* Require integral types (other than frame number,
9663 * which is always displayed in decimal) to have a
9664 * number base.
9665 *
9666 * If the display value is BASE_NONE and there is a
9667 * strings conversion then the dissector writer is
9668 * telling us that the field's numerical value is
9669 * meaningless; we'll avoid showing the value to the
9670 * user.
9671 */
9672 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9673 case BASE_DEC:
9674 case BASE_HEX:
9675 case BASE_OCT:
9676 case BASE_DEC_HEX:
9677 case BASE_HEX_DEC:
9678 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9679 break;
9680 case BASE_NONE:
9681 if (hfinfo->strings == NULL((void*)0)) {
9682 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
))
9683 " 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
))
9684 " 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
))
9685 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
))
9686 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
))
;
9687 }
9688 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9689 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
))
9690 " 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
))
9691 " 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
))
9692 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
))
9693 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
))
;
9694 }
9695 break;
9696
9697 default:
9698 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9699 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)
9700 " 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)
9701 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)
9702 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)
;
9703 //wmem_free(NULL, tmp_str);
9704 }
9705 break;
9706 case FT_BYTES:
9707 case FT_UINT_BYTES:
9708 /* Require bytes to have a "display type" that could
9709 * add a character between displayed bytes.
9710 */
9711 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9712 case BASE_NONE:
9713 case SEP_DOT:
9714 case SEP_DASH:
9715 case SEP_COLON:
9716 case SEP_SPACE:
9717 break;
9718 default:
9719 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9720 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)
9721 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)
;
9722 //wmem_free(NULL, tmp_str);
9723 }
9724 if (hfinfo->bitmask != 0)
9725 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
))
9726 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
))
9727 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
))
;
9728 //allowed to support string if its a protocol (for pinos)
9729 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9730 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
))
9731 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
))
9732 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
))
;
9733 break;
9734
9735 case FT_PROTOCOL:
9736 case FT_FRAMENUM:
9737 if (hfinfo->display != BASE_NONE) {
9738 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9739 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)
9740 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)
9741 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)
;
9742 //wmem_free(NULL, tmp_str);
9743 }
9744 if (hfinfo->bitmask != 0)
9745 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
))
9746 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
))
9747 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
))
;
9748 break;
9749
9750 case FT_BOOLEAN:
9751 break;
9752
9753 case FT_ABSOLUTE_TIME:
9754 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9755 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9756 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)
9757 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)
;
9758 //wmem_free(NULL, tmp_str);
9759 }
9760 if (hfinfo->bitmask != 0)
9761 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
))
9762 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
))
9763 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
))
;
9764 break;
9765
9766 case FT_STRING:
9767 case FT_STRINGZ:
9768 case FT_UINT_STRING:
9769 case FT_STRINGZPAD:
9770 case FT_STRINGZTRUNC:
9771 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9772 case BASE_NONE:
9773 case BASE_STR_WSP:
9774 break;
9775
9776 default:
9777 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9778 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)
9779 " 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)
9780 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)
9781 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)
;
9782 //wmem_free(NULL, tmp_str);
9783 }
9784
9785 if (hfinfo->bitmask != 0)
9786 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
))
9787 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
))
9788 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
))
;
9789 if (hfinfo->strings != NULL((void*)0))
9790 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
))
9791 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
))
9792 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
))
;
9793 break;
9794
9795 case FT_IPv4:
9796 switch (hfinfo->display) {
9797 case BASE_NONE:
9798 case BASE_NETMASK:
9799 break;
9800
9801 default:
9802 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9803 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)
9804 " 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)
9805 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)
9806 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)
;
9807 //wmem_free(NULL, tmp_str);
9808 break;
9809 }
9810 break;
9811 case FT_FLOAT:
9812 case FT_DOUBLE:
9813 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9814 case BASE_NONE:
9815 case BASE_DEC:
9816 case BASE_HEX:
9817 case BASE_EXP:
9818 case BASE_CUSTOM:
9819 break;
9820 default:
9821 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9822 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)
9823 " 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)
9824 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)
9825 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)
;
9826 //wmem_free(NULL, tmp_str);
9827 }
9828 if (hfinfo->bitmask != 0)
9829 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
))
9830 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
))
9831 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
))
;
9832 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9833 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
))
9834 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
))
9835 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
))
;
9836 break;
9837 case FT_IEEE_11073_SFLOAT:
9838 case FT_IEEE_11073_FLOAT:
9839 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9840 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9841 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)
9842 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)
9843 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)
9844 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)
;
9845 //wmem_free(NULL, tmp_str);
9846 }
9847 if (hfinfo->bitmask != 0)
9848 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
))
9849 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
))
9850 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
))
;
9851 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9852 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
))
9853 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
))
9854 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
))
;
9855 break;
9856 default:
9857 if (hfinfo->display != BASE_NONE) {
9858 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9859 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)
9860 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)
9861 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)
9862 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)
;
9863 //wmem_free(NULL, tmp_str);
9864 }
9865 if (hfinfo->bitmask != 0)
9866 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
))
9867 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
))
9868 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
))
;
9869 if (hfinfo->strings != NULL((void*)0))
9870 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
))
9871 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
))
9872 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
))
;
9873 break;
9874 }
9875}
9876
9877static void
9878register_type_length_mismatch(void)
9879{
9880 static ei_register_info ei[] = {
9881 { &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)}}
}},
9882 { &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)}}
}},
9883 };
9884
9885 expert_module_t* expert_type_length_mismatch;
9886
9887 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9888
9889 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9890 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9891
9892 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9893 disabling them makes no sense. */
9894 proto_set_cant_toggle(proto_type_length_mismatch);
9895}
9896
9897static void
9898register_byte_array_string_decodinws_error(void)
9899{
9900 static ei_register_info ei[] = {
9901 { &ei_byte_array_string_decoding_failed_error,
9902 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9903 "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)}}
9904 }
9905 },
9906 };
9907
9908 expert_module_t* expert_byte_array_string_decoding_error;
9909
9910 proto_byte_array_string_decoding_error =
9911 proto_register_protocol("Byte Array-String Decoding Error",
9912 "Byte Array-string decoding error",
9913 "_ws.byte_array_string.decoding_error");
9914
9915 expert_byte_array_string_decoding_error =
9916 expert_register_protocol(proto_byte_array_string_decoding_error);
9917 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9918
9919 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9920 disabling them makes no sense. */
9921 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9922}
9923
9924static void
9925register_date_time_string_decodinws_error(void)
9926{
9927 static ei_register_info ei[] = {
9928 { &ei_date_time_string_decoding_failed_error,
9929 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9930 "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)}}
9931 }
9932 },
9933 };
9934
9935 expert_module_t* expert_date_time_string_decoding_error;
9936
9937 proto_date_time_string_decoding_error =
9938 proto_register_protocol("Date and Time-String Decoding Error",
9939 "Date and Time-string decoding error",
9940 "_ws.date_time_string.decoding_error");
9941
9942 expert_date_time_string_decoding_error =
9943 expert_register_protocol(proto_date_time_string_decoding_error);
9944 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9945
9946 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9947 disabling them makes no sense. */
9948 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9949}
9950
9951static void
9952register_string_errors(void)
9953{
9954 static ei_register_info ei[] = {
9955 { &ei_string_trailing_characters,
9956 { "_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)}}
}
9957 },
9958 };
9959
9960 expert_module_t* expert_string_errors;
9961
9962 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9963
9964 expert_string_errors = expert_register_protocol(proto_string_errors);
9965 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9966
9967 /* "String Errors" isn't really a protocol, it's an error indication;
9968 disabling them makes no sense. */
9969 proto_set_cant_toggle(proto_string_errors);
9970}
9971
9972static int
9973proto_register_field_init(header_field_info *hfinfo, const int parent)
9974{
9975
9976 tmp_fld_check_assert(hfinfo);
9977
9978 hfinfo->parent = parent;
9979 hfinfo->same_name_next = NULL((void*)0);
9980 hfinfo->same_name_prev_id = -1;
9981
9982 /* if we always add and never delete, then id == len - 1 is correct */
9983 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9984 if (!gpa_hfinfo.hfi) {
9985 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9986 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9987 /* The entry with index 0 is not used. */
9988 gpa_hfinfo.hfi[0] = NULL((void*)0);
9989 gpa_hfinfo.len = 1;
9990 } else {
9991 gpa_hfinfo.allocated_len += 1000;
9992 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9993 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9994 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9995 }
9996 }
9997 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9998 gpa_hfinfo.len++;
9999 hfinfo->id = gpa_hfinfo.len - 1;
10000
10001 /* if we have real names, enter this field in the name tree */
10002 /* Already checked in tmp_fld_check_assert */
10003 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10004 {
10005
10006 header_field_info *same_name_next_hfinfo;
10007
10008 /* We allow multiple hfinfo's to be registered under the same
10009 * abbreviation. This was done for X.25, as, depending
10010 * on whether it's modulo-8 or modulo-128 operation,
10011 * some bitfield fields may be in different bits of
10012 * a byte, and we want to be able to refer to that field
10013 * with one name regardless of whether the packets
10014 * are modulo-8 or modulo-128 packets. */
10015
10016 /* wmem_map_insert - if key is already present the previous
10017 * hfinfo with the same key/name is returned, otherwise NULL */
10018 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10019 if (same_name_hfinfo) {
10020 /* There's already a field with this name.
10021 * Put the current field *before* that field
10022 * in the list of fields with this name, Thus,
10023 * we end up with an effectively
10024 * doubly-linked-list of same-named hfinfo's,
10025 * with the head of the list (stored in the
10026 * hash) being the last seen hfinfo.
10027 */
10028 same_name_next_hfinfo =
10029 same_name_hfinfo->same_name_next;
10030
10031 hfinfo->same_name_next = same_name_next_hfinfo;
10032 if (same_name_next_hfinfo)
10033 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10034
10035 same_name_hfinfo->same_name_next = hfinfo;
10036 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10037#ifdef ENABLE_CHECK_FILTER
10038 while (same_name_hfinfo) {
10039 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10040 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", 10040
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10041 same_name_hfinfo = same_name_hfinfo->same_name_next;
10042 }
10043#endif
10044 }
10045 }
10046
10047 return hfinfo->id;
10048}
10049
10050void
10051proto_register_subtree_array(int * const *indices, const int num_indices)
10052{
10053 int i;
10054 int *const *ptr = indices;
10055
10056 /*
10057 * If we've already allocated the array of tree types, expand
10058 * it; this lets plugins such as mate add tree types after
10059 * the initial startup. (If we haven't already allocated it,
10060 * we don't allocate it; on the first pass, we just assign
10061 * ett values and keep track of how many we've assigned, and
10062 * when we're finished registering all dissectors we allocate
10063 * the array, so that we do only one allocation rather than
10064 * wasting CPU time and memory by growing the array for each
10065 * dissector that registers ett values.)
10066 */
10067 if (tree_is_expanded != NULL((void*)0)) {
10068 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10069
10070 /* set new items to 0 */
10071 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10072 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10073 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10074 }
10075
10076 /*
10077 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10078 * returning the indices through the pointers in the array whose
10079 * first element is pointed to by "indices", and update
10080 * "num_tree_types" appropriately.
10081 */
10082 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10083 if (**ptr != -1 && **ptr != 0) {
10084 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.")
10085 " 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.")
10086 " 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.")
10087 " 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.")
;
10088 }
10089 **ptr = num_tree_types;
10090 }
10091}
10092
10093static void
10094mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10095{
10096 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10097 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10098 char *last_char;
10099
10100 /* ..... field_name: dataaaaaaaaaaaaa
10101 * |
10102 * ^^^^^ name_pos
10103 *
10104 * ..... field_name […]: dataaaaaaaaaaaaa
10105 *
10106 * name_pos==0 means that we have only data or only a field_name
10107 */
10108
10109 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10109, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10110
10111 if (name_pos >= size - trunc_len) {
10112 /* No room for trunc_str after the field_name, put it first. */
10113 name_pos = 0;
10114 }
10115
10116 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10117 if (name_pos == 0) {
10118 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10119 memcpy(label_str, trunc_str + 1, trunc_len);
10120 } else {
10121 memcpy(label_str + name_pos, trunc_str, trunc_len);
10122 }
10123 /* in general, label_str is UTF-8
10124 we can truncate it only at the beginning of a new character
10125 we go backwards from the byte right after our buffer and
10126 find the next starting byte of a UTF-8 character, this is
10127 where we cut
10128 there's no need to use g_utf8_find_prev_char(), the search
10129 will always succeed since we copied trunc_str into the
10130 buffer */
10131 /* g_utf8_prev_char does not deference the memory address
10132 * passed in (until after decrementing it, so it is perfectly
10133 * legal to pass in a pointer one past the last element.
10134 */
10135 last_char = g_utf8_prev_char(label_str + size);
10136 *last_char = '\0';
10137 /* This is unnecessary (above always terminates), but try to
10138 * convince Coverity to avoid dozens of false positives. */
10139 label_str[size - 1] = '\0';
10140
10141 if (value_pos && *value_pos > 0) {
10142 if (name_pos == 0) {
10143 *value_pos += trunc_len;
10144 } else {
10145 /* Move one back to include trunc_str in the value. */
10146 *value_pos -= 1;
10147 }
10148 }
10149
10150 /* Check if value_pos is past label_str. */
10151 if (value_pos && *value_pos >= size) {
10152 *value_pos = size - 1;
10153 }
10154}
10155
10156static void
10157label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10158{
10159 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10160}
10161
10162static size_t
10163label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10164{
10165 size_t name_pos;
10166
10167 /* "%s: %s", hfinfo->name, text */
10168 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)
;
10169 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10170 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10171 if (value_pos) {
10172 *value_pos = pos;
10173 }
10174 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10175 }
10176
10177 if (pos >= ITEM_LABEL_LENGTH240) {
10178 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10179 label_mark_truncated(label_str, name_pos, value_pos);
10180 }
10181
10182 return pos;
10183}
10184
10185static size_t
10186label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10187{
10188 size_t name_pos;
10189
10190 /* "%s: %s (%s)", hfinfo->name, text, descr */
10191 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)
;
10192 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10193 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10194 if (value_pos) {
10195 *value_pos = pos;
10196 }
10197 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10198 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)
;
10199 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)
;
10200 } else {
10201 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)
;
10202 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10203 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)
;
10204 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10205 }
10206 }
10207
10208 if (pos >= ITEM_LABEL_LENGTH240) {
10209 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10210 label_mark_truncated(label_str, name_pos, value_pos);
10211 }
10212
10213 return pos;
10214}
10215
10216void
10217proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10218{
10219 const header_field_info *hfinfo;
10220 const char *str;
10221 const uint8_t *bytes;
10222 uint32_t integer;
10223 const ipv4_addr_and_mask *ipv4;
10224 const ipv6_addr_and_prefix *ipv6;
10225 const e_guid_t *guid;
10226 char *name;
10227 address addr;
10228 char *addr_str;
10229 char *tmp;
10230
10231 if (!label_str) {
10232 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10232, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10233 return;
10234 }
10235
10236 label_str[0]= '\0';
10237
10238 if (!fi) {
10239 return;
10240 }
10241
10242 hfinfo = fi->hfinfo;
10243
10244 switch (hfinfo->type) {
10245 case FT_NONE:
10246 case FT_PROTOCOL:
10247 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10248 if (value_pos) {
10249 *value_pos = strlen(hfinfo->name);
10250 }
10251 break;
10252
10253 case FT_BOOLEAN:
10254 fill_label_boolean(fi, label_str, value_pos);
10255 break;
10256
10257 case FT_BYTES:
10258 case FT_UINT_BYTES:
10259 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10260 fvalue_get_bytes_data(fi->value),
10261 (unsigned)fvalue_length2(fi->value));
10262 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10263 wmem_free(NULL((void*)0), tmp);
10264 break;
10265
10266 case FT_CHAR:
10267 if (hfinfo->bitmask) {
10268 fill_label_bitfield_char(fi, label_str, value_pos);
10269 } else {
10270 fill_label_char(fi, label_str, value_pos);
10271 }
10272 break;
10273
10274 /* Four types of integers to take care of:
10275 * Bitfield, with val_string
10276 * Bitfield, w/o val_string
10277 * Non-bitfield, with val_string
10278 * Non-bitfield, w/o val_string
10279 */
10280 case FT_UINT8:
10281 case FT_UINT16:
10282 case FT_UINT24:
10283 case FT_UINT32:
10284 if (hfinfo->bitmask) {
10285 fill_label_bitfield(fi, label_str, value_pos, false0);
10286 } else {
10287 fill_label_number(fi, label_str, value_pos, false0);
10288 }
10289 break;
10290
10291 case FT_FRAMENUM:
10292 fill_label_number(fi, label_str, value_pos, false0);
10293 break;
10294
10295 case FT_UINT40:
10296 case FT_UINT48:
10297 case FT_UINT56:
10298 case FT_UINT64:
10299 if (hfinfo->bitmask) {
10300 fill_label_bitfield64(fi, label_str, value_pos, false0);
10301 } else {
10302 fill_label_number64(fi, label_str, value_pos, false0);
10303 }
10304 break;
10305
10306 case FT_INT8:
10307 case FT_INT16:
10308 case FT_INT24:
10309 case FT_INT32:
10310 if (hfinfo->bitmask) {
10311 fill_label_bitfield(fi, label_str, value_pos, true1);
10312 } else {
10313 fill_label_number(fi, label_str, value_pos, true1);
10314 }
10315 break;
10316
10317 case FT_INT40:
10318 case FT_INT48:
10319 case FT_INT56:
10320 case FT_INT64:
10321 if (hfinfo->bitmask) {
10322 fill_label_bitfield64(fi, label_str, value_pos, true1);
10323 } else {
10324 fill_label_number64(fi, label_str, value_pos, true1);
10325 }
10326 break;
10327
10328 case FT_FLOAT:
10329 case FT_DOUBLE:
10330 fill_label_float(fi, label_str, value_pos);
10331 break;
10332
10333 case FT_ABSOLUTE_TIME:
10334 {
10335 const nstime_t *value = fvalue_get_time(fi->value);
10336 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10337 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10338 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10339 }
10340 if (hfinfo->strings) {
10341 /*
10342 * Table of time valus to be displayed
10343 * specially.
10344 */
10345 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10346 if (time_string != NULL((void*)0)) {
10347 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10348 break;
10349 }
10350 }
10351 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10352 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10353 wmem_free(NULL((void*)0), tmp);
10354 break;
10355 }
10356 case FT_RELATIVE_TIME:
10357 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10358 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10359 wmem_free(NULL((void*)0), tmp);
10360 break;
10361
10362 case FT_IPXNET:
10363 integer = fvalue_get_uinteger(fi->value);
10364 tmp = get_ipxnet_name(NULL((void*)0), integer);
10365 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10366 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10367 wmem_free(NULL((void*)0), tmp);
10368 wmem_free(NULL((void*)0), addr_str);
10369 break;
10370
10371 case FT_VINES:
10372 addr.type = AT_VINES;
10373 addr.len = VINES_ADDR_LEN6;
10374 addr.data = fvalue_get_bytes_data(fi->value);
10375
10376 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10377 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10378 wmem_free(NULL((void*)0), addr_str);
10379 break;
10380
10381 case FT_ETHER:
10382 bytes = fvalue_get_bytes_data(fi->value);
10383
10384 addr.type = AT_ETHER;
10385 addr.len = 6;
10386 addr.data = bytes;
10387
10388 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10389 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10390 wmem_free(NULL((void*)0), addr_str);
10391 break;
10392
10393 case FT_IPv4:
10394 ipv4 = fvalue_get_ipv4(fi->value);
10395 set_address_ipv4(&addr, ipv4);
10396
10397 if (hfinfo->display == BASE_NETMASK) {
10398 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10399 } else {
10400 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10401 }
10402 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10403 wmem_free(NULL((void*)0), addr_str);
10404 free_address(&addr);
10405 break;
10406
10407 case FT_IPv6:
10408 ipv6 = fvalue_get_ipv6(fi->value);
10409 set_address_ipv6(&addr, ipv6);
10410
10411 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10412 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10413 wmem_free(NULL((void*)0), addr_str);
10414 free_address(&addr);
10415 break;
10416
10417 case FT_FCWWN:
10418 bytes = fvalue_get_bytes_data(fi->value);
10419 addr.type = AT_FCWWN;
10420 addr.len = FCWWN_ADDR_LEN8;
10421 addr.data = bytes;
10422
10423 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10424 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10425 wmem_free(NULL((void*)0), addr_str);
10426 break;
10427
10428 case FT_GUID:
10429 guid = fvalue_get_guid(fi->value);
10430 tmp = guid_to_str(NULL((void*)0), guid);
10431 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10432 wmem_free(NULL((void*)0), tmp);
10433 break;
10434
10435 case FT_OID:
10436 bytes = fvalue_get_bytes_data(fi->value);
10437 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10438 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10439 if (name) {
10440 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10441 wmem_free(NULL((void*)0), name);
10442 } else {
10443 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10444 }
10445 wmem_free(NULL((void*)0), tmp);
10446 break;
10447
10448 case FT_REL_OID:
10449 bytes = fvalue_get_bytes_data(fi->value);
10450 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10451 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10452 if (name) {
10453 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10454 wmem_free(NULL((void*)0), name);
10455 } else {
10456 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10457 }
10458 wmem_free(NULL((void*)0), tmp);
10459 break;
10460
10461 case FT_SYSTEM_ID:
10462 bytes = fvalue_get_bytes_data(fi->value);
10463 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10464 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10465 wmem_free(NULL((void*)0), tmp);
10466 break;
10467
10468 case FT_EUI64:
10469 bytes = fvalue_get_bytes_data(fi->value);
10470 addr.type = AT_EUI64;
10471 addr.len = EUI64_ADDR_LEN8;
10472 addr.data = bytes;
10473
10474 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10475 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10476 wmem_free(NULL((void*)0), addr_str);
10477 break;
10478 case FT_STRING:
10479 case FT_STRINGZ:
10480 case FT_UINT_STRING:
10481 case FT_STRINGZPAD:
10482 case FT_STRINGZTRUNC:
10483 case FT_AX25:
10484 str = fvalue_get_string(fi->value);
10485 label_fill(label_str, 0, hfinfo, str, value_pos);
10486 break;
10487
10488 case FT_IEEE_11073_SFLOAT:
10489 case FT_IEEE_11073_FLOAT:
10490 fill_label_ieee_11073_float(fi, label_str, value_pos);
10491 break;
10492
10493 default:
10494 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
))
10495 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
))
10496 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
))
10497 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
))
;
10498 break;
10499 }
10500}
10501
10502static void
10503fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10504{
10505 char *p;
10506 int bitfield_byte_length = 0, bitwidth;
10507 uint64_t unshifted_value;
10508 uint64_t value;
10509
10510 const header_field_info *hfinfo = fi->hfinfo;
10511
10512 value = fvalue_get_uinteger64(fi->value);
10513 if (hfinfo->bitmask) {
10514 /* Figure out the bit width */
10515 bitwidth = hfinfo_container_bitwidth(hfinfo);
10516
10517 /* Un-shift bits */
10518 unshifted_value = value;
10519 unshifted_value <<= hfinfo_bitshift(hfinfo);
10520
10521 /* Create the bitfield first */
10522 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10523 bitfield_byte_length = (int) (p - label_str);
10524 }
10525
10526 /* Fill in the textual info */
10527 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10528}
10529
10530static const char *
10531hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10532{
10533 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10534 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10535
10536 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10537 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10538 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10539 else
10540 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10541 }
10542
10543 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10544 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10545
10546 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10547 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10548
10549 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10550}
10551
10552static const char *
10553hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10554{
10555 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10556 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10557 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10558 else
10559 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10560 }
10561
10562 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10563 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10564
10565 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10566 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10567
10568 /* If this is reached somebody registered a 64-bit field with a 32-bit
10569 * value-string, which isn't right. */
10570 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)
10571 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10572
10573 /* This is necessary to squelch MSVC errors; is there
10574 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10575 never returns? */
10576 return NULL((void*)0);
10577}
10578
10579static const char *
10580hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10581{
10582 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10583 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10584
10585 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)
;
10586
10587 /* This is necessary to squelch MSVC errors; is there
10588 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10589 never returns? */
10590 return NULL((void*)0);
10591}
10592
10593static const char *
10594hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10595{
10596 const char *str = hf_try_val_to_str(value, hfinfo);
10597
10598 return (str) ? str : unknown_str;
10599}
10600
10601static const char *
10602hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10603{
10604 const char *str = hf_try_val64_to_str(value, hfinfo);
10605
10606 return (str) ? str : unknown_str;
10607}
10608
10609/* Fills data for bitfield chars with val_strings */
10610static void
10611fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10612{
10613 char *p;
10614 int bitfield_byte_length, bitwidth;
10615 uint32_t unshifted_value;
10616 uint32_t value;
10617
10618 char buf[32];
10619 const char *out;
10620
10621 const header_field_info *hfinfo = fi->hfinfo;
10622
10623 /* Figure out the bit width */
10624 bitwidth = hfinfo_container_bitwidth(hfinfo);
10625
10626 /* Un-shift bits */
10627 value = fvalue_get_uinteger(fi->value);
10628
10629 unshifted_value = value;
10630 if (hfinfo->bitmask) {
10631 unshifted_value <<= hfinfo_bitshift(hfinfo);
10632 }
10633
10634 /* Create the bitfield first */
10635 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10636 bitfield_byte_length = (int) (p - label_str);
10637
10638 /* Fill in the textual info using stored (shifted) value */
10639 if (hfinfo->display == BASE_CUSTOM) {
10640 char tmp[ITEM_LABEL_LENGTH240];
10641 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10642
10643 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10643, "fmtfunc"))))
;
10644 fmtfunc(tmp, value);
10645 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10646 }
10647 else if (hfinfo->strings) {
10648 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10649
10650 out = hfinfo_char_vals_format(hfinfo, buf, value);
10651 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10652 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10653 else
10654 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10655 }
10656 else {
10657 out = hfinfo_char_value_format(hfinfo, buf, value);
10658
10659 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10660 }
10661}
10662
10663/* Fills data for bitfield ints with val_strings */
10664static void
10665fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10666{
10667 char *p;
10668 int bitfield_byte_length, bitwidth;
10669 uint32_t value, unshifted_value;
10670 char buf[NUMBER_LABEL_LENGTH80];
10671 const char *out;
10672
10673 const header_field_info *hfinfo = fi->hfinfo;
10674
10675 /* Figure out the bit width */
10676 if (fi->flags & FI_VARINT0x00040000)
10677 bitwidth = fi->length*8;
10678 else
10679 bitwidth = hfinfo_container_bitwidth(hfinfo);
10680
10681 /* Un-shift bits */
10682 if (is_signed)
10683 value = fvalue_get_sinteger(fi->value);
10684 else
10685 value = fvalue_get_uinteger(fi->value);
10686
10687 unshifted_value = value;
10688 if (hfinfo->bitmask) {
10689 unshifted_value <<= hfinfo_bitshift(hfinfo);
10690 }
10691
10692 /* Create the bitfield first */
10693 if (fi->flags & FI_VARINT0x00040000)
10694 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10695 else
10696 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10697 bitfield_byte_length = (int) (p - label_str);
10698
10699 /* Fill in the textual info using stored (shifted) value */
10700 if (hfinfo->display == BASE_CUSTOM) {
10701 char tmp[ITEM_LABEL_LENGTH240];
10702 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10703
10704 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10704, "fmtfunc"))))
;
10705 fmtfunc(tmp, value);
10706 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10707 }
10708 else if (hfinfo->strings) {
10709 const char *val_str = hf_try_val_to_str(value, hfinfo);
10710
10711 out = hfinfo_number_vals_format(hfinfo, buf, value);
10712 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10713 /*
10714 * Unique values only display value_string string
10715 * if there is a match. Otherwise it's just a number
10716 */
10717 if (val_str) {
10718 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10719 } else {
10720 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10721 }
10722 } else {
10723 if (val_str == NULL((void*)0))
10724 val_str = "Unknown";
10725
10726 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10727 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10728 else
10729 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10730 }
10731 }
10732 else {
10733 out = hfinfo_number_value_format(hfinfo, buf, value);
10734
10735 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10736 }
10737}
10738
10739static void
10740fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10741{
10742 char *p;
10743 int bitfield_byte_length, bitwidth;
10744 uint64_t value, unshifted_value;
10745 char buf[NUMBER_LABEL_LENGTH80];
10746 const char *out;
10747
10748 const header_field_info *hfinfo = fi->hfinfo;
10749
10750 /* Figure out the bit width */
10751 if (fi->flags & FI_VARINT0x00040000)
10752 bitwidth = fi->length*8;
10753 else
10754 bitwidth = hfinfo_container_bitwidth(hfinfo);
10755
10756 /* Un-shift bits */
10757 if (is_signed)
10758 value = fvalue_get_sinteger64(fi->value);
10759 else
10760 value = fvalue_get_uinteger64(fi->value);
10761
10762 unshifted_value = value;
10763 if (hfinfo->bitmask) {
10764 unshifted_value <<= hfinfo_bitshift(hfinfo);
10765 }
10766
10767 /* Create the bitfield first */
10768 if (fi->flags & FI_VARINT0x00040000)
10769 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10770 else
10771 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10772 bitfield_byte_length = (int) (p - label_str);
10773
10774 /* Fill in the textual info using stored (shifted) value */
10775 if (hfinfo->display == BASE_CUSTOM) {
10776 char tmp[ITEM_LABEL_LENGTH240];
10777 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10778
10779 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10779, "fmtfunc64"
))))
;
10780 fmtfunc64(tmp, value);
10781 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10782 }
10783 else if (hfinfo->strings) {
10784 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10785
10786 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10787 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10788 /*
10789 * Unique values only display value_string string
10790 * if there is a match. Otherwise it's just a number
10791 */
10792 if (val_str) {
10793 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10794 } else {
10795 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10796 }
10797 } else {
10798 if (val_str == NULL((void*)0))
10799 val_str = "Unknown";
10800
10801 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10802 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10803 else
10804 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10805 }
10806 }
10807 else {
10808 out = hfinfo_number_value_format64(hfinfo, buf, value);
10809
10810 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10811 }
10812}
10813
10814static void
10815fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10816{
10817 const header_field_info *hfinfo = fi->hfinfo;
10818 uint32_t value;
10819
10820 char buf[32];
10821 const char *out;
10822
10823 value = fvalue_get_uinteger(fi->value);
10824
10825 /* Fill in the textual info */
10826 if (hfinfo->display == BASE_CUSTOM) {
10827 char tmp[ITEM_LABEL_LENGTH240];
10828 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10829
10830 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10830, "fmtfunc"))))
;
10831 fmtfunc(tmp, value);
10832 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10833 }
10834 else if (hfinfo->strings) {
10835 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10836
10837 out = hfinfo_char_vals_format(hfinfo, buf, value);
10838 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10839 }
10840 else {
10841 out = hfinfo_char_value_format(hfinfo, buf, value);
10842
10843 label_fill(label_str, 0, hfinfo, out, value_pos);
10844 }
10845}
10846
10847static void
10848fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10849{
10850 const header_field_info *hfinfo = fi->hfinfo;
10851 uint32_t value;
10852
10853 char buf[NUMBER_LABEL_LENGTH80];
10854 const char *out;
10855
10856 if (is_signed)
10857 value = fvalue_get_sinteger(fi->value);
10858 else
10859 value = fvalue_get_uinteger(fi->value);
10860
10861 /* Fill in the textual info */
10862 if (hfinfo->display == BASE_CUSTOM) {
10863 char tmp[ITEM_LABEL_LENGTH240];
10864 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10865
10866 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10866, "fmtfunc"))))
;
10867 fmtfunc(tmp, value);
10868 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10869 }
10870 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10871 /*
10872 * It makes no sense to have a value-string table for a
10873 * frame-number field - they're just integers giving
10874 * the ordinal frame number.
10875 */
10876 const char *val_str = hf_try_val_to_str(value, hfinfo);
10877
10878 out = hfinfo_number_vals_format(hfinfo, buf, value);
10879 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10880 /*
10881 * Unique values only display value_string string
10882 * if there is a match. Otherwise it's just a number
10883 */
10884 if (val_str) {
10885 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10886 } else {
10887 label_fill(label_str, 0, hfinfo, out, value_pos);
10888 }
10889 } else {
10890 if (val_str == NULL((void*)0))
10891 val_str = "Unknown";
10892
10893 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10894 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10895 else
10896 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10897 }
10898 }
10899 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
))
) {
10900 char tmp[ITEM_LABEL_LENGTH240];
10901
10902 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10903 display_to_port_type((field_display_e)hfinfo->display), value);
10904 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10905 }
10906 else {
10907 out = hfinfo_number_value_format(hfinfo, buf, value);
10908
10909 label_fill(label_str, 0, hfinfo, out, value_pos);
10910 }
10911}
10912
10913static void
10914fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10915{
10916 const header_field_info *hfinfo = fi->hfinfo;
10917 uint64_t value;
10918
10919 char buf[NUMBER_LABEL_LENGTH80];
10920 const char *out;
10921
10922 if (is_signed)
10923 value = fvalue_get_sinteger64(fi->value);
10924 else
10925 value = fvalue_get_uinteger64(fi->value);
10926
10927 /* Fill in the textual info */
10928 if (hfinfo->display == BASE_CUSTOM) {
10929 char tmp[ITEM_LABEL_LENGTH240];
10930 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10931
10932 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10932, "fmtfunc64"
))))
;
10933 fmtfunc64(tmp, value);
10934 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10935 }
10936 else if (hfinfo->strings) {
10937 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10938
10939 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10940 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10941 /*
10942 * Unique values only display value_string string
10943 * if there is a match. Otherwise it's just a number
10944 */
10945 if (val_str) {
10946 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10947 } else {
10948 label_fill(label_str, 0, hfinfo, out, value_pos);
10949 }
10950 } else {
10951 if (val_str == NULL((void*)0))
10952 val_str = "Unknown";
10953
10954 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10955 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10956 else
10957 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10958 }
10959 }
10960 else {
10961 out = hfinfo_number_value_format64(hfinfo, buf, value);
10962
10963 label_fill(label_str, 0, hfinfo, out, value_pos);
10964 }
10965}
10966
10967static size_t
10968fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10969{
10970 int display;
10971 int n;
10972 double value;
10973
10974 if (label_str_size < 12) {
10975 /* Not enough room to write an entire floating point value. */
10976 return 0;
10977 }
10978
10979 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10980 value = fvalue_get_floating(fi->value);
10981
10982 if (display == BASE_CUSTOM) {
10983 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10984 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10984, "fmtfunc"))))
;
10985 fmtfunc(label_str, value);
10986 return strlen(label_str);
10987 }
10988
10989 switch (display) {
10990 case BASE_NONE:
10991 if (fi->hfinfo->type == FT_FLOAT) {
10992 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10993 } else {
10994 n = (int)strlen(dtoa_g_fmt(label_str, value));
10995 }
10996 break;
10997 case BASE_DEC:
10998 n = snprintf(label_str, label_str_size, "%f", value);
10999 break;
11000 case BASE_HEX:
11001 n = snprintf(label_str, label_str_size, "%a", value);
11002 break;
11003 case BASE_EXP:
11004 n = snprintf(label_str, label_str_size, "%e", value);
11005 break;
11006 default:
11007 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11007
, __func__, "assertion \"not reached\" failed")
;
11008 }
11009 if (n < 0) {
11010 return 0; /* error */
11011 }
11012 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11013 const char *hf_str_val;
11014 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11015 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11016 }
11017 if (n > label_str_size) {
11018 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11018, __func__, "label length too small"); } } while (0)
;
11019 return strlen(label_str);
11020 }
11021
11022 return n;
11023}
11024
11025void
11026fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11027{
11028 char tmp[ITEM_LABEL_LENGTH240];
11029
11030 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11031 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11032}
11033
11034static size_t
11035fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11036{
11037 int display;
11038 size_t pos = 0;
11039 double value;
11040 char* tmp_str;
11041
11042 if (label_str_size < 12) {
11043 /* Not enough room to write an entire floating point value. */
11044 return 0;
11045 }
11046
11047 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11048 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11049 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11050 wmem_free(NULL((void*)0), tmp_str);
11051
11052 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11053 const char *hf_str_val;
11054 fvalue_to_double(fi->value, &value);
11055 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11056 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)
;
11057 }
11058 if ((int)pos > label_str_size) {
11059 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11059, __func__, "label length too small"); } } while (0)
;
11060 return strlen(label_str);
11061 }
11062
11063 return pos;
11064}
11065
11066void
11067fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11068{
11069 char tmp[ITEM_LABEL_LENGTH240];
11070
11071 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11072 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11073}
11074
11075int
11076hfinfo_bitshift(const header_field_info *hfinfo)
11077{
11078 return ws_ctz(hfinfo->bitmask);
11079}
11080
11081
11082static int
11083hfinfo_bitoffset(const header_field_info *hfinfo)
11084{
11085 if (!hfinfo->bitmask) {
11086 return 0;
11087 }
11088
11089 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11090 * as the first bit */
11091 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11092}
11093
11094static int
11095hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11096{
11097 if (!hfinfo->bitmask) {
11098 return 0;
11099 }
11100
11101 /* ilog2 = first set bit, ctz = last set bit */
11102 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11103}
11104
11105static int
11106hfinfo_type_bitwidth(enum ftenum type)
11107{
11108 int bitwidth = 0;
11109
11110 switch (type) {
11111 case FT_CHAR:
11112 case FT_UINT8:
11113 case FT_INT8:
11114 bitwidth = 8;
11115 break;
11116 case FT_UINT16:
11117 case FT_INT16:
11118 bitwidth = 16;
11119 break;
11120 case FT_UINT24:
11121 case FT_INT24:
11122 bitwidth = 24;
11123 break;
11124 case FT_UINT32:
11125 case FT_INT32:
11126 bitwidth = 32;
11127 break;
11128 case FT_UINT40:
11129 case FT_INT40:
11130 bitwidth = 40;
11131 break;
11132 case FT_UINT48:
11133 case FT_INT48:
11134 bitwidth = 48;
11135 break;
11136 case FT_UINT56:
11137 case FT_INT56:
11138 bitwidth = 56;
11139 break;
11140 case FT_UINT64:
11141 case FT_INT64:
11142 bitwidth = 64;
11143 break;
11144 default:
11145 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11145))
;
11146 ;
11147 }
11148 return bitwidth;
11149}
11150
11151
11152static int
11153hfinfo_container_bitwidth(const header_field_info *hfinfo)
11154{
11155 if (!hfinfo->bitmask) {
11156 return 0;
11157 }
11158
11159 if (hfinfo->type == FT_BOOLEAN) {
11160 return hfinfo->display; /* hacky? :) */
11161 }
11162
11163 return hfinfo_type_bitwidth(hfinfo->type);
11164}
11165
11166static int
11167hfinfo_hex_digits(const header_field_info *hfinfo)
11168{
11169 int bitwidth;
11170
11171 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11172 * appropriate to determine the number of hex digits for the field.
11173 * So instead, we compute it from the bitmask.
11174 */
11175 if (hfinfo->bitmask != 0) {
11176 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11177 } else {
11178 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11179 }
11180
11181 /* Divide by 4, rounding up, to get number of hex digits. */
11182 return (bitwidth + 3) / 4;
11183}
11184
11185const char *
11186hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11187{
11188 char *ptr = &buf[6];
11189 static const char hex_digits[16] =
11190 { '0', '1', '2', '3', '4', '5', '6', '7',
11191 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11192
11193 *ptr = '\0';
11194 *(--ptr) = '\'';
11195 /* Properly format value */
11196 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11197 /*
11198 * Printable, so just show the character, and, if it needs
11199 * to be escaped, escape it.
11200 */
11201 *(--ptr) = value;
11202 if (value == '\\' || value == '\'')
11203 *(--ptr) = '\\';
11204 } else {
11205 /*
11206 * Non-printable; show it as an escape sequence.
11207 */
11208 switch (value) {
11209
11210 case '\0':
11211 /*
11212 * Show a NUL with only one digit.
11213 */
11214 *(--ptr) = '0';
11215 break;
11216
11217 case '\a':
11218 case '\b':
11219 case '\f':
11220 case '\n':
11221 case '\r':
11222 case '\t':
11223 case '\v':
11224 *(--ptr) = value - '\a' + 'a';
11225 break;
11226
11227 default:
11228 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11229
11230 case BASE_OCT:
11231 *(--ptr) = (value & 0x7) + '0';
11232 value >>= 3;
11233 *(--ptr) = (value & 0x7) + '0';
11234 value >>= 3;
11235 *(--ptr) = (value & 0x7) + '0';
11236 break;
11237
11238 case BASE_HEX:
11239 *(--ptr) = hex_digits[value & 0x0F];
11240 value >>= 4;
11241 *(--ptr) = hex_digits[value & 0x0F];
11242 *(--ptr) = 'x';
11243 break;
11244
11245 default:
11246 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11247 }
11248 }
11249 *(--ptr) = '\\';
11250 }
11251 *(--ptr) = '\'';
11252 return ptr;
11253}
11254
11255static const char *
11256hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11257{
11258 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11259 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
))
;
11260
11261 *ptr = '\0';
11262 /* Properly format value */
11263 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11264 case BASE_DEC:
11265 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11266
11267 case BASE_DEC_HEX:
11268 *(--ptr) = ')';
11269 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11270 *(--ptr) = '(';
11271 *(--ptr) = ' ';
11272 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11273 return ptr;
11274
11275 case BASE_OCT:
11276 return oct_to_str_back(ptr, value);
11277
11278 case BASE_HEX:
11279 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11280
11281 case BASE_HEX_DEC:
11282 *(--ptr) = ')';
11283 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11284 *(--ptr) = '(';
11285 *(--ptr) = ' ';
11286 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11287 return ptr;
11288
11289 case BASE_PT_UDP:
11290 case BASE_PT_TCP:
11291 case BASE_PT_DCCP:
11292 case BASE_PT_SCTP:
11293 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11294 display_to_port_type((field_display_e)display), value);
11295 return buf;
11296 case BASE_OUI:
11297 {
11298 uint8_t p_oui[3];
11299 const char *manuf_name;
11300
11301 p_oui[0] = value >> 16 & 0xFF;
11302 p_oui[1] = value >> 8 & 0xFF;
11303 p_oui[2] = value & 0xFF;
11304
11305 /* Attempt an OUI lookup. */
11306 manuf_name = uint_get_manuf_name_if_known(value);
11307 if (manuf_name == NULL((void*)0)) {
11308 /* Could not find an OUI. */
11309 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11310 }
11311 else {
11312 /* Found an address string. */
11313 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11314 }
11315 return buf;
11316 }
11317
11318 default:
11319 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11320 }
11321 return ptr;
11322}
11323
11324static const char *
11325hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11326{
11327 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11328 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
))
;
11329
11330 *ptr = '\0';
11331 /* Properly format value */
11332 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11333 case BASE_DEC:
11334 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11335
11336 case BASE_DEC_HEX:
11337 *(--ptr) = ')';
11338 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11339 *(--ptr) = '(';
11340 *(--ptr) = ' ';
11341 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11342 return ptr;
11343
11344 case BASE_OCT:
11345 return oct64_to_str_back(ptr, value);
11346
11347 case BASE_HEX:
11348 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11349
11350 case BASE_HEX_DEC:
11351 *(--ptr) = ')';
11352 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11353 *(--ptr) = '(';
11354 *(--ptr) = ' ';
11355 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11356 return ptr;
11357
11358 default:
11359 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11360 }
11361
11362 return ptr;
11363}
11364
11365static const char *
11366hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11367{
11368 int display = hfinfo->display;
11369
11370 if (hfinfo->type == FT_FRAMENUM) {
11371 /*
11372 * Frame numbers are always displayed in decimal.
11373 */
11374 display = BASE_DEC;
11375 }
11376
11377 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11378}
11379
11380static const char *
11381hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11382{
11383 int display = hfinfo->display;
11384
11385 if (hfinfo->type == FT_FRAMENUM) {
11386 /*
11387 * Frame numbers are always displayed in decimal.
11388 */
11389 display = BASE_DEC;
11390 }
11391
11392 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11393}
11394
11395static const char *
11396hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11397{
11398 /* Get the underlying BASE_ value */
11399 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11400
11401 return hfinfo_char_value_format_display(display, buf, value);
11402}
11403
11404static const char *
11405hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11406{
11407 /* Get the underlying BASE_ value */
11408 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11409
11410 if (hfinfo->type == FT_FRAMENUM) {
11411 /*
11412 * Frame numbers are always displayed in decimal.
11413 */
11414 display = BASE_DEC;
11415 }
11416
11417 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11418 display = BASE_DEC;
11419 } else if (display == BASE_OUI) {
11420 display = BASE_HEX;
11421 }
11422
11423 switch (display) {
11424 case BASE_NONE:
11425 /* case BASE_DEC: */
11426 case BASE_DEC_HEX:
11427 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11428 case BASE_CUSTOM:
11429 display = BASE_DEC;
11430 break;
11431
11432 /* case BASE_HEX: */
11433 case BASE_HEX_DEC:
11434 display = BASE_HEX;
11435 break;
11436 }
11437
11438 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11439}
11440
11441static const char *
11442hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11443{
11444 /* Get the underlying BASE_ value */
11445 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11446
11447 if (hfinfo->type == FT_FRAMENUM) {
11448 /*
11449 * Frame numbers are always displayed in decimal.
11450 */
11451 display = BASE_DEC;
11452 }
11453
11454 switch (display) {
11455 case BASE_NONE:
11456 /* case BASE_DEC: */
11457 case BASE_DEC_HEX:
11458 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11459 case BASE_CUSTOM:
11460 display = BASE_DEC;
11461 break;
11462
11463 /* case BASE_HEX: */
11464 case BASE_HEX_DEC:
11465 display = BASE_HEX;
11466 break;
11467 }
11468
11469 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11470}
11471
11472static const char *
11473hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11474{
11475 /* Get the underlying BASE_ value */
11476 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11477
11478 return hfinfo_char_value_format_display(display, buf, value);
11479}
11480
11481static const char *
11482hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11483{
11484 /* Get the underlying BASE_ value */
11485 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11486
11487 if (display == BASE_NONE)
11488 return NULL((void*)0);
11489
11490 if (display == BASE_DEC_HEX)
11491 display = BASE_DEC;
11492 if (display == BASE_HEX_DEC)
11493 display = BASE_HEX;
11494
11495 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11496}
11497
11498static const char *
11499hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11500{
11501 /* Get the underlying BASE_ value */
11502 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11503
11504 if (display == BASE_NONE)
11505 return NULL((void*)0);
11506
11507 if (display == BASE_DEC_HEX)
11508 display = BASE_DEC;
11509 if (display == BASE_HEX_DEC)
11510 display = BASE_HEX;
11511
11512 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11513}
11514
11515const char *
11516proto_registrar_get_name(const int n)
11517{
11518 header_field_info *hfinfo;
11519
11520 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", 11520
, __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", 11520
, "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", 11520, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11521 return hfinfo->name;
11522}
11523
11524const char *
11525proto_registrar_get_abbrev(const int n)
11526{
11527 header_field_info *hfinfo;
11528
11529 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", 11529
, __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", 11529
, "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", 11529, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11530 return hfinfo->abbrev;
11531}
11532
11533enum ftenum
11534proto_registrar_get_ftype(const int n)
11535{
11536 header_field_info *hfinfo;
11537
11538 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", 11538
, __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", 11538
, "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", 11538, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11539 return hfinfo->type;
11540}
11541
11542int
11543proto_registrar_get_parent(const int n)
11544{
11545 header_field_info *hfinfo;
11546
11547 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", 11547
, __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", 11547
, "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", 11547, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11548 return hfinfo->parent;
11549}
11550
11551bool_Bool
11552proto_registrar_is_protocol(const int n)
11553{
11554 header_field_info *hfinfo;
11555
11556 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", 11556
, __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", 11556
, "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", 11556, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11557 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11558}
11559
11560/* Returns length of field in packet (not necessarily the length
11561 * in our internal representation, as in the case of IPv4).
11562 * 0 means undeterminable at time of registration
11563 * -1 means the field is not registered. */
11564int
11565proto_registrar_get_length(const int n)
11566{
11567 header_field_info *hfinfo;
11568
11569 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", 11569
, __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", 11569
, "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", 11569, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11570 return ftype_wire_size(hfinfo->type);
11571}
11572
11573size_t
11574proto_registrar_get_count(struct proto_registrar_stats *stats)
11575{
11576 header_field_info *hfinfo;
11577
11578 // Index zero is not used. We have to skip it.
11579 size_t total_count = gpa_hfinfo.len - 1;
11580 if (stats == NULL((void*)0)) {
11581 return total_count;
11582 }
11583 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11584 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11585 stats->deregistered_count++;
11586 continue; /* This is a deregistered protocol or header field */
11587 }
11588
11589 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", 11589
, __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", 11589, "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", 11589, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11590
11591 if (proto_registrar_is_protocol(id))
11592 stats->protocol_count++;
11593
11594 if (hfinfo->same_name_prev_id != -1)
11595 stats->same_name_count++;
11596 }
11597
11598 return total_count;
11599}
11600
11601/* Looks for a protocol or a field in a proto_tree. Returns true if
11602 * it exists anywhere, or false if it exists nowhere. */
11603bool_Bool
11604proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11605{
11606 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11607
11608 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11609 return true1;
11610 }
11611 else {
11612 return false0;
11613 }
11614}
11615
11616/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11617 * This only works if the hfindex was "primed" before the dissection
11618 * took place, as we just pass back the already-created GPtrArray*.
11619 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11620 * handles that. */
11621GPtrArray *
11622proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11623{
11624 if (!tree)
11625 return NULL((void*)0);
11626
11627 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11628 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11629 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11630 else
11631 return NULL((void*)0);
11632}
11633
11634bool_Bool
11635proto_tracking_interesting_fields(const proto_tree *tree)
11636{
11637 GHashTable *interesting_hfids;
11638
11639 if (!tree)
11640 return false0;
11641
11642 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11643
11644 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11645}
11646
11647/* Helper struct for proto_find_info() and proto_all_finfos() */
11648typedef struct {
11649 GPtrArray *array;
11650 int id;
11651} ffdata_t;
11652
11653/* Helper function for proto_find_info() */
11654static bool_Bool
11655find_finfo(proto_node *node, void * data)
11656{
11657 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11658 if (fi && fi->hfinfo) {
11659 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11660 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11661 }
11662 }
11663
11664 /* Don't stop traversing. */
11665 return false0;
11666}
11667
11668/* Helper function for proto_find_first_info() */
11669static bool_Bool
11670find_first_finfo(proto_node *node, void *data)
11671{
11672 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11673 if (fi && fi->hfinfo) {
11674 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11675 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11676
11677 /* Stop traversing. */
11678 return true1;
11679 }
11680 }
11681
11682 /* Continue traversing. */
11683 return false0;
11684}
11685
11686/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11687* This works on any proto_tree, primed or unprimed, but actually searches
11688* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11689* The caller does need to free the returned GPtrArray with
11690* g_ptr_array_free(<array>, true).
11691*/
11692GPtrArray *
11693proto_find_finfo(proto_tree *tree, const int id)
11694{
11695 ffdata_t ffdata;
11696
11697 ffdata.array = g_ptr_array_new();
11698 ffdata.id = id;
11699
11700 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11701
11702 return ffdata.array;
11703}
11704
11705/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11706* This works on any proto_tree, primed or unprimed, but actually searches
11707* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11708* The caller does need to free the returned GPtrArray with
11709* g_ptr_array_free(<array>, true).
11710*/
11711GPtrArray *
11712proto_find_first_finfo(proto_tree *tree, const int id)
11713{
11714 ffdata_t ffdata;
11715
11716 ffdata.array = g_ptr_array_new();
11717 ffdata.id = id;
11718
11719 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11720
11721 return ffdata.array;
11722}
11723
11724/* Helper function for proto_all_finfos() */
11725static bool_Bool
11726every_finfo(proto_node *node, void * data)
11727{
11728 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11729 if (fi && fi->hfinfo) {
11730 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11731 }
11732
11733 /* Don't stop traversing. */
11734 return false0;
11735}
11736
11737/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11738 * The caller does need to free the returned GPtrArray with
11739 * g_ptr_array_free(<array>, true).
11740 */
11741GPtrArray *
11742proto_all_finfos(proto_tree *tree)
11743{
11744 ffdata_t ffdata;
11745
11746 /* Pre allocate enough space to hold all fields in most cases */
11747 ffdata.array = g_ptr_array_sized_new(512);
11748 ffdata.id = 0;
11749
11750 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11751
11752 return ffdata.array;
11753}
11754
11755
11756typedef struct {
11757 unsigned offset;
11758 field_info *finfo;
11759 tvbuff_t *tvb;
11760} offset_search_t;
11761
11762static bool_Bool
11763check_for_offset(proto_node *node, void * data)
11764{
11765 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11766 offset_search_t *offsearch = (offset_search_t *)data;
11767
11768 /* !fi == the top most container node which holds nothing */
11769 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11770 if (offsearch->offset >= (unsigned) fi->start &&
11771 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11772
11773 offsearch->finfo = fi;
11774 return false0; /* keep traversing */
11775 }
11776 }
11777 return false0; /* keep traversing */
11778}
11779
11780/* Search a proto_tree backwards (from leaves to root) looking for the field
11781 * whose start/length occupies 'offset' */
11782/* XXX - I couldn't find an easy way to search backwards, so I search
11783 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11784 * the one I want to return to the user. This algorithm is inefficient
11785 * and could be re-done, but I'd have to handle all the children and
11786 * siblings of each node myself. When I have more time I'll do that.
11787 * (yeah right) */
11788field_info *
11789proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11790{
11791 offset_search_t offsearch;
11792
11793 offsearch.offset = offset;
11794 offsearch.finfo = NULL((void*)0);
11795 offsearch.tvb = tvb;
11796
11797 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11798
11799 return offsearch.finfo;
11800}
11801
11802typedef struct {
11803 unsigned length;
11804 char *buf;
11805} decoded_data_t;
11806
11807static bool_Bool
11808check_for_undecoded(proto_node *node, void * data)
11809{
11810 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11811 decoded_data_t* decoded = (decoded_data_t*)data;
11812 unsigned i;
11813 unsigned byte;
11814 unsigned bit;
11815
11816 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11817 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11818 byte = i / 8;
11819 bit = i % 8;
11820 decoded->buf[byte] |= (1 << bit);
11821 }
11822 }
11823
11824 return false0;
11825}
11826
11827char*
11828proto_find_undecoded_data(proto_tree *tree, unsigned length)
11829{
11830 decoded_data_t decoded;
11831 decoded.length = length;
11832 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11833
11834 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11835 return decoded.buf;
11836}
11837
11838/* Dumps the protocols in the registration database to stdout. An independent
11839 * program can take this output and format it into nice tables or HTML or
11840 * whatever.
11841 *
11842 * There is one record per line. The fields are tab-delimited.
11843 *
11844 * Field 1 = protocol name
11845 * Field 2 = protocol short name
11846 * Field 3 = protocol filter name
11847 * Field 4 = protocol enabled
11848 * Field 5 = protocol enabled by default
11849 * Field 6 = protocol can toggle
11850 */
11851void
11852proto_registrar_dump_protocols(void)
11853{
11854 protocol_t *protocol;
11855 int i;
11856 void *cookie = NULL((void*)0);
11857
11858
11859 i = proto_get_first_protocol(&cookie);
11860 while (i != -1) {
11861 protocol = find_protocol_by_id(i);
11862 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11863 protocol->name,
11864 protocol->short_name,
11865 protocol->filter_name,
11866 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11867 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11868 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11869 i = proto_get_next_protocol(&cookie);
11870 }
11871}
11872
11873/* Dumps the value_strings, extended value string headers, range_strings
11874 * or true/false strings for fields that have them.
11875 * There is one record per line. Fields are tab-delimited.
11876 * There are four types of records: Value String, Extended Value String Header,
11877 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11878 * the type of record.
11879 *
11880 * Note that a record will be generated only if the value_string,... is referenced
11881 * in a registered hfinfo entry.
11882 *
11883 *
11884 * Value Strings
11885 * -------------
11886 * Field 1 = 'V'
11887 * Field 2 = Field abbreviation to which this value string corresponds
11888 * Field 3 = Integer value
11889 * Field 4 = String
11890 *
11891 * Extended Value String Headers
11892 * -----------------------------
11893 * Field 1 = 'E'
11894 * Field 2 = Field abbreviation to which this extended value string header corresponds
11895 * Field 3 = Extended Value String "Name"
11896 * Field 4 = Number of entries in the associated value_string array
11897 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11898 *
11899 * Range Strings
11900 * -------------
11901 * Field 1 = 'R'
11902 * Field 2 = Field abbreviation to which this range string corresponds
11903 * Field 3 = Integer value: lower bound
11904 * Field 4 = Integer value: upper bound
11905 * Field 5 = String
11906 *
11907 * True/False Strings
11908 * ------------------
11909 * Field 1 = 'T'
11910 * Field 2 = Field abbreviation to which this true/false string corresponds
11911 * Field 3 = True String
11912 * Field 4 = False String
11913 */
11914void
11915proto_registrar_dump_values(void)
11916{
11917 header_field_info *hfinfo;
11918 int i, len, vi;
11919 const value_string *vals;
11920 const val64_string *vals64;
11921 const range_string *range;
11922 const true_false_string *tfs;
11923 const unit_name_string *units;
11924
11925 len = gpa_hfinfo.len;
11926 for (i = 1; i < len ; i++) {
11927 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11928 continue; /* This is a deregistered protocol or field */
11929
11930 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", 11930
, __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", 11930
, "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", 11930, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11931
11932 if (hfinfo->id == hf_text_only) {
11933 continue;
11934 }
11935
11936 /* ignore protocols */
11937 if (proto_registrar_is_protocol(i)) {
11938 continue;
11939 }
11940 /* process header fields */
11941#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11942 /*
11943 * If this field isn't at the head of the list of
11944 * fields with this name, skip this field - all
11945 * fields with the same name are really just versions
11946 * of the same field stored in different bits, and
11947 * should have the same type/radix/value list, and
11948 * just differ in their bit masks. (If a field isn't
11949 * a bitfield, but can be, say, 1 or 2 bytes long,
11950 * it can just be made FT_UINT16, meaning the
11951 * *maximum* length is 2 bytes, and be used
11952 * for all lengths.)
11953 */
11954 if (hfinfo->same_name_prev_id != -1)
11955 continue;
11956#endif
11957 vals = NULL((void*)0);
11958 vals64 = NULL((void*)0);
11959 range = NULL((void*)0);
11960 tfs = NULL((void*)0);
11961 units = NULL((void*)0);
11962
11963 if (hfinfo->strings != NULL((void*)0)) {
11964 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11965 (hfinfo->type == FT_CHAR ||
11966 hfinfo->type == FT_UINT8 ||
11967 hfinfo->type == FT_UINT16 ||
11968 hfinfo->type == FT_UINT24 ||
11969 hfinfo->type == FT_UINT32 ||
11970 hfinfo->type == FT_UINT40 ||
11971 hfinfo->type == FT_UINT48 ||
11972 hfinfo->type == FT_UINT56 ||
11973 hfinfo->type == FT_UINT64 ||
11974 hfinfo->type == FT_INT8 ||
11975 hfinfo->type == FT_INT16 ||
11976 hfinfo->type == FT_INT24 ||
11977 hfinfo->type == FT_INT32 ||
11978 hfinfo->type == FT_INT40 ||
11979 hfinfo->type == FT_INT48 ||
11980 hfinfo->type == FT_INT56 ||
11981 hfinfo->type == FT_INT64 ||
11982 hfinfo->type == FT_FLOAT ||
11983 hfinfo->type == FT_DOUBLE)) {
11984
11985 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11986 range = (const range_string *)hfinfo->strings;
11987 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11988 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11989 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11990 } else {
11991 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11992 }
11993 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11994 vals64 = (const val64_string *)hfinfo->strings;
11995 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11996 units = (const unit_name_string *)hfinfo->strings;
11997 } else {
11998 vals = (const value_string *)hfinfo->strings;
11999 }
12000 }
12001 else if (hfinfo->type == FT_BOOLEAN) {
12002 tfs = (const struct true_false_string *)hfinfo->strings;
12003 }
12004 }
12005
12006 /* Print value strings? */
12007 if (vals) {
12008 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12009 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12010 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12011 if (!val64_string_ext_validate(vse_p)) {
12012 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12012, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12013 continue;
12014 }
12015 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12016 printf("E\t%s\t%u\t%s\t%s\n",
12017 hfinfo->abbrev,
12018 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12019 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12020 val64_string_ext_match_type_str(vse_p));
12021 } else {
12022 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12023 if (!value_string_ext_validate(vse_p)) {
12024 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12024, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12025 continue;
12026 }
12027 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12028 printf("E\t%s\t%u\t%s\t%s\n",
12029 hfinfo->abbrev,
12030 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12031 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12032 value_string_ext_match_type_str(vse_p));
12033 }
12034 }
12035 vi = 0;
12036 while (vals[vi].strptr) {
12037 /* Print in the proper base */
12038 if (hfinfo->type == FT_CHAR) {
12039 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12040 printf("V\t%s\t'%c'\t%s\n",
12041 hfinfo->abbrev,
12042 vals[vi].value,
12043 vals[vi].strptr);
12044 } else {
12045 if (hfinfo->display == BASE_HEX) {
12046 printf("V\t%s\t'\\x%02x'\t%s\n",
12047 hfinfo->abbrev,
12048 vals[vi].value,
12049 vals[vi].strptr);
12050 }
12051 else {
12052 printf("V\t%s\t'\\%03o'\t%s\n",
12053 hfinfo->abbrev,
12054 vals[vi].value,
12055 vals[vi].strptr);
12056 }
12057 }
12058 } else {
12059 if (hfinfo->display == BASE_HEX) {
12060 printf("V\t%s\t0x%x\t%s\n",
12061 hfinfo->abbrev,
12062 vals[vi].value,
12063 vals[vi].strptr);
12064 }
12065 else {
12066 printf("V\t%s\t%u\t%s\n",
12067 hfinfo->abbrev,
12068 vals[vi].value,
12069 vals[vi].strptr);
12070 }
12071 }
12072 vi++;
12073 }
12074 }
12075 else if (vals64) {
12076 vi = 0;
12077 while (vals64[vi].strptr) {
12078 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12079 hfinfo->abbrev,
12080 vals64[vi].value,
12081 vals64[vi].strptr);
12082 vi++;
12083 }
12084 }
12085
12086 /* print range strings? */
12087 else if (range) {
12088 vi = 0;
12089 while (range[vi].strptr) {
12090 /* Print in the proper base */
12091 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12092 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12093 hfinfo->abbrev,
12094 range[vi].value_min,
12095 range[vi].value_max,
12096 range[vi].strptr);
12097 }
12098 else {
12099 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12100 hfinfo->abbrev,
12101 range[vi].value_min,
12102 range[vi].value_max,
12103 range[vi].strptr);
12104 }
12105 vi++;
12106 }
12107 }
12108
12109 /* Print true/false strings? */
12110 else if (tfs) {
12111 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12112 tfs->true_string, tfs->false_string);
12113 }
12114 /* Print unit strings? */
12115 else if (units) {
12116 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12117 units->singular, units->plural ? units->plural : "(no plural)");
12118 }
12119 }
12120}
12121
12122/* Prints the number of registered fields.
12123 * Useful for determining an appropriate value for
12124 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12125 *
12126 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12127 * the number of fields, true otherwise.
12128 */
12129bool_Bool
12130proto_registrar_dump_fieldcount(void)
12131{
12132 struct proto_registrar_stats stats = {0, 0, 0};
12133 size_t total_count = proto_registrar_get_count(&stats);
12134
12135 printf("There are %zu header fields registered, of which:\n"
12136 "\t%zu are deregistered\n"
12137 "\t%zu are protocols\n"
12138 "\t%zu have the same name as another field\n\n",
12139 total_count, stats.deregistered_count, stats.protocol_count,
12140 stats.same_name_count);
12141
12142 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12143 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12144 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12145 "\n");
12146
12147 printf("The header field table consumes %u KiB of memory.\n",
12148 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12149 printf("The fields themselves consume %u KiB of memory.\n",
12150 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12151
12152 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12153}
12154
12155static void
12156elastic_add_base_mapping(json_dumper *dumper)
12157{
12158 json_dumper_set_member_name(dumper, "index_patterns");
12159 json_dumper_begin_array(dumper);
12160 // The index names from write_json_index() in print.c
12161 json_dumper_value_string(dumper, "packets-*");
12162 json_dumper_end_array(dumper);
12163
12164 json_dumper_set_member_name(dumper, "settings");
12165 json_dumper_begin_object(dumper);
12166 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12167 json_dumper_value_anyf(dumper, "%d", 1000000);
12168 json_dumper_end_object(dumper);
12169}
12170
12171static char*
12172ws_type_to_elastic(unsigned type)
12173{
12174 switch(type) {
12175 case FT_INT8:
12176 return "byte";
12177 case FT_UINT8:
12178 case FT_INT16:
12179 return "short";
12180 case FT_UINT16:
12181 case FT_INT32:
12182 case FT_UINT24:
12183 case FT_INT24:
12184 return "integer";
12185 case FT_FRAMENUM:
12186 case FT_UINT32:
12187 case FT_UINT40:
12188 case FT_UINT48:
12189 case FT_UINT56:
12190 case FT_INT40:
12191 case FT_INT48:
12192 case FT_INT56:
12193 case FT_INT64:
12194 return "long";
12195 case FT_UINT64:
12196 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12197 case FT_FLOAT:
12198 return "float";
12199 case FT_DOUBLE:
12200 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12201 return "double";
12202 case FT_IPv6:
12203 case FT_IPv4:
12204 return "ip";
12205 case FT_ABSOLUTE_TIME:
12206 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12207 case FT_BOOLEAN:
12208 return "boolean";
12209 default:
12210 return NULL((void*)0);
12211 }
12212}
12213
12214static char*
12215dot_to_underscore(char* str)
12216{
12217 unsigned i;
12218 for (i = 0; i < strlen(str); i++) {
12219 if (str[i] == '.')
12220 str[i] = '_';
12221 }
12222 return str;
12223}
12224
12225/* Dumps a mapping file for ElasticSearch
12226 * This is the v1 (legacy) _template API.
12227 * At some point it may need to be updated with the composable templates
12228 * introduced in Elasticsearch 7.8 (_index_template)
12229 */
12230void
12231proto_registrar_dump_elastic(const char* filter)
12232{
12233 header_field_info *hfinfo;
12234 header_field_info *parent_hfinfo;
12235 unsigned i;
12236 bool_Bool open_object = true1;
12237 const char* prev_proto = NULL((void*)0);
12238 char* str;
12239 char** protos = NULL((void*)0);
12240 char* proto;
12241 bool_Bool found;
12242 unsigned j;
12243 char* type;
12244 char* prev_item = NULL((void*)0);
12245
12246 /* We have filtering protocols. Extract them. */
12247 if (filter) {
12248 protos = g_strsplit(filter, ",", -1);
12249 }
12250
12251 /*
12252 * To help tracking down the json tree, objects have been appended with a comment:
12253 * n.label -> where n is the indentation level and label the name of the object
12254 */
12255
12256 json_dumper dumper = {
12257 .output_file = stdoutstdout,
12258 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12259 };
12260 json_dumper_begin_object(&dumper); // 1.root
12261 elastic_add_base_mapping(&dumper);
12262
12263 json_dumper_set_member_name(&dumper, "mappings");
12264 json_dumper_begin_object(&dumper); // 2.mappings
12265
12266 json_dumper_set_member_name(&dumper, "properties");
12267 json_dumper_begin_object(&dumper); // 3.properties
12268 json_dumper_set_member_name(&dumper, "timestamp");
12269 json_dumper_begin_object(&dumper); // 4.timestamp
12270 json_dumper_set_member_name(&dumper, "type");
12271 json_dumper_value_string(&dumper, "date");
12272 json_dumper_end_object(&dumper); // 4.timestamp
12273
12274 json_dumper_set_member_name(&dumper, "layers");
12275 json_dumper_begin_object(&dumper); // 4.layers
12276 json_dumper_set_member_name(&dumper, "properties");
12277 json_dumper_begin_object(&dumper); // 5.properties
12278
12279 for (i = 1; i < gpa_hfinfo.len; i++) {
12280 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12281 continue; /* This is a deregistered protocol or header field */
12282
12283 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", 12283
, __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", 12283
, "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", 12283, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12284
12285 /*
12286 * Skip the pseudo-field for "proto_tree_add_text()" since
12287 * we don't want it in the list of filterable protocols.
12288 */
12289 if (hfinfo->id == hf_text_only)
12290 continue;
12291
12292 if (!proto_registrar_is_protocol(i)) {
12293 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", 12293
, __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", 12293
, "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", 12293
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12294
12295 /*
12296 * Skip the field if filter protocols have been set and this one's
12297 * parent is not listed.
12298 */
12299 if (protos) {
12300 found = false0;
12301 j = 0;
12302 proto = protos[0];
12303 while(proto) {
12304 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12305 found = true1;
12306 break;
12307 }
12308 j++;
12309 proto = protos[j];
12310 }
12311 if (!found)
12312 continue;
12313 }
12314
12315 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12316 json_dumper_end_object(&dumper); // 7.properties
12317 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12318 open_object = true1;
12319 }
12320
12321 prev_proto = parent_hfinfo->abbrev;
12322
12323 if (open_object) {
12324 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12325 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12326 json_dumper_set_member_name(&dumper, "properties");
12327 json_dumper_begin_object(&dumper); // 7.properties
12328 open_object = false0;
12329 }
12330 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12331 type = ws_type_to_elastic(hfinfo->type);
12332 /* when type is NULL, we have the default mapping: string */
12333 if (type) {
12334 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12335 dot_to_underscore(str);
12336 if (g_strcmp0(prev_item, str)) {
12337 json_dumper_set_member_name(&dumper, str);
12338 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12339 json_dumper_set_member_name(&dumper, "type");
12340 json_dumper_value_string(&dumper, type);
12341 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12342 }
12343 g_free(prev_item);
12344 prev_item = str;
12345 }
12346 }
12347 }
12348 g_free(prev_item);
12349
12350 if (prev_proto) {
12351 json_dumper_end_object(&dumper); // 7.properties
12352 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12353 }
12354
12355 json_dumper_end_object(&dumper); // 5.properties
12356 json_dumper_end_object(&dumper); // 4.layers
12357 json_dumper_end_object(&dumper); // 3.properties
12358 json_dumper_end_object(&dumper); // 2.mappings
12359 json_dumper_end_object(&dumper); // 1.root
12360 bool_Bool ret = json_dumper_finish(&dumper);
12361 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12361, "ret"))))
;
12362
12363 g_strfreev(protos);
12364}
12365
12366/* Dumps the contents of the registration database to stdout. An independent
12367 * program can take this output and format it into nice tables or HTML or
12368 * whatever.
12369 *
12370 * There is one record per line. Each record is either a protocol or a header
12371 * field, differentiated by the first field. The fields are tab-delimited.
12372 *
12373 * Protocols
12374 * ---------
12375 * Field 1 = 'P'
12376 * Field 2 = descriptive protocol name
12377 * Field 3 = protocol abbreviation
12378 *
12379 * Header Fields
12380 * -------------
12381 * Field 1 = 'F'
12382 * Field 2 = descriptive field name
12383 * Field 3 = field abbreviation
12384 * Field 4 = type ( textual representation of the ftenum type )
12385 * Field 5 = parent protocol abbreviation
12386 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12387 * Field 7 = bitmask: format: hex: 0x....
12388 * Field 8 = blurb describing field
12389 */
12390void
12391proto_registrar_dump_fields(void)
12392{
12393 header_field_info *hfinfo, *parent_hfinfo;
12394 int i, len;
12395 const char *enum_name;
12396 const char *base_name;
12397 const char *blurb;
12398 char width[5];
12399
12400 len = gpa_hfinfo.len;
12401 for (i = 1; i < len ; i++) {
12402 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12403 continue; /* This is a deregistered protocol or header field */
12404
12405 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", 12405
, __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", 12405
, "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", 12405, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12406
12407 /*
12408 * Skip the pseudo-field for "proto_tree_add_text()" since
12409 * we don't want it in the list of filterable fields.
12410 */
12411 if (hfinfo->id == hf_text_only)
12412 continue;
12413
12414 /* format for protocols */
12415 if (proto_registrar_is_protocol(i)) {
12416 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12417 }
12418 /* format for header fields */
12419 else {
12420 /*
12421 * If this field isn't at the head of the list of
12422 * fields with this name, skip this field - all
12423 * fields with the same name are really just versions
12424 * of the same field stored in different bits, and
12425 * should have the same type/radix/value list, and
12426 * just differ in their bit masks. (If a field isn't
12427 * a bitfield, but can be, say, 1 or 2 bytes long,
12428 * it can just be made FT_UINT16, meaning the
12429 * *maximum* length is 2 bytes, and be used
12430 * for all lengths.)
12431 */
12432 if (hfinfo->same_name_prev_id != -1)
12433 continue;
12434
12435 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", 12435
, __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", 12435
, "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", 12435
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12436
12437 enum_name = ftype_name(hfinfo->type);
12438 base_name = "";
12439
12440 if (hfinfo->type == FT_CHAR ||
12441 hfinfo->type == FT_UINT8 ||
12442 hfinfo->type == FT_UINT16 ||
12443 hfinfo->type == FT_UINT24 ||
12444 hfinfo->type == FT_UINT32 ||
12445 hfinfo->type == FT_UINT40 ||
12446 hfinfo->type == FT_UINT48 ||
12447 hfinfo->type == FT_UINT56 ||
12448 hfinfo->type == FT_UINT64 ||
12449 hfinfo->type == FT_INT8 ||
12450 hfinfo->type == FT_INT16 ||
12451 hfinfo->type == FT_INT24 ||
12452 hfinfo->type == FT_INT32 ||
12453 hfinfo->type == FT_INT40 ||
12454 hfinfo->type == FT_INT48 ||
12455 hfinfo->type == FT_INT56 ||
12456 hfinfo->type == FT_INT64) {
12457
12458 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12459 case BASE_NONE:
12460 case BASE_DEC:
12461 case BASE_HEX:
12462 case BASE_OCT:
12463 case BASE_DEC_HEX:
12464 case BASE_HEX_DEC:
12465 case BASE_CUSTOM:
12466 case BASE_PT_UDP:
12467 case BASE_PT_TCP:
12468 case BASE_PT_DCCP:
12469 case BASE_PT_SCTP:
12470 case BASE_OUI:
12471 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12472 break;
12473 default:
12474 base_name = "????";
12475 break;
12476 }
12477 } else if (hfinfo->type == FT_BOOLEAN) {
12478 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12479 snprintf(width, sizeof(width), "%d", hfinfo->display);
12480 base_name = width;
12481 }
12482
12483 blurb = hfinfo->blurb;
12484 if (blurb == NULL((void*)0))
12485 blurb = "";
12486 else if (strlen(blurb) == 0)
12487 blurb = "\"\"";
12488
12489 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12490 hfinfo->name, hfinfo->abbrev, enum_name,
12491 parent_hfinfo->abbrev, base_name,
12492 hfinfo->bitmask, blurb);
12493 }
12494 }
12495}
12496
12497/* Dumps all abbreviated field and protocol completions of the given string to
12498 * stdout. An independent program may use this for command-line tab completion
12499 * of fields.
12500 */
12501bool_Bool
12502proto_registrar_dump_field_completions(const char *prefix)
12503{
12504 header_field_info *hfinfo;
12505 int i, len;
12506 size_t prefix_len;
12507 bool_Bool matched = false0;
12508
12509 prefix_len = strlen(prefix);
12510 len = gpa_hfinfo.len;
12511 for (i = 1; i < len ; i++) {
12512 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12513 continue; /* This is a deregistered protocol or header field */
12514
12515 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", 12515
, __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", 12515
, "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", 12515, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12516
12517 /*
12518 * Skip the pseudo-field for "proto_tree_add_text()" since
12519 * we don't want it in the list of filterable fields.
12520 */
12521 if (hfinfo->id == hf_text_only)
12522 continue;
12523
12524 /* format for protocols */
12525 if (proto_registrar_is_protocol(i)) {
12526 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12527 matched = true1;
12528 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12529 }
12530 }
12531 /* format for header fields */
12532 else {
12533 /*
12534 * If this field isn't at the head of the list of
12535 * fields with this name, skip this field - all
12536 * fields with the same name are really just versions
12537 * of the same field stored in different bits, and
12538 * should have the same type/radix/value list, and
12539 * just differ in their bit masks. (If a field isn't
12540 * a bitfield, but can be, say, 1 or 2 bytes long,
12541 * it can just be made FT_UINT16, meaning the
12542 * *maximum* length is 2 bytes, and be used
12543 * for all lengths.)
12544 */
12545 if (hfinfo->same_name_prev_id != -1)
12546 continue;
12547
12548 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12549 matched = true1;
12550 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12551 }
12552 }
12553 }
12554 return matched;
12555}
12556
12557/* Dumps field types and descriptive names to stdout. An independent
12558 * program can take this output and format it into nice tables or HTML or
12559 * whatever.
12560 *
12561 * There is one record per line. The fields are tab-delimited.
12562 *
12563 * Field 1 = field type name, e.g. FT_UINT8
12564 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12565 */
12566void
12567proto_registrar_dump_ftypes(void)
12568{
12569 int fte;
12570
12571 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12572 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12573 }
12574}
12575
12576/* This function indicates whether it's possible to construct a
12577 * "match selected" display filter string for the specified field,
12578 * returns an indication of whether it's possible, and, if it's
12579 * possible and "filter" is non-null, constructs the filter and
12580 * sets "*filter" to point to it.
12581 * You do not need to [g_]free() this string since it will be automatically
12582 * freed once the next packet is dissected.
12583 */
12584static bool_Bool
12585construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12586 char **filter)
12587{
12588 const header_field_info *hfinfo;
12589 int start, length, length_remaining;
12590
12591 if (!finfo)
12592 return false0;
12593
12594 hfinfo = finfo->hfinfo;
12595 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12595, "hfinfo"))))
;
12596
12597 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12598 * then "the numeric value ... is not used when preparing
12599 * filters for the field in question." If it's any other
12600 * base, we'll generate the filter normally (which will
12601 * be numeric, even though the human-readable string does
12602 * work for filtering.)
12603 *
12604 * XXX - It might be nice to use fvalue_to_string_repr() in
12605 * "proto_item_fill_label()" as well, although, there, you'd
12606 * have to deal with the base *and* with resolved values for
12607 * addresses.
12608 *
12609 * Perhaps in addition to taking the repr type (DISPLAY
12610 * or DFILTER) and the display (base), fvalue_to_string_repr()
12611 * should have the the "strings" values in the header_field_info
12612 * structure for the field as a parameter, so it can have
12613 * if the field is Boolean or an enumerated integer type,
12614 * the tables used to generate human-readable values.
12615 */
12616 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12617 const char *str = NULL((void*)0);
12618
12619 switch (hfinfo->type) {
12620
12621 case FT_INT8:
12622 case FT_INT16:
12623 case FT_INT24:
12624 case FT_INT32:
12625 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12626 break;
12627
12628 case FT_CHAR:
12629 case FT_UINT8:
12630 case FT_UINT16:
12631 case FT_UINT24:
12632 case FT_UINT32:
12633 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12634 break;
12635
12636 default:
12637 break;
12638 }
12639
12640 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12641 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12642 return true1;
12643 }
12644 }
12645
12646 switch (hfinfo->type) {
12647
12648 case FT_PROTOCOL:
12649 if (filter != NULL((void*)0))
12650 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12651 break;
12652
12653 case FT_NONE:
12654 /*
12655 * If the length is 0, just match the name of the
12656 * field.
12657 *
12658 * (Also check for negative values, just in case,
12659 * as we'll cast it to an unsigned value later.)
12660 */
12661 length = finfo->length;
12662 if (length == 0) {
12663 if (filter != NULL((void*)0))
12664 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12665 break;
12666 }
12667 if (length < 0)
12668 return false0;
12669
12670 /*
12671 * This doesn't have a value, so we'd match
12672 * on the raw bytes at this address.
12673 *
12674 * Should we be allowed to access to the raw bytes?
12675 * If "edt" is NULL, the answer is "no".
12676 */
12677 if (edt == NULL((void*)0))
12678 return false0;
12679
12680 /*
12681 * Is this field part of the raw frame tvbuff?
12682 * If not, we can't use "frame[N:M]" to match
12683 * it.
12684 *
12685 * XXX - should this be frame-relative, or
12686 * protocol-relative?
12687 *
12688 * XXX - does this fallback for non-registered
12689 * fields even make sense?
12690 */
12691 if (finfo->ds_tvb != edt->tvb)
12692 return false0; /* you lose */
12693
12694 /*
12695 * Don't go past the end of that tvbuff.
12696 */
12697 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12698 if (length > length_remaining)
12699 length = length_remaining;
12700 if (length <= 0)
12701 return false0;
12702
12703 if (filter != NULL((void*)0)) {
12704 start = finfo->start;
12705 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12706 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12707 wmem_free(NULL((void*)0), str);
12708 }
12709 break;
12710
12711 /* By default, use the fvalue's "to_string_repr" method. */
12712 default:
12713 if (filter != NULL((void*)0)) {
12714 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12715 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12716 wmem_free(NULL((void*)0), str);
12717 }
12718 break;
12719 }
12720
12721 return true1;
12722}
12723
12724/*
12725 * Returns true if we can do a "match selected" on the field, false
12726 * otherwise.
12727 */
12728bool_Bool
12729proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12730{
12731 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12732}
12733
12734/* This function attempts to construct a "match selected" display filter
12735 * string for the specified field; if it can do so, it returns a pointer
12736 * to the string, otherwise it returns NULL.
12737 *
12738 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12739 */
12740char *
12741proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12742{
12743 char *filter = NULL((void*)0);
12744
12745 if (!construct_match_selected_string(finfo, edt, &filter))
12746 {
12747 wmem_free(NULL((void*)0), filter);
12748 return NULL((void*)0);
12749 }
12750 return filter;
12751}
12752
12753/* This function is common code for all proto_tree_add_bitmask... functions.
12754 */
12755
12756static bool_Bool
12757proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12758 const int len, const int ett, int * const *fields,
12759 const int flags, bool_Bool first,
12760 bool_Bool use_parent_tree,
12761 proto_tree* tree, uint64_t value)
12762{
12763 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12764 uint64_t bitmask = 0;
12765 uint64_t tmpval;
12766 header_field_info *hf;
12767 uint32_t integer32;
12768 int bit_offset;
12769 int no_of_bits;
12770
12771 if (!*fields)
12772 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"
)
;
12773
12774 if (len < 0 || len > 8)
12775 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12776 /**
12777 * packet-frame.c uses len=0 since the value is taken from the packet
12778 * metadata, not the packet bytes. In that case, assume that all bits
12779 * in the provided value are valid.
12780 */
12781 if (len > 0) {
12782 available_bits >>= (8 - (unsigned)len)*8;
12783 }
12784
12785 if (use_parent_tree == false0)
12786 tree = proto_item_add_subtree(item, ett);
12787
12788 while (*fields) {
12789 uint64_t present_bits;
12790 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", 12790, __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", 12790
, "**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", 12790, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12791 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", 12791
, "hf->bitmask != 0", hf->abbrev))))
;
12792
12793 bitmask |= hf->bitmask;
12794
12795 /* Skip fields that aren't fully present */
12796 present_bits = available_bits & hf->bitmask;
12797 if (present_bits != hf->bitmask) {
12798 fields++;
12799 continue;
12800 }
12801
12802 switch (hf->type) {
12803 case FT_CHAR:
12804 case FT_UINT8:
12805 case FT_UINT16:
12806 case FT_UINT24:
12807 case FT_UINT32:
12808 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12809 break;
12810
12811 case FT_INT8:
12812 case FT_INT16:
12813 case FT_INT24:
12814 case FT_INT32:
12815 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12816 break;
12817
12818 case FT_UINT40:
12819 case FT_UINT48:
12820 case FT_UINT56:
12821 case FT_UINT64:
12822 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12823 break;
12824
12825 case FT_INT40:
12826 case FT_INT48:
12827 case FT_INT56:
12828 case FT_INT64:
12829 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12830 break;
12831
12832 case FT_BOOLEAN:
12833 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12834 break;
12835
12836 default:
12837 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))
12838 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))
12839 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))
12840 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))
;
12841 break;
12842 }
12843 if (flags & BMT_NO_APPEND0x01) {
12844 fields++;
12845 continue;
12846 }
12847 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12848
12849 /* XXX: README.developer and the comments have always defined
12850 * BMT_NO_INT as "only boolean flags are added to the title /
12851 * don't add non-boolean (integral) fields", but the
12852 * implementation has always added BASE_CUSTOM and fields with
12853 * value_strings, though not fields with unit_strings.
12854 * Possibly this is because some dissectors use a FT_UINT8
12855 * with a value_string for fields that should be a FT_BOOLEAN.
12856 */
12857 switch (hf->type) {
12858 case FT_CHAR:
12859 if (hf->display == BASE_CUSTOM) {
12860 char lbl[ITEM_LABEL_LENGTH240];
12861 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12862
12863 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12863, "fmtfunc"))))
;
12864 fmtfunc(lbl, (uint32_t) tmpval);
12865 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12866 hf->name, lbl);
12867 first = false0;
12868 }
12869 else if (hf->strings) {
12870 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12871 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12872 first = false0;
12873 }
12874 else if (!(flags & BMT_NO_INT0x02)) {
12875 char buf[32];
12876 const char *out;
12877
12878 if (!first) {
12879 proto_item_append_text(item, ", ");
12880 }
12881
12882 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12883 proto_item_append_text(item, "%s: %s", hf->name, out);
12884 first = false0;
12885 }
12886
12887 break;
12888
12889 case FT_UINT8:
12890 case FT_UINT16:
12891 case FT_UINT24:
12892 case FT_UINT32:
12893 if (hf->display == BASE_CUSTOM) {
12894 char lbl[ITEM_LABEL_LENGTH240];
12895 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12896
12897 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12897, "fmtfunc"))))
;
12898 fmtfunc(lbl, (uint32_t) tmpval);
12899 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12900 hf->name, lbl);
12901 first = false0;
12902 }
12903 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12904 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12905 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12906 first = false0;
12907 }
12908 else if (!(flags & BMT_NO_INT0x02)) {
12909 char buf[NUMBER_LABEL_LENGTH80];
12910 const char *out = NULL((void*)0);
12911
12912 if (!first) {
12913 proto_item_append_text(item, ", ");
12914 }
12915
12916 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12917 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12918 }
12919 if (out == NULL((void*)0)) {
12920 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12921 }
12922 proto_item_append_text(item, "%s: %s", hf->name, out);
12923 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12924 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12925 }
12926 first = false0;
12927 }
12928
12929 break;
12930
12931 case FT_INT8:
12932 case FT_INT16:
12933 case FT_INT24:
12934 case FT_INT32:
12935 integer32 = (uint32_t) tmpval;
12936 if (hf->bitmask) {
12937 no_of_bits = ws_count_ones(hf->bitmask);
12938 integer32 = ws_sign_ext32(integer32, no_of_bits);
12939 }
12940 if (hf->display == BASE_CUSTOM) {
12941 char lbl[ITEM_LABEL_LENGTH240];
12942 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12943
12944 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12944, "fmtfunc"))))
;
12945 fmtfunc(lbl, (int32_t) integer32);
12946 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12947 hf->name, lbl);
12948 first = false0;
12949 }
12950 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12951 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12952 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12953 first = false0;
12954 }
12955 else if (!(flags & BMT_NO_INT0x02)) {
12956 char buf[NUMBER_LABEL_LENGTH80];
12957 const char *out = NULL((void*)0);
12958
12959 if (!first) {
12960 proto_item_append_text(item, ", ");
12961 }
12962
12963 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12964 out = hf_try_val_to_str((int32_t) integer32, hf);
12965 }
12966 if (out == NULL((void*)0)) {
12967 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12968 }
12969 proto_item_append_text(item, "%s: %s", hf->name, out);
12970 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12971 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12972 }
12973 first = false0;
12974 }
12975
12976 break;
12977
12978 case FT_UINT40:
12979 case FT_UINT48:
12980 case FT_UINT56:
12981 case FT_UINT64:
12982 if (hf->display == BASE_CUSTOM) {
12983 char lbl[ITEM_LABEL_LENGTH240];
12984 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12985
12986 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12986, "fmtfunc"))))
;
12987 fmtfunc(lbl, tmpval);
12988 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12989 hf->name, lbl);
12990 first = false0;
12991 }
12992 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12993 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12994 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12995 first = false0;
12996 }
12997 else if (!(flags & BMT_NO_INT0x02)) {
12998 char buf[NUMBER_LABEL_LENGTH80];
12999 const char *out = NULL((void*)0);
13000
13001 if (!first) {
13002 proto_item_append_text(item, ", ");
13003 }
13004
13005 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13006 out = hf_try_val64_to_str(tmpval, hf);
13007 }
13008 if (out == NULL((void*)0)) {
13009 out = hfinfo_number_value_format64(hf, buf, tmpval);
13010 }
13011 proto_item_append_text(item, "%s: %s", hf->name, out);
13012 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13013 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13014 }
13015 first = false0;
13016 }
13017
13018 break;
13019
13020 case FT_INT40:
13021 case FT_INT48:
13022 case FT_INT56:
13023 case FT_INT64:
13024 if (hf->bitmask) {
13025 no_of_bits = ws_count_ones(hf->bitmask);
13026 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13027 }
13028 if (hf->display == BASE_CUSTOM) {
13029 char lbl[ITEM_LABEL_LENGTH240];
13030 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13031
13032 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13032, "fmtfunc"))))
;
13033 fmtfunc(lbl, (int64_t) tmpval);
13034 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13035 hf->name, lbl);
13036 first = false0;
13037 }
13038 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13039 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13040 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13041 first = false0;
13042 }
13043 else if (!(flags & BMT_NO_INT0x02)) {
13044 char buf[NUMBER_LABEL_LENGTH80];
13045 const char *out = NULL((void*)0);
13046
13047 if (!first) {
13048 proto_item_append_text(item, ", ");
13049 }
13050
13051 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13052 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13053 }
13054 if (out == NULL((void*)0)) {
13055 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13056 }
13057 proto_item_append_text(item, "%s: %s", hf->name, out);
13058 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13059 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13060 }
13061 first = false0;
13062 }
13063
13064 break;
13065
13066 case FT_BOOLEAN:
13067 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13068 /* If we have true/false strings, emit full - otherwise messages
13069 might look weird */
13070 const struct true_false_string *tfs =
13071 (const struct true_false_string *)hf->strings;
13072
13073 if (tmpval) {
13074 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13075 hf->name, tfs->true_string);
13076 first = false0;
13077 } else if (!(flags & BMT_NO_FALSE0x04)) {
13078 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13079 hf->name, tfs->false_string);
13080 first = false0;
13081 }
13082 } else if (hf->bitmask & value) {
13083 /* If the flag is set, show the name */
13084 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13085 first = false0;
13086 }
13087 break;
13088 default:
13089 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))
13090 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))
13091 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))
13092 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))
;
13093 break;
13094 }
13095
13096 fields++;
13097 }
13098
13099 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13100 * but then again most dissectors don't set the bitmask field for
13101 * the higher level bitmask hfi, so calculate the bitmask from the
13102 * fields present. */
13103 if (item) {
13104 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13105 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13106 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)
;
13107 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)
;
13108 }
13109 return first;
13110}
13111
13112/* This function will dissect a sequence of bytes that describe a
13113 * bitmask and supply the value of that sequence through a pointer.
13114 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13115 * to be dissected.
13116 * This field will form an expansion under which the individual fields of the
13117 * bitmask is dissected and displayed.
13118 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13119 *
13120 * fields is an array of pointers to int that lists all the fields of the
13121 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13122 * or another integer of the same type/size as hf_hdr with a mask specified.
13123 * This array is terminated by a NULL entry.
13124 *
13125 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13126 * FT_integer fields that have a value_string attached will have the
13127 * matched string displayed on the expansion line.
13128 */
13129proto_item *
13130proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13131 const unsigned offset, const int hf_hdr,
13132 const int ett, int * const *fields,
13133 const unsigned encoding, uint64_t *retval)
13134{
13135 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);
13136}
13137
13138/* This function will dissect a sequence of bytes that describe a
13139 * bitmask.
13140 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13141 * to be dissected.
13142 * This field will form an expansion under which the individual fields of the
13143 * bitmask is dissected and displayed.
13144 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13145 *
13146 * fields is an array of pointers to int that lists all the fields of the
13147 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13148 * or another integer of the same type/size as hf_hdr with a mask specified.
13149 * This array is terminated by a NULL entry.
13150 *
13151 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13152 * FT_integer fields that have a value_string attached will have the
13153 * matched string displayed on the expansion line.
13154 */
13155proto_item *
13156proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13157 const unsigned offset, const int hf_hdr,
13158 const int ett, int * const *fields,
13159 const unsigned encoding)
13160{
13161 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13162}
13163
13164/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13165 * what data is appended to the header.
13166 */
13167proto_item *
13168proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13169 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13170 uint64_t *retval)
13171{
13172 proto_item *item = NULL((void*)0);
13173 header_field_info *hf;
13174 int len;
13175 uint64_t value;
13176
13177 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", 13177, __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", 13177
, "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", 13177, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13178 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", 13178, (hf)->abbrev)))
;
13179 len = ftype_wire_size(hf->type);
13180 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13181
13182 if (parent_tree) {
13183 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13184 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13185 flags, false0, false0, NULL((void*)0), value);
13186 }
13187
13188 *retval = value;
13189 if (hf->bitmask) {
13190 /* Mask out irrelevant portions */
13191 *retval &= hf->bitmask;
13192 /* Shift bits */
13193 *retval >>= hfinfo_bitshift(hf);
13194 }
13195
13196 return item;
13197}
13198
13199/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13200 * what data is appended to the header.
13201 */
13202proto_item *
13203proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13204 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13205{
13206 proto_item *item = NULL((void*)0);
13207 header_field_info *hf;
13208 int len;
13209 uint64_t value;
13210
13211 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", 13211, __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", 13211
, "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", 13211, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13212 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", 13212, (hf)->abbrev)))
;
13213
13214 if (parent_tree) {
13215 len = ftype_wire_size(hf->type);
13216 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13217 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13218 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13219 flags, false0, false0, NULL((void*)0), value);
13220 }
13221
13222 return item;
13223}
13224
13225/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13226 can't be retrieved directly from tvb) */
13227proto_item *
13228proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13229 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13230{
13231 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13232 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13233}
13234
13235/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13236WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13237proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13238 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13239{
13240 proto_item *item = NULL((void*)0);
13241 header_field_info *hf;
13242 int len;
13243
13244 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", 13244, __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", 13244
, "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", 13244, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13245 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", 13245, (hf)->abbrev)))
;
13246 /* the proto_tree_add_uint/_uint64() calls below
13247 will fail if tvb==NULL and len!=0 */
13248 len = tvb ? ftype_wire_size(hf->type) : 0;
13249
13250 if (parent_tree) {
13251 if (len <= 4)
13252 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13253 else
13254 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13255
13256 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13257 flags, false0, false0, NULL((void*)0), value);
13258 }
13259
13260 return item;
13261}
13262
13263/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13264void
13265proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13266 const int len, int * const *fields, const unsigned encoding)
13267{
13268 uint64_t value;
13269
13270 if (tree) {
13271 value = get_uint64_value(tree, tvb, offset, len, encoding);
13272 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13273 BMT_NO_APPEND0x01, false0, true1, tree, value);
13274 }
13275}
13276
13277WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13278proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13279 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13280{
13281 uint64_t value;
13282
13283 value = get_uint64_value(tree, tvb, offset, len, encoding);
13284 if (tree) {
13285 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13286 BMT_NO_APPEND0x01, false0, true1, tree, value);
13287 }
13288 if (retval) {
13289 *retval = value;
13290 }
13291}
13292
13293WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13294proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13295 const int len, int * const *fields, const uint64_t value)
13296{
13297 if (tree) {
13298 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13299 BMT_NO_APPEND0x01, false0, true1, tree, value);
13300 }
13301}
13302
13303
13304/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13305 * This is intended to support bitmask fields whose lengths can vary, perhaps
13306 * as the underlying standard evolves over time.
13307 * With this API there is the possibility of being called to display more or
13308 * less data than the dissector was coded to support.
13309 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13310 * Thus when presented with "too much" or "too little" data, MSbits will be
13311 * ignored or MSfields sacrificed.
13312 *
13313 * Only fields for which all defined bits are available are displayed.
13314 */
13315proto_item *
13316proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13317 const unsigned offset, const unsigned len, const int hf_hdr,
13318 const int ett, int * const *fields, struct expert_field* exp,
13319 const unsigned encoding)
13320{
13321 proto_item *item = NULL((void*)0);
13322 header_field_info *hf;
13323 unsigned decodable_len;
13324 unsigned decodable_offset;
13325 uint32_t decodable_value;
13326 uint64_t value;
13327
13328 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", 13328, __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", 13328
, "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", 13328, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13329 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", 13329, (hf)->abbrev)))
;
13330
13331 decodable_offset = offset;
13332 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13333
13334 /* If we are ftype_wire_size-limited,
13335 * make sure we decode as many LSBs as possible.
13336 */
13337 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13338 decodable_offset += (len - decodable_len);
13339 }
13340
13341 if (parent_tree) {
13342 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13343 decodable_len, encoding);
13344
13345 /* The root item covers all the bytes even if we can't decode them all */
13346 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13347 decodable_value);
13348 }
13349
13350 if (decodable_len < len) {
13351 /* Dissector likely requires updating for new protocol revision */
13352 expert_add_info_format(NULL((void*)0), item, exp,
13353 "Only least-significant %d of %d bytes decoded",
13354 decodable_len, len);
13355 }
13356
13357 if (item) {
13358 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13359 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13360 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13361 }
13362
13363 return item;
13364}
13365
13366/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13367proto_item *
13368proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13369 const unsigned offset, const unsigned len,
13370 const char *name, const char *fallback,
13371 const int ett, int * const *fields,
13372 const unsigned encoding, const int flags)
13373{
13374 proto_item *item = NULL((void*)0);
13375 uint64_t value;
13376
13377 if (parent_tree) {
13378 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13379 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13380 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13381 flags, true1, false0, NULL((void*)0), value) && fallback) {
13382 /* Still at first item - append 'fallback' text if any */
13383 proto_item_append_text(item, "%s", fallback);
13384 }
13385 }
13386
13387 return item;
13388}
13389
13390proto_item *
13391proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13392 const unsigned bit_offset, const int no_of_bits,
13393 const unsigned encoding)
13394{
13395 header_field_info *hfinfo;
13396 int octet_length;
13397 int octet_offset;
13398
13399 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", 13399, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13399
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13399, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13400
13401 if (no_of_bits < 0) {
13402 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13403 }
13404 octet_length = (no_of_bits + 7) >> 3;
13405 octet_offset = bit_offset >> 3;
13406 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13407
13408 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13409 * but only after doing a bunch more work (which we can, in the common
13410 * case, shortcut here).
13411 */
13412 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13413 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", 13413
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13413, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13413, "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", 13413, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13414
13415 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13416}
13417
13418/*
13419 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13420 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13421 * Offset should be given in bits from the start of the tvb.
13422 */
13423
13424static proto_item *
13425_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13426 const unsigned bit_offset, const int no_of_bits,
13427 uint64_t *return_value, const unsigned encoding)
13428{
13429 int offset;
13430 unsigned length;
13431 uint8_t tot_no_bits;
13432 char *bf_str;
13433 char lbl_str[ITEM_LABEL_LENGTH240];
13434 uint64_t value = 0;
13435 uint8_t *bytes = NULL((void*)0);
13436 size_t bytes_length = 0;
13437
13438 proto_item *pi;
13439 header_field_info *hf_field;
13440
13441 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13442 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", 13442, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13442
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13442, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13443
13444 if (hf_field->bitmask != 0) {
13445 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)
13446 " 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)
13447 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)
;
13448 }
13449
13450 if (no_of_bits < 0) {
13451 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13452 } else if (no_of_bits == 0) {
13453 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)
13454 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)
;
13455 }
13456
13457 /* Byte align offset */
13458 offset = bit_offset>>3;
13459
13460 /*
13461 * Calculate the number of octets used to hold the bits
13462 */
13463 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13464 length = (tot_no_bits + 7) >> 3;
13465
13466 if (no_of_bits < 65) {
13467 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13468 } else if (hf_field->type != FT_BYTES) {
13469 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)
13470 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)
;
13471 return NULL((void*)0);
13472 }
13473
13474 /* Sign extend for signed types */
13475 switch (hf_field->type) {
13476 case FT_INT8:
13477 case FT_INT16:
13478 case FT_INT24:
13479 case FT_INT32:
13480 case FT_INT40:
13481 case FT_INT48:
13482 case FT_INT56:
13483 case FT_INT64:
13484 value = ws_sign_ext64(value, no_of_bits);
13485 break;
13486
13487 default:
13488 break;
13489 }
13490
13491 if (return_value) {
13492 *return_value = value;
13493 }
13494
13495 /* Coast clear. Try and fake it */
13496 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13497 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", 13497
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13497, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13497, "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", 13497, __func__, "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); } } }
;
13498
13499 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13500
13501 switch (hf_field->type) {
13502 case FT_BOOLEAN:
13503 /* Boolean field */
13504 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13505 "%s = %s: %s",
13506 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13507 break;
13508
13509 case FT_CHAR:
13510 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13511 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13512 break;
13513
13514 case FT_UINT8:
13515 case FT_UINT16:
13516 case FT_UINT24:
13517 case FT_UINT32:
13518 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13519 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13520 break;
13521
13522 case FT_INT8:
13523 case FT_INT16:
13524 case FT_INT24:
13525 case FT_INT32:
13526 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13527 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13528 break;
13529
13530 case FT_UINT40:
13531 case FT_UINT48:
13532 case FT_UINT56:
13533 case FT_UINT64:
13534 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13535 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13536 break;
13537
13538 case FT_INT40:
13539 case FT_INT48:
13540 case FT_INT56:
13541 case FT_INT64:
13542 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13543 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13544 break;
13545
13546 case FT_BYTES:
13547 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13548 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13549 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13550 proto_item_set_text(pi, "%s", lbl_str);
13551 return pi;
13552
13553 /* TODO: should handle FT_UINT_BYTES ? */
13554
13555 default:
13556 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))
13557 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))
13558 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))
13559 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))
;
13560 return NULL((void*)0);
13561 }
13562
13563 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13564 return pi;
13565}
13566
13567proto_item *
13568proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13569 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13570 uint64_t *return_value)
13571{
13572 proto_item *pi;
13573 int no_of_bits;
13574 int octet_offset;
13575 unsigned mask_initial_bit_offset;
13576 unsigned mask_greatest_bit_offset;
13577 unsigned octet_length;
13578 uint8_t i;
13579 char bf_str[256];
13580 char lbl_str[ITEM_LABEL_LENGTH240];
13581 uint64_t value;
13582 uint64_t composite_bitmask;
13583 uint64_t composite_bitmap;
13584
13585 header_field_info *hf_field;
13586
13587 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13588 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", 13588, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13588
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13588, "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
13589
13590 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13591 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)
13592 " 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)
13593 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)
;
13594 }
13595
13596 mask_initial_bit_offset = bit_offset % 8;
13597
13598 no_of_bits = 0;
13599 value = 0;
13600 i = 0;
13601 mask_greatest_bit_offset = 0;
13602 composite_bitmask = 0;
13603 composite_bitmap = 0;
13604
13605 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
13606 uint64_t crumb_mask, crumb_value;
13607 uint8_t crumb_end_bit_offset;
13608
13609 crumb_value = tvb_get_bits64(tvb,
13610 bit_offset + crumb_spec[i].crumb_bit_offset,
13611 crumb_spec[i].crumb_bit_length,
13612 ENC_BIG_ENDIAN0x00000000);
13613 value += crumb_value;
13614 no_of_bits += crumb_spec[i].crumb_bit_length;
13615 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", 13615
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13616
13617 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13618 octet containing the initial offset.
13619 If the mask is beyond 32 bits, then give up on bit map display.
13620 This could be improved in future, probably showing a table
13621 of 32 or 64 bits per row */
13622 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13623 crumb_end_bit_offset = mask_initial_bit_offset
13624 + crumb_spec[i].crumb_bit_offset
13625 + crumb_spec[i].crumb_bit_length;
13626 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'
13627
13628 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13629 mask_greatest_bit_offset = crumb_end_bit_offset;
13630 }
13631 /* Currently the bitmap of the crumbs are only shown if
13632 * smaller than 32 bits. Do not bother calculating the
13633 * mask if it is larger than that. */
13634 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13635 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'
13636 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13637 }
13638 }
13639 /* Shift left for the next segment */
13640 value <<= crumb_spec[++i].crumb_bit_length;
13641 }
13642
13643 /* Sign extend for signed types */
13644 switch (hf_field->type) {
13645 case FT_INT8:
13646 case FT_INT16:
13647 case FT_INT24:
13648 case FT_INT32:
13649 case FT_INT40:
13650 case FT_INT48:
13651 case FT_INT56:
13652 case FT_INT64:
13653 value = ws_sign_ext64(value, no_of_bits);
13654 break;
13655 default:
13656 break;
13657 }
13658
13659 if (return_value) {
13660 *return_value = value;
13661 }
13662
13663 /* Coast clear. Try and fake it */
13664 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13665 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", 13665
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13665, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13665, "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", 13665, __func__, "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); } } }
;
13666
13667 /* initialise the format string */
13668 bf_str[0] = '\0';
13669
13670 octet_offset = bit_offset >> 3;
13671
13672 /* Round up mask length to nearest octet */
13673 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13674 mask_greatest_bit_offset = octet_length << 3;
13675
13676 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13677 It would be a useful enhancement to eliminate this restriction. */
13678 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13679 other_decode_bitfield_value(bf_str,
13680 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13681 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13682 mask_greatest_bit_offset);
13683 } else {
13684 /* If the bitmask is too large, try to describe its contents. */
13685 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13686 }
13687
13688 switch (hf_field->type) {
13689 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13690 /* Boolean field */
13691 return proto_tree_add_boolean_format(tree, hfindex,
13692 tvb, octet_offset, octet_length, value,
13693 "%s = %s: %s",
13694 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13695 break;
13696
13697 case FT_CHAR:
13698 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13699 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13700 break;
13701
13702 case FT_UINT8:
13703 case FT_UINT16:
13704 case FT_UINT24:
13705 case FT_UINT32:
13706 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13707 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13708 break;
13709
13710 case FT_INT8:
13711 case FT_INT16:
13712 case FT_INT24:
13713 case FT_INT32:
13714 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13715 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13716 break;
13717
13718 case FT_UINT40:
13719 case FT_UINT48:
13720 case FT_UINT56:
13721 case FT_UINT64:
13722 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13723 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13724 break;
13725
13726 case FT_INT40:
13727 case FT_INT48:
13728 case FT_INT56:
13729 case FT_INT64:
13730 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13731 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13732 break;
13733
13734 default:
13735 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))
13736 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))
13737 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))
13738 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))
;
13739 return NULL((void*)0);
13740 }
13741 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13742 return pi;
13743}
13744
13745void
13746proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13747 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13748{
13749 header_field_info *hfinfo;
13750 int start = bit_offset >> 3;
13751 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13752
13753 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13754 * so that we can use the tree's memory scope in calculating the string */
13755 if (length == -1) {
13756 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13757 } else {
13758 tvb_ensure_bytes_exist(tvb, start, length);
13759 }
13760 if (!tree) return;
13761
13762 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", 13762, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13762
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13762, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13763 proto_tree_add_text_internal(tree, tvb, start, length,
13764 "%s crumb %d of %s (decoded above)",
13765 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13766 tvb_get_bits32(tvb,
13767 bit_offset,
13768 crumb_spec[crumb_index].crumb_bit_length,
13769 ENC_BIG_ENDIAN0x00000000),
13770 ENC_BIG_ENDIAN0x00000000),
13771 crumb_index,
13772 hfinfo->name);
13773}
13774
13775proto_item *
13776proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13777 const unsigned bit_offset, const int no_of_bits,
13778 uint64_t *return_value, const unsigned encoding)
13779{
13780 proto_item *item;
13781
13782 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13783 bit_offset, no_of_bits,
13784 return_value, encoding))) {
13785 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)
;
13786 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)
;
13787 }
13788 return item;
13789}
13790
13791static proto_item *
13792_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13793 tvbuff_t *tvb, const unsigned bit_offset,
13794 const int no_of_bits, void *value_ptr,
13795 const unsigned encoding, char *value_str)
13796{
13797 int offset;
13798 unsigned length;
13799 uint8_t tot_no_bits;
13800 char *str;
13801 uint64_t value = 0;
13802 header_field_info *hf_field;
13803
13804 /* We do not have to return a value, try to fake it as soon as possible */
13805 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13806 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", 13806
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13806, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13806, "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", 13806, __func__, "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); } } }
;
13807
13808 if (hf_field->bitmask != 0) {
13809 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)
13810 " 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)
13811 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)
;
13812 }
13813
13814 if (no_of_bits < 0) {
13815 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13816 } else if (no_of_bits == 0) {
13817 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)
13818 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)
;
13819 }
13820
13821 /* Byte align offset */
13822 offset = bit_offset>>3;
13823
13824 /*
13825 * Calculate the number of octets used to hold the bits
13826 */
13827 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13828 length = tot_no_bits>>3;
13829 /* If we are using part of the next octet, increase length by 1 */
13830 if (tot_no_bits & 0x07)
13831 length++;
13832
13833 if (no_of_bits < 65) {
13834 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13835 } else {
13836 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)
13837 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)
;
13838 return NULL((void*)0);
13839 }
13840
13841 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13842
13843 (void) g_strlcat(str, " = ", 256+64);
13844 (void) g_strlcat(str, hf_field->name, 256+64);
13845
13846 /*
13847 * This function does not receive an actual value but a dimensionless pointer to that value.
13848 * For this reason, the type of the header field is examined in order to determine
13849 * what kind of value we should read from this address.
13850 * The caller of this function must make sure that for the specific header field type the address of
13851 * a compatible value is provided.
13852 */
13853 switch (hf_field->type) {
13854 case FT_BOOLEAN:
13855 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13856 "%s: %s", str, value_str);
13857 break;
13858
13859 case FT_CHAR:
13860 case FT_UINT8:
13861 case FT_UINT16:
13862 case FT_UINT24:
13863 case FT_UINT32:
13864 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13865 "%s: %s", str, value_str);
13866 break;
13867
13868 case FT_UINT40:
13869 case FT_UINT48:
13870 case FT_UINT56:
13871 case FT_UINT64:
13872 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13873 "%s: %s", str, value_str);
13874 break;
13875
13876 case FT_INT8:
13877 case FT_INT16:
13878 case FT_INT24:
13879 case FT_INT32:
13880 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13881 "%s: %s", str, value_str);
13882 break;
13883
13884 case FT_INT40:
13885 case FT_INT48:
13886 case FT_INT56:
13887 case FT_INT64:
13888 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13889 "%s: %s", str, value_str);
13890 break;
13891
13892 case FT_FLOAT:
13893 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13894 "%s: %s", str, value_str);
13895 break;
13896
13897 default:
13898 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))
13899 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))
13900 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))
13901 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))
;
13902 return NULL((void*)0);
13903 }
13904}
13905
13906static proto_item *
13907proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13908 tvbuff_t *tvb, const unsigned bit_offset,
13909 const int no_of_bits, void *value_ptr,
13910 const unsigned encoding, char *value_str)
13911{
13912 proto_item *item;
13913
13914 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13915 tvb, bit_offset, no_of_bits,
13916 value_ptr, encoding, value_str))) {
13917 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)
;
13918 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)
;
13919 }
13920 return item;
13921}
13922
13923#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);
\
13924 va_start(ap, format)__builtin_va_start(ap, format); \
13925 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13926 va_end(ap)__builtin_va_end(ap);
13927
13928proto_item *
13929proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13930 tvbuff_t *tvb, const unsigned bit_offset,
13931 const int no_of_bits, uint32_t value,
13932 const unsigned encoding,
13933 const char *format, ...)
13934{
13935 va_list ap;
13936 char *dst;
13937 header_field_info *hf_field;
13938
13939 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13940
13941 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", 13941
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13941, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13941, "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", 13941, __func__, "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); } } }
;
13942
13943 switch (hf_field->type) {
13944 case FT_UINT8:
13945 case FT_UINT16:
13946 case FT_UINT24:
13947 case FT_UINT32:
13948 break;
13949
13950 default:
13951 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)
13952 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)
;
13953 return NULL((void*)0);
13954 }
13955
13956 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);
;
13957
13958 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13959}
13960
13961proto_item *
13962proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13963 tvbuff_t *tvb, const unsigned bit_offset,
13964 const int no_of_bits, uint64_t value,
13965 const unsigned encoding,
13966 const char *format, ...)
13967{
13968 va_list ap;
13969 char *dst;
13970 header_field_info *hf_field;
13971
13972 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13973
13974 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", 13974
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13974, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13974, "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", 13974, __func__, "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); } } }
;
13975
13976 switch (hf_field->type) {
13977 case FT_UINT40:
13978 case FT_UINT48:
13979 case FT_UINT56:
13980 case FT_UINT64:
13981 break;
13982
13983 default:
13984 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)
13985 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)
;
13986 return NULL((void*)0);
13987 }
13988
13989 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);
;
13990
13991 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13992}
13993
13994proto_item *
13995proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13996 tvbuff_t *tvb, const unsigned bit_offset,
13997 const int no_of_bits, float value,
13998 const unsigned encoding,
13999 const char *format, ...)
14000{
14001 va_list ap;
14002 char *dst;
14003 header_field_info *hf_field;
14004
14005 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14006
14007 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", 14007
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14007, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14007, "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", 14007, __func__, "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); } } }
;
14008
14009 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",
14009, ((hf_field))->abbrev))))
;
14010
14011 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);
;
14012
14013 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14014}
14015
14016proto_item *
14017proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14018 tvbuff_t *tvb, const unsigned bit_offset,
14019 const int no_of_bits, int32_t value,
14020 const unsigned encoding,
14021 const char *format, ...)
14022{
14023 va_list ap;
14024 char *dst;
14025 header_field_info *hf_field;
14026
14027 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14028
14029 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", 14029
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14029, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14029, "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", 14029, __func__, "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); } } }
;
14030
14031 switch (hf_field->type) {
14032 case FT_INT8:
14033 case FT_INT16:
14034 case FT_INT24:
14035 case FT_INT32:
14036 break;
14037
14038 default:
14039 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)
14040 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)
;
14041 return NULL((void*)0);
14042 }
14043
14044 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);
;
14045
14046 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14047}
14048
14049proto_item *
14050proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14051 tvbuff_t *tvb, const unsigned bit_offset,
14052 const int no_of_bits, int64_t value,
14053 const unsigned encoding,
14054 const char *format, ...)
14055{
14056 va_list ap;
14057 char *dst;
14058 header_field_info *hf_field;
14059
14060 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14061
14062 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", 14062
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14062, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14062, "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", 14062, __func__, "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); } } }
;
14063
14064 switch (hf_field->type) {
14065 case FT_INT40:
14066 case FT_INT48:
14067 case FT_INT56:
14068 case FT_INT64:
14069 break;
14070
14071 default:
14072 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)
14073 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)
;
14074 return NULL((void*)0);
14075 }
14076
14077 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);
;
14078
14079 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14080}
14081
14082proto_item *
14083proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14084 tvbuff_t *tvb, const unsigned bit_offset,
14085 const int no_of_bits, uint64_t value,
14086 const unsigned encoding,
14087 const char *format, ...)
14088{
14089 va_list ap;
14090 char *dst;
14091 header_field_info *hf_field;
14092
14093 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14094
14095 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", 14095
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14095, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14095, "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", 14095, __func__, "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); } } }
;
14096
14097 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"
, 14097, ((hf_field))->abbrev))))
;
14098
14099 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);
;
14100
14101 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14102}
14103
14104proto_item *
14105proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14106 const unsigned bit_offset, const int no_of_chars)
14107{
14108 proto_item *pi;
14109 header_field_info *hfinfo;
14110 int byte_length;
14111 int byte_offset;
14112 char *string;
14113
14114 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14115
14116 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", 14116
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14116, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14116, "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", 14116, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14117
14118 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"
, 14118, ((hfinfo))->abbrev))))
;
14119
14120 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14121 byte_offset = bit_offset >> 3;
14122
14123 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14124
14125 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14126 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14126, "byte_length >= 0"
))))
;
14127 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14128
14129 return pi;
14130}
14131
14132proto_item *
14133proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14134 const unsigned bit_offset, const int no_of_chars)
14135{
14136 proto_item *pi;
14137 header_field_info *hfinfo;
14138 int byte_length;
14139 int byte_offset;
14140 char *string;
14141
14142 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14143
14144 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", 14144
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14144, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14144, "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", 14144, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14145
14146 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"
, 14146, ((hfinfo))->abbrev))))
;
14147
14148 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14149 byte_offset = bit_offset >> 3;
14150
14151 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14152
14153 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14154 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14154, "byte_length >= 0"
))))
;
14155 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14156
14157 return pi;
14158}
14159
14160const value_string proto_checksum_vals[] = {
14161 { PROTO_CHECKSUM_E_BAD, "Bad" },
14162 { PROTO_CHECKSUM_E_GOOD, "Good" },
14163 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14164 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14165 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14166
14167 { 0, NULL((void*)0) }
14168};
14169
14170#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14171
14172proto_item *
14173proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14174 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14175 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14176{
14177 header_field_info *hfinfo;
14178 uint32_t checksum;
14179 uint32_t len;
14180 proto_item* ti = NULL((void*)0);
14181 proto_item* ti2;
14182 bool_Bool incorrect_checksum = true1;
14183
14184 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", 14184, __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", 14184
, "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", 14184, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14185
14186 switch (hfinfo->type) {
14187 case FT_UINT8:
14188 len = 1;
14189 break;
14190 case FT_UINT16:
14191 len = 2;
14192 break;
14193 case FT_UINT24:
14194 len = 3;
14195 break;
14196 case FT_UINT32:
14197 len = 4;
14198 break;
14199 default:
14200 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)
14201 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14202 }
14203
14204 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14205 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14206 proto_item_set_generated(ti);
14207 // Backward compatible with use of -1
14208 if (hf_checksum_status > 0) {
14209 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14210 proto_item_set_generated(ti2);
14211 }
14212 return ti;
14213 }
14214
14215 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14216 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14217 proto_item_set_generated(ti);
14218 } else {
14219 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14220 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14221 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14222 if (computed_checksum == 0) {
14223 proto_item_append_text(ti, " [correct]");
14224 // Backward compatible with use of -1
14225 if (hf_checksum_status > 0) {
14226 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14227 proto_item_set_generated(ti2);
14228 }
14229 incorrect_checksum = false0;
14230 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14231 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14232 /* XXX - This can't distinguish between "shouldbe"
14233 * 0x0000 and 0xFFFF unless we know whether there
14234 * were any nonzero bits (other than the checksum).
14235 * Protocols should not use this path if they might
14236 * have an all zero packet.
14237 * Some implementations put the wrong zero; maybe
14238 * we should have a special expert info for that?
14239 */
14240 }
14241 } else {
14242 if (checksum == computed_checksum) {
14243 proto_item_append_text(ti, " [correct]");
14244 // Backward compatible with use of -1
14245 if (hf_checksum_status > 0) {
14246 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14247 proto_item_set_generated(ti2);
14248 }
14249 incorrect_checksum = false0;
14250 }
14251 }
14252
14253 if (incorrect_checksum) {
14254 // Backward compatible with use of -1
14255 if (hf_checksum_status > 0) {
14256 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14257 proto_item_set_generated(ti2);
14258 }
14259 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14260 proto_item_append_text(ti, " [incorrect]");
14261 if (bad_checksum_expert != NULL((void*)0))
14262 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14263 } else {
14264 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14265 if (bad_checksum_expert != NULL((void*)0))
14266 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);
14267 }
14268 }
14269 } else {
14270 // Backward compatible with use of -1
14271 if (hf_checksum_status > 0) {
14272 proto_item_append_text(ti, " [unverified]");
14273 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14274 proto_item_set_generated(ti2);
14275 }
14276 }
14277 }
14278
14279 return ti;
14280}
14281
14282proto_item *
14283proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14284 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14285 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14286{
14287 header_field_info *hfinfo;
14288 uint8_t *checksum = NULL((void*)0);
14289 proto_item* ti = NULL((void*)0);
14290 proto_item* ti2;
14291 bool_Bool incorrect_checksum = true1;
14292
14293 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", 14293, __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", 14293
, "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", 14293, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14294
14295 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",
14295, ((hfinfo))->abbrev))))
;
14296
14297 /* Make sure a NULL computed_checksum isn't dereferenced.
14298 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14299 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14300 * cases the behavior is unexpected and still a programmer error;
14301 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14302 * _NOT_PRESENT nor _GENERATED is correct.
14303 */
14304 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", 14304, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14305
14306 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14307 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14308 proto_item_set_generated(ti);
14309 // Backward compatible with use of -1
14310 if (hf_checksum_status > 0) {
14311 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14312 proto_item_set_generated(ti2);
14313 }
14314 return ti;
14315 }
14316
14317 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14318 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14319 proto_item_set_generated(ti);
14320 return ti;
14321 }
14322
14323 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14324 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14325 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14326 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14327 bool_Bool non_zero_flag = false0;
14328 for (size_t index = 0; index < checksum_len; index++) {
14329 if (computed_checksum[index]) {
14330 non_zero_flag = true1;
14331 break;
14332 }
14333 }
14334 if (!non_zero_flag) {
14335 proto_item_append_text(ti, " [correct]");
14336 // Backward compatible with use of -1
14337 if (hf_checksum_status > 0) {
14338 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14339 proto_item_set_generated(ti2);
14340 }
14341 incorrect_checksum = false0;
14342 }
14343 } else {
14344 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14345 proto_item_append_text(ti, " [correct]");
14346 // Backward compatible with use of -1
14347 if (hf_checksum_status > 0) {
14348 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14349 proto_item_set_generated(ti2);
14350 }
14351 incorrect_checksum = false0;
14352 }
14353 }
14354
14355 if (incorrect_checksum) {
14356 // Backward compatible with use of -1
14357 if (hf_checksum_status > 0) {
14358 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14359 proto_item_set_generated(ti2);
14360 }
14361 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14362 proto_item_append_text(ti, " [incorrect]");
14363 if (bad_checksum_expert != NULL((void*)0))
14364 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14365 } else {
14366 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14367 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14368 if (bad_checksum_expert != NULL((void*)0))
14369 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14370 }
14371 }
14372 } else {
14373 // Backward compatible with use of -1
14374 if (hf_checksum_status > 0) {
14375 proto_item_append_text(ti, " [unverified]");
14376 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14377 proto_item_set_generated(ti2);
14378 }
14379 }
14380
14381 return ti;
14382}
14383
14384unsigned char
14385proto_check_field_name(const char *field_name)
14386{
14387 return module_check_valid_name(field_name, false0);
14388}
14389
14390unsigned char
14391proto_check_field_name_lower(const char *field_name)
14392{
14393 return module_check_valid_name(field_name, true1);
14394}
14395
14396bool_Bool
14397tree_expanded(int tree_type)
14398{
14399 if (tree_type <= 0) {
14400 return false0;
14401 }
14402 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", 14402, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14403 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14404}
14405
14406void
14407tree_expanded_set(int tree_type, bool_Bool value)
14408{
14409 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", 14409, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14410
14411 if (value)
14412 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14413 else
14414 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14415}
14416
14417/*
14418 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14419 *
14420 * Local variables:
14421 * c-basic-offset: 8
14422 * tab-width: 8
14423 * indent-tabs-mode: t
14424 * End:
14425 *
14426 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14427 * :indentSize=8:tabSize=8:noTabs=false:
14428 */