Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13633, 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-01-25-100340-3605-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;
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))
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 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7316 } else {
7317 number_out = hf_try_val_to_str(number, hfinfo);
7318
7319 if (!number_out) {
7320 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7321 }
7322
7323 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7324 }
7325 } else {
7326 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7327
7328 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7329 }
7330
7331 break;
7332
7333 case FT_INT40:
7334 case FT_INT48:
7335 case FT_INT56:
7336 case FT_INT64:
7337 case FT_UINT40:
7338 case FT_UINT48:
7339 case FT_UINT56:
7340 case FT_UINT64:
7341 hf_str_val = NULL((void*)0);
7342 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
))
?
7343 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7344 fvalue_get_uinteger64(finfo->value);
7345
7346 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7347 char tmp[ITEM_LABEL_LENGTH240];
7348 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7349
7350 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7350, "fmtfunc64"
))))
;
7351 fmtfunc64(tmp, number64);
7352
7353 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7354 } else if (hfinfo->strings) {
7355 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7356 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7357 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7358 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7359 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7360 } else {
7361 number_out = hf_try_val64_to_str(number64, hfinfo);
7362
7363 if (!number_out)
7364 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7365
7366 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7367 }
7368 } else {
7369 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7370
7371 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7372 }
7373
7374 break;
7375
7376 case FT_EUI64:
7377 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7378 tmp_str = address_to_display(NULL((void*)0), &addr);
7379 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7380 wmem_free(NULL((void*)0), tmp_str);
7381 break;
7382
7383 case FT_IPv4:
7384 ipv4 = fvalue_get_ipv4(finfo->value);
7385 //XXX: Should we ignore the mask?
7386 set_address_ipv4(&addr, ipv4);
7387 tmp_str = address_to_display(NULL((void*)0), &addr);
7388 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7389 wmem_free(NULL((void*)0), tmp_str);
7390 free_address(&addr);
7391 break;
7392
7393 case FT_IPv6:
7394 ipv6 = fvalue_get_ipv6(finfo->value);
7395 set_address_ipv6(&addr, ipv6);
7396 tmp_str = address_to_display(NULL((void*)0), &addr);
7397 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7398 wmem_free(NULL((void*)0), tmp_str);
7399 free_address(&addr);
7400 break;
7401
7402 case FT_FCWWN:
7403 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7404 tmp_str = address_to_display(NULL((void*)0), &addr);
7405 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7406 wmem_free(NULL((void*)0), tmp_str);
7407 break;
7408
7409 case FT_ETHER:
7410 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7411 tmp_str = address_to_display(NULL((void*)0), &addr);
7412 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7413 wmem_free(NULL((void*)0), tmp_str);
7414 break;
7415
7416 case FT_GUID:
7417 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7418 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7419 wmem_free(NULL((void*)0), tmp_str);
7420 break;
7421
7422 case FT_REL_OID:
7423 bytes = fvalue_get_bytes_data(finfo->value);
7424 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7425 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7426 wmem_free(NULL((void*)0), tmp_str);
7427 break;
7428
7429 case FT_OID:
7430 bytes = fvalue_get_bytes_data(finfo->value);
7431 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7432 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7433 wmem_free(NULL((void*)0), tmp_str);
7434 break;
7435
7436 case FT_SYSTEM_ID:
7437 bytes = fvalue_get_bytes_data(finfo->value);
7438 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7439 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7440 wmem_free(NULL((void*)0), tmp_str);
7441 break;
7442
7443 case FT_FLOAT:
7444 case FT_DOUBLE:
7445 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7446 break;
7447
7448 case FT_IEEE_11073_SFLOAT:
7449 case FT_IEEE_11073_FLOAT:
7450 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7451 break;
7452
7453 case FT_STRING:
7454 case FT_STRINGZ:
7455 case FT_UINT_STRING:
7456 case FT_STRINGZPAD:
7457 case FT_STRINGZTRUNC:
7458 str = fvalue_get_string(finfo->value);
7459 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7460 if (label_len >= label_str_size) {
7461 /* Truncation occurred. Get the real length
7462 * copied (not including '\0') */
7463 label_len = label_str_size ? label_str_size - 1 : 0;
7464 }
7465 break;
7466
7467 default:
7468 /* First try ftype string representation */
7469 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7470 if (!tmp_str) {
7471 /* Default to show as bytes */
7472 bytes = fvalue_get_bytes_data(finfo->value);
7473 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7474 }
7475 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7476 wmem_free(NULL((void*)0), tmp_str);
7477 break;
7478 }
7479 return label_len;
7480}
7481
7482const char *
7483proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7484 char *result, char *expr, const int size)
7485{
7486 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7487 GPtrArray *finfos;
7488 field_info *finfo = NULL((void*)0);
7489 header_field_info* hfinfo;
7490 const char *abbrev = NULL((void*)0);
7491
7492 char *str;
7493 col_custom_t *field_idx;
7494 int field_id;
7495 int ii = 0;
7496
7497 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7497, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7498 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7499 field_id = field_idx->field_id;
7500 if (field_id == 0) {
7501 GPtrArray *fvals = NULL((void*)0);
7502 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7503 if (fvals != NULL((void*)0)) {
7504
7505 // XXX - Handling occurrences is unusual when more
7506 // than one field is involved, e.g. there's four
7507 // results for tcp.port + tcp.port. We may really
7508 // want to apply it to the operands, not the output.
7509 // Note that occurrences are not quite the same as
7510 // the layer operator (should the grammar support
7511 // both?)
7512 /* Calculate single index or set outer boundaries */
7513 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7514 if (occurrence < 0) {
7515 i = occurrence + len;
7516 last = i;
7517 } else if (occurrence > 0) {
7518 i = occurrence - 1;
7519 last = i;
7520 } else {
7521 i = 0;
7522 last = len - 1;
7523 }
7524 if (i < 0 || i >= len) {
7525 g_ptr_array_unref(fvals);
7526 continue;
7527 }
7528 for (; i <= last; i++) {
7529 /* XXX - We could have a "resolved" result
7530 * for types where the value depends only
7531 * on the type, e.g. FT_IPv4, and not on
7532 * hfinfo->strings. Supporting the latter
7533 * requires knowing which hfinfo matched
7534 * if there are multiple with the same
7535 * abbreviation. In any case, we need to
7536 * know the expected return type of the
7537 * field expression.
7538 */
7539 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7540 if (offset_r && (offset_r < (size - 1)))
7541 result[offset_r++] = ',';
7542 if (offset_e && (offset_e < (size - 1)))
7543 expr[offset_e++] = ',';
7544 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7545 // col_{add,append,set}_* calls ws_label_strcpy
7546 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7547
7548 g_free(str);
7549 }
7550 g_ptr_array_unref(fvals);
7551 } else if (passed) {
7552 // XXX - Occurrence doesn't make sense for a test
7553 // output, it should be applied to the operands.
7554 if (offset_r && (offset_r < (size - 1)))
7555 result[offset_r++] = ',';
7556 if (offset_e && (offset_e < (size - 1)))
7557 expr[offset_e++] = ',';
7558 /* Prevent multiple check marks */
7559 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7560 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7561 } else {
7562 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7563 }
7564 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7565 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7566 } else {
7567 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7568 }
7569 }
7570 continue;
7571 }
7572 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", 7572
, __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", 7572,
"(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", 7572,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7573
7574 /* do we need to rewind ? */
7575 if (!hfinfo)
7576 return "";
7577
7578 if (occurrence < 0) {
7579 /* Search other direction */
7580 while (hfinfo->same_name_prev_id != -1) {
7581 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", 7581
, __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", 7581, "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", 7581,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7582 }
7583 }
7584
7585 prev_len = 0; /* Reset handled occurrences */
7586
7587 while (hfinfo) {
7588 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7589
7590 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7591 if (occurrence < 0) {
7592 hfinfo = hfinfo->same_name_next;
7593 } else {
7594 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7595 }
7596 continue;
7597 }
7598
7599 /* Are there enough occurrences of the field? */
7600 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7601 if (occurrence < 0) {
7602 hfinfo = hfinfo->same_name_next;
7603 } else {
7604 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7605 }
7606 prev_len += len;
7607 continue;
7608 }
7609
7610 /* Calculate single index or set outer boundaries */
7611 if (occurrence < 0) {
7612 i = occurrence + len + prev_len;
7613 last = i;
7614 } else if (occurrence > 0) {
7615 i = occurrence - 1 - prev_len;
7616 last = i;
7617 } else {
7618 i = 0;
7619 last = len - 1;
7620 }
7621
7622 prev_len += len; /* Count handled occurrences */
7623
7624 while (i <= last) {
7625 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7626
7627 if (offset_r && (offset_r < (size - 1)))
7628 result[offset_r++] = ',';
7629
7630 if (display_details) {
7631 char representation[ITEM_LABEL_LENGTH240];
7632 size_t offset = 0;
7633
7634 if (finfo->rep && finfo->rep->value_len) {
7635 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7636 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7637 } else {
7638 proto_item_fill_label(finfo, representation, &offset);
7639 }
7640 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7641 } else {
7642 switch (hfinfo->type) {
7643
7644 case FT_NONE:
7645 case FT_PROTOCOL:
7646 /* Prevent multiple check marks */
7647 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7648 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7649 } else {
7650 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7651 }
7652 break;
7653
7654 default:
7655 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7656 break;
7657 }
7658 }
7659
7660 if (offset_e && (offset_e < (size - 1)))
7661 expr[offset_e++] = ',';
7662
7663 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
))
)) {
7664 const char *hf_str_val;
7665 /* Integer types with BASE_NONE never get the numeric value. */
7666 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7667 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7668 } 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
)
) {
7669 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7670 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7671 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7672 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7673 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7674 }
7675 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7676 offset_e = (int)strlen(expr);
7677 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7678 /* Prevent multiple check marks */
7679 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7680 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7681 } else {
7682 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7683 }
7684 } else {
7685 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7686 // col_{add,append,set}_* calls ws_label_strcpy
7687 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7688 wmem_free(NULL((void*)0), str);
7689 }
7690 i++;
7691 }
7692
7693 /* XXX: Why is only the first abbreviation returned for a multifield
7694 * custom column? */
7695 if (!abbrev) {
7696 /* Store abbrev for return value */
7697 abbrev = hfinfo->abbrev;
7698 }
7699
7700 if (occurrence == 0) {
7701 /* Fetch next hfinfo with same name (abbrev) */
7702 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7703 } else {
7704 hfinfo = NULL((void*)0);
7705 }
7706 }
7707 }
7708
7709 if (offset_r >= (size - 1)) {
7710 mark_truncated(result, 0, size, NULL((void*)0));
7711 }
7712 if (offset_e >= (size - 1)) {
7713 mark_truncated(expr, 0, size, NULL((void*)0));
7714 }
7715 return abbrev ? abbrev : "";
7716}
7717
7718char *
7719proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7720{
7721 int len, prev_len, last, i;
7722 GPtrArray *finfos;
7723 field_info *finfo = NULL((void*)0);
7724 header_field_info* hfinfo;
7725
7726 char *filter = NULL((void*)0);
7727 GPtrArray *filter_array;
7728
7729 col_custom_t *col_custom;
7730 int field_id;
7731
7732 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7732, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7733 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7734 for (GSList *iter = field_ids; iter; iter = iter->next) {
7735 col_custom = (col_custom_t*)iter->data;
7736 field_id = col_custom->field_id;
7737 if (field_id == 0) {
7738 GPtrArray *fvals = NULL((void*)0);
7739 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7740 if (fvals != NULL((void*)0)) {
7741 // XXX - Handling occurrences is unusual when more
7742 // than one field is involved, e.g. there's four
7743 // results for tcp.port + tcp.port. We really
7744 // want to apply it to the operands, not the output.
7745 /* Calculate single index or set outer boundaries */
7746 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7747 if (occurrence < 0) {
7748 i = occurrence + len;
7749 last = i;
7750 } else if (occurrence > 0) {
7751 i = occurrence - 1;
7752 last = i;
7753 } else {
7754 i = 0;
7755 last = len - 1;
7756 }
7757 if (i < 0 || i >= len) {
7758 g_ptr_array_unref(fvals);
7759 continue;
7760 }
7761 for (; i <= last; i++) {
7762 /* XXX - Should multiple values for one
7763 * field use set membership to reduce
7764 * verbosity, here and below? */
7765 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7766 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7767 wmem_free(NULL((void*)0), str);
7768 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7769 g_ptr_array_add(filter_array, filter);
7770 }
7771 }
7772 g_ptr_array_unref(fvals);
7773 } else if (passed) {
7774 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7775 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7776 g_ptr_array_add(filter_array, filter);
7777 }
7778 } else {
7779 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7780 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7781 g_ptr_array_add(filter_array, filter);
7782 }
7783 }
7784 continue;
7785 }
7786
7787 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", 7787
, __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", 7787,
"(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", 7787,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7788
7789 /* do we need to rewind ? */
7790 if (!hfinfo)
7791 return NULL((void*)0);
7792
7793 if (occurrence < 0) {
7794 /* Search other direction */
7795 while (hfinfo->same_name_prev_id != -1) {
7796 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", 7796
, __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", 7796, "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", 7796,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7797 }
7798 }
7799
7800 prev_len = 0; /* Reset handled occurrences */
7801
7802 while (hfinfo) {
7803 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7804
7805 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7806 if (occurrence < 0) {
7807 hfinfo = hfinfo->same_name_next;
7808 } else {
7809 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7810 }
7811 continue;
7812 }
7813
7814 /* Are there enough occurrences of the field? */
7815 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7816 if (occurrence < 0) {
7817 hfinfo = hfinfo->same_name_next;
7818 } else {
7819 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7820 }
7821 prev_len += len;
7822 continue;
7823 }
7824
7825 /* Calculate single index or set outer boundaries */
7826 if (occurrence < 0) {
7827 i = occurrence + len + prev_len;
7828 last = i;
7829 } else if (occurrence > 0) {
7830 i = occurrence - 1 - prev_len;
7831 last = i;
7832 } else {
7833 i = 0;
7834 last = len - 1;
7835 }
7836
7837 prev_len += len; /* Count handled occurrences */
7838
7839 while (i <= last) {
7840 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7841
7842 filter = proto_construct_match_selected_string(finfo, edt);
7843 if (filter) {
7844 /* Only add the same expression once (especially for FT_PROTOCOL).
7845 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7846 */
7847 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7848 g_ptr_array_add(filter_array, filter);
7849 }
7850 }
7851 i++;
7852 }
7853
7854 if (occurrence == 0) {
7855 /* Fetch next hfinfo with same name (abbrev) */
7856 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7857 } else {
7858 hfinfo = NULL((void*)0);
7859 }
7860 }
7861 }
7862
7863 g_ptr_array_add(filter_array, NULL((void*)0));
7864
7865 /* XXX: Should this be || or && ? */
7866 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7867
7868 g_ptr_array_free(filter_array, true1);
7869
7870 return output;
7871}
7872
7873/* Set text of proto_item after having already been created. */
7874void
7875proto_item_set_text(proto_item *pi, const char *format, ...)
7876{
7877 field_info *fi = NULL((void*)0);
7878 va_list ap;
7879
7880 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7881
7882 fi = PITEM_FINFO(pi)((pi)->finfo);
7883 if (fi == NULL((void*)0))
7884 return;
7885
7886 if (fi->rep) {
7887 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7888 fi->rep = NULL((void*)0);
7889 }
7890
7891 va_start(ap, format)__builtin_va_start(ap, format);
7892 proto_tree_set_representation(pi, format, ap);
7893 va_end(ap)__builtin_va_end(ap);
7894}
7895
7896/* Append to text of proto_item after having already been created. */
7897void
7898proto_item_append_text(proto_item *pi, const char *format, ...)
7899{
7900 field_info *fi = NULL((void*)0);
7901 size_t curlen;
7902 char *str;
7903 va_list ap;
7904
7905 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7906
7907 fi = PITEM_FINFO(pi)((pi)->finfo);
7908 if (fi == NULL((void*)0)) {
7909 return;
7910 }
7911
7912 if (!proto_item_is_hidden(pi)) {
7913 /*
7914 * If we don't already have a representation,
7915 * generate the default representation.
7916 */
7917 if (fi->rep == NULL((void*)0)) {
7918 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;
;
7919 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7920 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7921 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7922 (strncmp(format, ": ", 2) == 0)) {
7923 fi->rep->value_pos += 2;
7924 }
7925 }
7926 if (fi->rep) {
7927 curlen = strlen(fi->rep->representation);
7928 /* curlen doesn't include the \0 byte.
7929 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7930 * the representation has already been truncated (of an up
7931 * to 4 byte UTF-8 character) or is just at the maximum length
7932 * unless we search for " [truncated]" (which may not be
7933 * at the start.)
7934 * It's safer to do nothing.
7935 */
7936 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7937 va_start(ap, format)__builtin_va_start(ap, format);
7938 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7939 va_end(ap)__builtin_va_end(ap);
7940 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"
, 7940, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7941 /* Keep fi->rep->value_pos */
7942 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7943 if (curlen >= ITEM_LABEL_LENGTH240) {
7944 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7945 size_t name_pos = label_find_name_pos(fi->rep);
7946 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7947 }
7948 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7949 }
7950 }
7951 }
7952}
7953
7954/* Prepend to text of proto_item after having already been created. */
7955void
7956proto_item_prepend_text(proto_item *pi, const char *format, ...)
7957{
7958 field_info *fi = NULL((void*)0);
7959 size_t pos;
7960 char representation[ITEM_LABEL_LENGTH240];
7961 char *str;
7962 va_list ap;
7963
7964 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7965
7966 fi = PITEM_FINFO(pi)((pi)->finfo);
7967 if (fi == NULL((void*)0)) {
7968 return;
7969 }
7970
7971 if (!proto_item_is_hidden(pi)) {
7972 /*
7973 * If we don't already have a representation,
7974 * generate the default representation.
7975 */
7976 if (fi->rep == NULL((void*)0)) {
7977 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;
;
7978 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7979 } else
7980 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7981
7982 va_start(ap, format)__builtin_va_start(ap, format);
7983 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7984 va_end(ap)__builtin_va_end(ap);
7985 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"
, 7985, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7986 fi->rep->value_pos += strlen(str);
7987 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7988 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7989 /* XXX: As above, if the old representation is close to the label
7990 * length, it might already be marked as truncated. */
7991 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7992 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7993 size_t name_pos = label_find_name_pos(fi->rep);
7994 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7995 }
7996 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7997 }
7998}
7999
8000static void
8001finfo_set_len(field_info *fi, const int length)
8002{
8003 int length_remaining;
8004
8005 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", 8005,
"length >= 0", fi->hfinfo->abbrev))))
;
8006 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
8007 if (length > length_remaining)
8008 fi->length = length_remaining;
8009 else
8010 fi->length = length;
8011
8012 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8013 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8014 fvalue_set_protocol_length(fi->value, fi->length);
8015 }
8016
8017 /*
8018 * You cannot just make the "len" field of a GByteArray
8019 * larger, if there's no data to back that length;
8020 * you can only make it smaller.
8021 */
8022 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8023 GBytes *bytes = fvalue_get_bytes(fi->value);
8024 size_t size;
8025 const void *data = g_bytes_get_data(bytes, &size);
8026 if ((size_t)fi->length <= size) {
8027 fvalue_set_bytes_data(fi->value, data, fi->length);
8028 }
8029 g_bytes_unref(bytes);
8030 }
8031}
8032
8033void
8034proto_item_set_len(proto_item *pi, const int length)
8035{
8036 field_info *fi;
8037
8038 if (pi == NULL((void*)0))
8039 return;
8040
8041 fi = PITEM_FINFO(pi)((pi)->finfo);
8042 if (fi == NULL((void*)0))
8043 return;
8044
8045 finfo_set_len(fi, length);
8046}
8047
8048/*
8049 * Sets the length of the item based on its start and on the specified
8050 * offset, which is the offset past the end of the item; as the start
8051 * in the item is relative to the beginning of the data source tvbuff,
8052 * we need to pass in a tvbuff - the end offset is relative to the beginning
8053 * of that tvbuff.
8054 */
8055void
8056proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8057{
8058 field_info *fi;
8059 int length;
8060
8061 if (pi == NULL((void*)0))
8062 return;
8063
8064 fi = PITEM_FINFO(pi)((pi)->finfo);
8065 if (fi == NULL((void*)0))
8066 return;
8067
8068 end += tvb_raw_offset(tvb);
8069 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8069, "end >= fi->start"
))))
;
8070 length = end - fi->start;
8071
8072 finfo_set_len(fi, length);
8073}
8074
8075int
8076proto_item_get_len(const proto_item *pi)
8077{
8078 field_info *fi;
8079
8080 if (!pi)
8081 return -1;
8082 fi = PITEM_FINFO(pi)((pi)->finfo);
8083 if (fi) {
8084 return fi->length;
8085 }
8086 return -1;
8087}
8088
8089void
8090proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8091 if (!ti) {
8092 return;
8093 }
8094 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)
;
8095 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)
;
8096}
8097
8098char *
8099proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8100{
8101 field_info *fi;
8102
8103 if (!pi)
8104 return wmem_strdup(scope, "");
8105 fi = PITEM_FINFO(pi)((pi)->finfo);
8106 if (!fi)
8107 return wmem_strdup(scope, "");
8108 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8108, "fi->hfinfo != ((void*)0)"
))))
;
8109 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8110}
8111
8112proto_tree *
8113proto_tree_create_root(packet_info *pinfo)
8114{
8115 proto_node *pnode;
8116
8117 /* Initialize the proto_node */
8118 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8119 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8120 pnode->parent = NULL((void*)0);
8121 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8122 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8123
8124 /* Make sure we can access pinfo everywhere */
8125 pnode->tree_data->pinfo = pinfo;
8126
8127 /* Don't initialize the tree_data_t. Wait until we know we need it */
8128 pnode->tree_data->interesting_hfids = NULL((void*)0);
8129
8130 /* Set the default to false so it's easier to
8131 * find errors; if we expect to see the protocol tree
8132 * but for some reason the default 'visible' is not
8133 * changed, then we'll find out very quickly. */
8134 pnode->tree_data->visible = false0;
8135
8136 /* Make sure that we fake protocols (if possible) */
8137 pnode->tree_data->fake_protocols = true1;
8138
8139 /* Keep track of the number of children */
8140 pnode->tree_data->count = 0;
8141
8142 /* Initialize our loop checks */
8143 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8144 pnode->tree_data->max_start = 0;
8145 pnode->tree_data->start_idle_count = 0;
8146
8147 return (proto_tree *)pnode;
8148}
8149
8150
8151/* "prime" a proto_tree with a single hfid that a dfilter
8152 * is interested in. */
8153void
8154proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8155{
8156 header_field_info *hfinfo;
8157
8158 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", 8158, __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", 8158, "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", 8158, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8159 /* this field is referenced by a filter so increase the refcount.
8160 also increase the refcount for the parent, i.e the protocol.
8161 Don't increase the refcount if we're already printing the
8162 type, as that is a superset of direct reference.
8163 */
8164 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8165 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8166 }
8167 /* only increase the refcount if there is a parent.
8168 if this is a protocol and not a field then parent will be -1
8169 and there is no parent to add any refcounting for.
8170 */
8171 if (hfinfo->parent != -1) {
8172 header_field_info *parent_hfinfo;
8173 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", 8173
, __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", 8173,
"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", 8173,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8174
8175 /* Mark parent as indirectly referenced unless it is already directly
8176 * referenced, i.e. the user has specified the parent in a filter.
8177 */
8178 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8179 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8180 }
8181}
8182
8183/* "prime" a proto_tree with a single hfid that a dfilter
8184 * is interested in. */
8185void
8186proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8187{
8188 header_field_info *hfinfo;
8189
8190 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", 8190, __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", 8190, "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", 8190, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8191 /* this field is referenced by an (output) filter so increase the refcount.
8192 also increase the refcount for the parent, i.e the protocol.
8193 */
8194 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8195 /* only increase the refcount if there is a parent.
8196 if this is a protocol and not a field then parent will be -1
8197 and there is no parent to add any refcounting for.
8198 */
8199 if (hfinfo->parent != -1) {
8200 header_field_info *parent_hfinfo;
8201 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", 8201
, __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", 8201,
"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", 8201,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8202
8203 /* Mark parent as indirectly referenced unless it is already directly
8204 * referenced, i.e. the user has specified the parent in a filter.
8205 */
8206 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8207 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8208 }
8209}
8210
8211proto_tree *
8212proto_item_add_subtree(proto_item *pi, const int idx) {
8213 field_info *fi;
8214
8215 if (!pi)
8216 return NULL((void*)0);
8217
8218 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", 8218, "idx >= 0 && idx < num_tree_types"
))))
;
8219
8220 fi = PITEM_FINFO(pi)((pi)->finfo);
8221 if (!fi)
8222 return (proto_tree *)pi;
8223
8224 fi->tree_type = idx;
8225
8226 return (proto_tree *)pi;
8227}
8228
8229proto_tree *
8230proto_item_get_subtree(proto_item *pi) {
8231 field_info *fi;
8232
8233 if (!pi)
8234 return NULL((void*)0);
8235 fi = PITEM_FINFO(pi)((pi)->finfo);
8236 if ( (fi) && (fi->tree_type == -1) )
8237 return NULL((void*)0);
8238 return (proto_tree *)pi;
8239}
8240
8241proto_item *
8242proto_item_get_parent(const proto_item *ti) {
8243 if (!ti)
8244 return NULL((void*)0);
8245 return ti->parent;
8246}
8247
8248proto_item *
8249proto_item_get_parent_nth(proto_item *ti, int gen) {
8250 if (!ti)
8251 return NULL((void*)0);
8252 while (gen--) {
8253 ti = ti->parent;
8254 if (!ti)
8255 return NULL((void*)0);
8256 }
8257 return ti;
8258}
8259
8260
8261proto_item *
8262proto_tree_get_parent(proto_tree *tree) {
8263 if (!tree)
8264 return NULL((void*)0);
8265 return (proto_item *)tree;
8266}
8267
8268proto_tree *
8269proto_tree_get_parent_tree(proto_tree *tree) {
8270 if (!tree)
8271 return NULL((void*)0);
8272
8273 /* we're the root tree, there's no parent
8274 return ourselves so the caller has at least a tree to attach to */
8275 if (!tree->parent)
8276 return tree;
8277
8278 return (proto_tree *)tree->parent;
8279}
8280
8281proto_tree *
8282proto_tree_get_root(proto_tree *tree) {
8283 if (!tree)
8284 return NULL((void*)0);
8285 while (tree->parent) {
8286 tree = tree->parent;
8287 }
8288 return tree;
8289}
8290
8291void
8292proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8293 proto_item *item_to_move)
8294{
8295 /* This function doesn't generate any values. It only reorganizes the protocol tree
8296 * so we can bail out immediately if it isn't visible. */
8297 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8298 return;
8299
8300 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", 8300, "item_to_move->parent == tree"
))))
;
8301 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", 8301, "fixed_item->parent == tree"
))))
;
8302
8303 /*** cut item_to_move out ***/
8304
8305 /* is item_to_move the first? */
8306 if (tree->first_child == item_to_move) {
8307 /* simply change first child to next */
8308 tree->first_child = item_to_move->next;
8309
8310 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", 8310, "tree->last_child != item_to_move"
))))
;
8311 } else {
8312 proto_item *curr_item;
8313 /* find previous and change it's next */
8314 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8315 if (curr_item->next == item_to_move) {
8316 break;
8317 }
8318 }
8319
8320 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8320, "curr_item"
))))
;
8321
8322 curr_item->next = item_to_move->next;
8323
8324 /* fix last_child if required */
8325 if (tree->last_child == item_to_move) {
8326 tree->last_child = curr_item;
8327 }
8328 }
8329
8330 /*** insert to_move after fixed ***/
8331 item_to_move->next = fixed_item->next;
8332 fixed_item->next = item_to_move;
8333 if (tree->last_child == fixed_item) {
8334 tree->last_child = item_to_move;
8335 }
8336}
8337
8338void
8339proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8340 const int length)
8341{
8342 field_info *fi;
8343
8344 if (tree == NULL((void*)0))
8345 return;
8346
8347 fi = PTREE_FINFO(tree)((tree)->finfo);
8348 if (fi == NULL((void*)0))
8349 return;
8350
8351 start += tvb_raw_offset(tvb);
8352 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8352, "start >= 0"
))))
;
8353 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8353, "length >= 0"
))))
;
8354
8355 fi->appendix_start = start;
8356 fi->appendix_length = length;
8357}
8358
8359static void
8360check_protocol_filter_name_or_fail(const char *filter_name)
8361{
8362 /* Require at least two characters. */
8363 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8364 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)
;
8365 }
8366
8367 if (proto_check_field_name(filter_name) != '\0') {
8368 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)
8369 " 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)
8370 " 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)
;
8371 }
8372
8373 /* Check that it doesn't match some very common numeric forms. */
8374 if (filter_name[0] == '0' &&
8375 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8376 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8377 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])
8378 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])
;
8379 }
8380
8381 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8382
8383 /* Check that it contains at least one letter. */
8384 bool_Bool have_letter = false0;
8385 for (const char *s = filter_name; *s != '\0'; s++) {
8386 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8387 have_letter = true1;
8388 break;
8389 }
8390 }
8391 if (!have_letter) {
8392 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)
8393 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8394 }
8395
8396 /* Check for reserved keywords. */
8397 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8398 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)
8399 " 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)
;
8400 }
8401}
8402
8403int
8404proto_register_protocol(const char *name, const char *short_name,
8405 const char *filter_name)
8406{
8407 protocol_t *protocol;
8408 header_field_info *hfinfo;
8409
8410 check_protocol_filter_name_or_fail(filter_name);
8411
8412 /*
8413 * Add this protocol to the list of known protocols;
8414 * the list is sorted by protocol short name.
8415 */
8416 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8417 protocol->name = name;
8418 protocol->short_name = short_name;
8419 protocol->filter_name = filter_name;
8420 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8421 protocol->is_enabled = true1; /* protocol is enabled by default */
8422 protocol->enabled_by_default = true1; /* see previous comment */
8423 protocol->can_toggle = true1;
8424 protocol->parent_proto_id = -1;
8425 protocol->heur_list = NULL((void*)0);
8426
8427 /* List will be sorted later by name, when all protocols completed registering */
8428 protocols = g_list_prepend(protocols, protocol);
8429 /*
8430 * Make sure there's not already a protocol with any of those
8431 * names. Crash if there is, as that's an error in the code
8432 * or an inappropriate plugin.
8433 * This situation has to be fixed to not register more than one
8434 * protocol with the same name.
8435 */
8436 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8437 /* ws_error will terminate the program */
8438 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)
8439 " 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)
;
8440 }
8441 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8442 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)
8443 " 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)
;
8444 }
8445 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8446 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)
8447 " 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)
;
8448 }
8449
8450 /* Here we allocate a new header_field_info struct */
8451 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8452 hfinfo->name = name;
8453 hfinfo->abbrev = filter_name;
8454 hfinfo->type = FT_PROTOCOL;
8455 hfinfo->display = BASE_NONE;
8456 hfinfo->strings = protocol;
8457 hfinfo->bitmask = 0;
8458 hfinfo->ref_type = HF_REF_TYPE_NONE;
8459 hfinfo->blurb = NULL((void*)0);
8460 hfinfo->parent = -1; /* This field differentiates protos and fields */
8461
8462 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8463 return protocol->proto_id;
8464}
8465
8466int
8467proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8468{
8469 protocol_t *protocol;
8470 header_field_info *hfinfo;
8471
8472 /*
8473 * Helper protocols don't need the strict rules as a "regular" protocol
8474 * Just register it in a list and make a hf_ field from it
8475 */
8476 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8477 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)
;
8478 }
8479
8480 if (parent_proto <= 0) {
8481 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)
8482 " 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)
;
8483 }
8484
8485 check_protocol_filter_name_or_fail(filter_name);
8486
8487 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8488 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8489 protocol->name = name;
8490 protocol->short_name = short_name;
8491 protocol->filter_name = filter_name;
8492 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8493
8494 /* Enabling and toggling is really determined by parent protocol,
8495 but provide default values here */
8496 protocol->is_enabled = true1;
8497 protocol->enabled_by_default = true1;
8498 protocol->can_toggle = true1;
8499
8500 protocol->parent_proto_id = parent_proto;
8501 protocol->heur_list = NULL((void*)0);
8502
8503 /* List will be sorted later by name, when all protocols completed registering */
8504 protocols = g_list_prepend(protocols, protocol);
8505
8506 /* Here we allocate a new header_field_info struct */
8507 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8508 hfinfo->name = name;
8509 hfinfo->abbrev = filter_name;
8510 hfinfo->type = field_type;
8511 hfinfo->display = BASE_NONE;
8512 if (field_type == FT_BYTES) {
8513 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8514 }
8515 hfinfo->strings = protocol;
8516 hfinfo->bitmask = 0;
8517 hfinfo->ref_type = HF_REF_TYPE_NONE;
8518 hfinfo->blurb = NULL((void*)0);
8519 hfinfo->parent = -1; /* This field differentiates protos and fields */
8520
8521 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8522 return protocol->proto_id;
8523}
8524
8525bool_Bool
8526proto_deregister_protocol(const char *short_name)
8527{
8528 protocol_t *protocol;
8529 header_field_info *hfinfo;
8530 int proto_id;
8531 unsigned i;
8532
8533 proto_id = proto_get_id_by_short_name(short_name);
8534 protocol = find_protocol_by_id(proto_id);
8535 if (protocol == NULL((void*)0))
8536 return false0;
8537
8538 g_hash_table_remove(proto_names, protocol->name);
8539 g_hash_table_remove(proto_short_names, (void *)short_name);
8540 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8541
8542 if (protocol->fields) {
8543 for (i = 0; i < protocol->fields->len; i++) {
8544 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8545 hfinfo_remove_from_gpa_name_map(hfinfo);
8546 expert_deregister_expertinfo(hfinfo->abbrev);
8547 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8548 }
8549 g_ptr_array_free(protocol->fields, true1);
8550 protocol->fields = NULL((void*)0);
8551 }
8552
8553 g_list_free(protocol->heur_list);
8554
8555 /* Remove this protocol from the list of known protocols */
8556 protocols = g_list_remove(protocols, protocol);
8557
8558 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8559 wmem_map_remove(gpa_name_map, protocol->filter_name);
8560
8561 g_free(last_field_name);
8562 last_field_name = NULL((void*)0);
8563
8564 return true1;
8565}
8566
8567void
8568proto_register_alias(const int proto_id, const char *alias_name)
8569{
8570 protocol_t *protocol;
8571
8572 protocol = find_protocol_by_id(proto_id);
8573 if (alias_name && protocol) {
8574 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8575 }
8576}
8577
8578/*
8579 * Routines to use to iterate over the protocols.
8580 * The argument passed to the iterator routines is an opaque cookie to
8581 * their callers; it's the GList pointer for the current element in
8582 * the list.
8583 * The ID of the protocol is returned, or -1 if there is no protocol.
8584 */
8585int
8586proto_get_first_protocol(void **cookie)
8587{
8588 protocol_t *protocol;
8589
8590 if (protocols == NULL((void*)0))
8591 return -1;
8592 *cookie = protocols;
8593 protocol = (protocol_t *)protocols->data;
8594 return protocol->proto_id;
8595}
8596
8597int
8598proto_get_data_protocol(void *cookie)
8599{
8600 GList *list_item = (GList *)cookie;
8601
8602 protocol_t *protocol = (protocol_t *)list_item->data;
8603 return protocol->proto_id;
8604}
8605
8606int
8607proto_get_next_protocol(void **cookie)
8608{
8609 GList *list_item = (GList *)*cookie;
8610 protocol_t *protocol;
8611
8612 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8613 if (list_item == NULL((void*)0))
8614 return -1;
8615 *cookie = list_item;
8616 protocol = (protocol_t *)list_item->data;
8617 return protocol->proto_id;
8618}
8619
8620header_field_info *
8621proto_get_first_protocol_field(const int proto_id, void **cookie)
8622{
8623 protocol_t *protocol = find_protocol_by_id(proto_id);
8624
8625 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8626 return NULL((void*)0);
8627
8628 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8629 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8630}
8631
8632header_field_info *
8633proto_get_next_protocol_field(const int proto_id, void **cookie)
8634{
8635 protocol_t *protocol = find_protocol_by_id(proto_id);
8636 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8637
8638 i++;
8639
8640 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8641 return NULL((void*)0);
8642
8643 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8644 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8645}
8646
8647protocol_t *
8648find_protocol_by_id(const int proto_id)
8649{
8650 header_field_info *hfinfo;
8651
8652 if (proto_id <= 0)
8653 return NULL((void*)0);
8654
8655 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", 8655, __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", 8655,
"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", 8655, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8656 if (hfinfo->type != FT_PROTOCOL) {
8657 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", 8657, "hfinfo->display & 0x00004000"
))))
;
8658 }
8659 return (protocol_t *)hfinfo->strings;
8660}
8661
8662int
8663proto_get_id(const protocol_t *protocol)
8664{
8665 return protocol->proto_id;
8666}
8667
8668bool_Bool
8669proto_name_already_registered(const char *name)
8670{
8671 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8671, "name", "No name present"))))
;
8672
8673 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8674 return true1;
8675 return false0;
8676}
8677
8678int
8679proto_get_id_by_filter_name(const char *filter_name)
8680{
8681 const protocol_t *protocol = NULL((void*)0);
8682
8683 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", 8683,
"filter_name", "No filter name present"))))
;
8684
8685 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8686
8687 if (protocol == NULL((void*)0))
8688 return -1;
8689 return protocol->proto_id;
8690}
8691
8692int
8693proto_get_id_by_short_name(const char *short_name)
8694{
8695 const protocol_t *protocol = NULL((void*)0);
8696
8697 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", 8697,
"short_name", "No short name present"))))
;
8698
8699 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8700
8701 if (protocol == NULL((void*)0))
8702 return -1;
8703 return protocol->proto_id;
8704}
8705
8706const char *
8707proto_get_protocol_name(const int proto_id)
8708{
8709 protocol_t *protocol;
8710
8711 protocol = find_protocol_by_id(proto_id);
8712
8713 if (protocol == NULL((void*)0))
8714 return NULL((void*)0);
8715 return protocol->name;
8716}
8717
8718const char *
8719proto_get_protocol_short_name(const protocol_t *protocol)
8720{
8721 if (protocol == NULL((void*)0))
8722 return "(none)";
8723 return protocol->short_name;
8724}
8725
8726const char *
8727proto_get_protocol_long_name(const protocol_t *protocol)
8728{
8729 if (protocol == NULL((void*)0))
8730 return "(none)";
8731 return protocol->name;
8732}
8733
8734const char *
8735proto_get_protocol_filter_name(const int proto_id)
8736{
8737 protocol_t *protocol;
8738
8739 protocol = find_protocol_by_id(proto_id);
8740 if (protocol == NULL((void*)0))
8741 return "(none)";
8742 return protocol->filter_name;
8743}
8744
8745void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8746{
8747 heur_dtbl_entry_t* heuristic_dissector;
8748
8749 if (protocol == NULL((void*)0))
8750 return;
8751
8752 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8753 if (heuristic_dissector != NULL((void*)0))
8754 {
8755 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8756 }
8757}
8758
8759void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8760{
8761 if (protocol == NULL((void*)0))
8762 return;
8763
8764 g_list_foreach(protocol->heur_list, func, user_data);
8765}
8766
8767void
8768proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8769 bool_Bool *is_tcp, bool_Bool *is_udp,
8770 bool_Bool *is_sctp, bool_Bool *is_tls,
8771 bool_Bool *is_rtp,
8772 bool_Bool *is_lte_rlc)
8773{
8774 wmem_list_frame_t *protos = wmem_list_head(layers);
8775 int proto_id;
8776 const char *proto_name;
8777
8778 /* Walk the list of a available protocols in the packet and
8779 attempt to find "major" ones. */
8780 /* It might make more sense to assemble and return a bitfield. */
8781 while (protos != NULL((void*)0))
8782 {
8783 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8784 proto_name = proto_get_protocol_filter_name(proto_id);
8785
8786 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8787 (!strcmp(proto_name, "ipv6")))) {
8788 *is_ip = true1;
8789 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8790 *is_tcp = true1;
8791 } else if (is_udp && !strcmp(proto_name, "udp")) {
8792 *is_udp = true1;
8793 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8794 *is_sctp = true1;
8795 } else if (is_tls && !strcmp(proto_name, "tls")) {
8796 *is_tls = true1;
8797 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8798 *is_rtp = true1;
8799 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8800 *is_lte_rlc = true1;
8801 }
8802
8803 protos = wmem_list_frame_next(protos);
8804 }
8805}
8806
8807bool_Bool
8808proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8809{
8810 wmem_list_frame_t *protos = wmem_list_head(layers);
8811 int proto_id;
8812 const char *name;
8813
8814 /* Walk the list of a available protocols in the packet and
8815 attempt to find the specified protocol. */
8816 while (protos != NULL((void*)0))
8817 {
8818 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8819 name = proto_get_protocol_filter_name(proto_id);
8820
8821 if (!strcmp(name, proto_name))
8822 {
8823 return true1;
8824 }
8825
8826 protos = wmem_list_frame_next(protos);
8827 }
8828
8829 return false0;
8830}
8831
8832char *
8833proto_list_layers(const packet_info *pinfo)
8834{
8835 wmem_strbuf_t *buf;
8836 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8837
8838 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8839
8840 /* Walk the list of layers in the packet and
8841 return a string of all entries. */
8842 while (layers != NULL((void*)0))
8843 {
8844 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8845
8846 layers = wmem_list_frame_next(layers);
8847 if (layers != NULL((void*)0)) {
8848 wmem_strbuf_append_c(buf, ':');
8849 }
8850 }
8851
8852 return wmem_strbuf_finalize(buf);
8853}
8854
8855uint8_t
8856proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8857{
8858 int *proto_layer_num_ptr;
8859
8860 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8861 if (proto_layer_num_ptr == NULL((void*)0)) {
8862 return 0;
8863 }
8864
8865 return (uint8_t)*proto_layer_num_ptr;
8866}
8867
8868bool_Bool
8869proto_is_pino(const protocol_t *protocol)
8870{
8871 return (protocol->parent_proto_id != -1);
8872}
8873
8874bool_Bool
8875// NOLINTNEXTLINE(misc-no-recursion)
8876proto_is_protocol_enabled(const protocol_t *protocol)
8877{
8878 if (protocol == NULL((void*)0))
8879 return false0;
8880
8881 //parent protocol determines enable/disable for helper dissectors
8882 if (proto_is_pino(protocol))
8883 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8884
8885 return protocol->is_enabled;
8886}
8887
8888bool_Bool
8889// NOLINTNEXTLINE(misc-no-recursion)
8890proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8891{
8892 //parent protocol determines enable/disable for helper dissectors
8893 if (proto_is_pino(protocol))
8894 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8895
8896 return protocol->enabled_by_default;
8897}
8898
8899bool_Bool
8900// NOLINTNEXTLINE(misc-no-recursion)
8901proto_can_toggle_protocol(const int proto_id)
8902{
8903 protocol_t *protocol;
8904
8905 protocol = find_protocol_by_id(proto_id);
8906 //parent protocol determines toggling for helper dissectors
8907 if (proto_is_pino(protocol))
8908 return proto_can_toggle_protocol(protocol->parent_proto_id);
8909
8910 return protocol->can_toggle;
8911}
8912
8913void
8914proto_disable_by_default(const int proto_id)
8915{
8916 protocol_t *protocol;
8917
8918 protocol = find_protocol_by_id(proto_id);
8919 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8919, "protocol->can_toggle"
))))
;
8920 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", 8920, "proto_is_pino(protocol) == 0"
))))
;
8921 protocol->is_enabled = false0;
8922 protocol->enabled_by_default = false0;
8923}
8924
8925void
8926proto_set_decoding(const int proto_id, const bool_Bool enabled)
8927{
8928 protocol_t *protocol;
8929
8930 protocol = find_protocol_by_id(proto_id);
8931 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8931, "protocol->can_toggle"
))))
;
8932 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", 8932, "proto_is_pino(protocol) == 0"
))))
;
8933 protocol->is_enabled = enabled;
8934}
8935
8936void
8937proto_disable_all(void)
8938{
8939 /* This doesn't explicitly disable heuristic protocols,
8940 * but the heuristic doesn't get called if the parent
8941 * protocol isn't enabled.
8942 */
8943 protocol_t *protocol;
8944 GList *list_item = protocols;
8945
8946 if (protocols == NULL((void*)0))
8947 return;
8948
8949 while (list_item) {
8950 protocol = (protocol_t *)list_item->data;
8951 if (protocol->can_toggle) {
8952 protocol->is_enabled = false0;
8953 }
8954 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8955 }
8956}
8957
8958static void
8959heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8960{
8961 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8962
8963 heur->enabled = heur->enabled_by_default;
8964}
8965
8966void
8967proto_reenable_all(void)
8968{
8969 protocol_t *protocol;
8970 GList *list_item = protocols;
8971
8972 if (protocols == NULL((void*)0))
8973 return;
8974
8975 while (list_item) {
8976 protocol = (protocol_t *)list_item->data;
8977 if (protocol->can_toggle)
8978 protocol->is_enabled = protocol->enabled_by_default;
8979 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8980 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8981 }
8982}
8983
8984void
8985proto_set_cant_toggle(const int proto_id)
8986{
8987 protocol_t *protocol;
8988
8989 protocol = find_protocol_by_id(proto_id);
8990 protocol->can_toggle = false0;
8991}
8992
8993static int
8994proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8995{
8996 g_ptr_array_add(proto->fields, hfi);
8997
8998 return proto_register_field_init(hfi, parent);
8999}
9000
9001/* for use with static arrays only, since we don't allocate our own copies
9002of the header_field_info struct contained within the hf_register_info struct */
9003void
9004proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9005{
9006 hf_register_info *ptr = hf;
9007 protocol_t *proto;
9008 int i;
9009
9010 proto = find_protocol_by_id(parent);
9011
9012 /* if (proto == NULL) - error or return? */
9013
9014 if (proto->fields == NULL((void*)0)) {
9015 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9016 * GLib introduced g_ptr_array_new_from_array, which might have
9017 * given a reason to actually use it. (#17774)
9018 */
9019 proto->fields = g_ptr_array_sized_new(num_records);
9020 }
9021
9022 for (i = 0; i < num_records; i++, ptr++) {
9023 /*
9024 * Make sure we haven't registered this yet.
9025 * Most fields have variables associated with them that
9026 * are initialized to 0; some are initialized to -1 (which
9027 * was the standard before 4.4).
9028 *
9029 * XXX - Since this is called almost 300000 times at startup,
9030 * it might be nice to compare to only 0 and require
9031 * dissectors to pass in zero for unregistered fields.
9032 */
9033 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9034 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9035 "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)
9036 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9037 return;
9038 }
9039
9040 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9041 }
9042}
9043
9044/* deregister already registered fields */
9045void
9046proto_deregister_field (const int parent, int hf_id)
9047{
9048 header_field_info *hfi;
9049 protocol_t *proto;
9050 unsigned i;
9051
9052 g_free(last_field_name);
9053 last_field_name = NULL((void*)0);
9054
9055 if (hf_id == -1 || hf_id == 0)
9056 return;
9057
9058 proto = find_protocol_by_id (parent);
9059 if (!proto || proto->fields == NULL((void*)0)) {
9060 return;
9061 }
9062
9063 for (i = 0; i < proto->fields->len; i++) {
9064 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9065 if (hfi->id == hf_id) {
9066 /* Found the hf_id in this protocol */
9067 wmem_map_remove(gpa_name_map, hfi->abbrev);
9068 g_ptr_array_remove_index_fast(proto->fields, i);
9069 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9070 return;
9071 }
9072 }
9073}
9074
9075/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9076void
9077proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9078{
9079 header_field_info *hfinfo;
9080 protocol_t *proto;
9081
9082 g_free(last_field_name);
9083 last_field_name = NULL((void*)0);
9084
9085 proto = find_protocol_by_id(parent);
9086 if (proto && proto->fields && proto->fields->len > 0) {
9087 unsigned i = proto->fields->len;
9088 do {
9089 i--;
9090
9091 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9092 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) )
) {
9093 hfinfo_remove_from_gpa_name_map(hfinfo);
9094 expert_deregister_expertinfo(hfinfo->abbrev);
9095 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9096 g_ptr_array_remove_index_fast(proto->fields, i);
9097 }
9098 } while (i > 0);
9099 }
9100}
9101
9102void
9103proto_add_deregistered_data (void *data)
9104{
9105 g_ptr_array_add(deregistered_data, data);
9106}
9107
9108void
9109proto_add_deregistered_slice (size_t block_size, void *mem_block)
9110{
9111 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
)))
;
9112
9113 slice_data->block_size = block_size;
9114 slice_data->mem_block = mem_block;
9115
9116 g_ptr_array_add(deregistered_slice, slice_data);
9117}
9118
9119void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9120{
9121 if (field_strings == NULL((void*)0)) {
9122 return;
9123 }
9124
9125 switch (field_type) {
9126 case FT_FRAMENUM:
9127 /* This is just an integer represented as a pointer */
9128 break;
9129 case FT_PROTOCOL: {
9130 protocol_t *protocol = (protocol_t *)field_strings;
9131 g_free((char *)protocol->short_name);
9132 break;
9133 }
9134 case FT_BOOLEAN: {
9135 true_false_string *tf = (true_false_string *)field_strings;
9136 g_free((char *)tf->true_string);
9137 g_free((char *)tf->false_string);
9138 break;
9139 }
9140 case FT_UINT40:
9141 case FT_INT40:
9142 case FT_UINT48:
9143 case FT_INT48:
9144 case FT_UINT56:
9145 case FT_INT56:
9146 case FT_UINT64:
9147 case FT_INT64: {
9148 if (field_display & BASE_UNIT_STRING0x00001000) {
9149 unit_name_string *unit = (unit_name_string *)field_strings;
9150 g_free((char *)unit->singular);
9151 g_free((char *)unit->plural);
9152 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9153 range_string *rs = (range_string *)field_strings;
9154 while (rs->strptr) {
9155 g_free((char *)rs->strptr);
9156 rs++;
9157 }
9158 } else if (field_display & BASE_EXT_STRING0x00000200) {
9159 val64_string_ext *vse = (val64_string_ext *)field_strings;
9160 val64_string *vs = (val64_string *)vse->_vs_p;
9161 while (vs->strptr) {
9162 g_free((char *)vs->strptr);
9163 vs++;
9164 }
9165 val64_string_ext_free(vse);
9166 field_strings = NULL((void*)0);
9167 } else if (field_display == BASE_CUSTOM) {
9168 /* this will be a pointer to a function, don't free that */
9169 field_strings = NULL((void*)0);
9170 } else {
9171 val64_string *vs64 = (val64_string *)field_strings;
9172 while (vs64->strptr) {
9173 g_free((char *)vs64->strptr);
9174 vs64++;
9175 }
9176 }
9177 break;
9178 }
9179 case FT_CHAR:
9180 case FT_UINT8:
9181 case FT_INT8:
9182 case FT_UINT16:
9183 case FT_INT16:
9184 case FT_UINT24:
9185 case FT_INT24:
9186 case FT_UINT32:
9187 case FT_INT32:
9188 case FT_FLOAT:
9189 case FT_DOUBLE: {
9190 if (field_display & BASE_UNIT_STRING0x00001000) {
9191 unit_name_string *unit = (unit_name_string *)field_strings;
9192 g_free((char *)unit->singular);
9193 g_free((char *)unit->plural);
9194 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9195 range_string *rs = (range_string *)field_strings;
9196 while (rs->strptr) {
9197 g_free((char *)rs->strptr);
9198 rs++;
9199 }
9200 } else if (field_display & BASE_EXT_STRING0x00000200) {
9201 value_string_ext *vse = (value_string_ext *)field_strings;
9202 value_string *vs = (value_string *)vse->_vs_p;
9203 while (vs->strptr) {
9204 g_free((char *)vs->strptr);
9205 vs++;
9206 }
9207 value_string_ext_free(vse);
9208 field_strings = NULL((void*)0);
9209 } else if (field_display == BASE_CUSTOM) {
9210 /* this will be a pointer to a function, don't free that */
9211 field_strings = NULL((void*)0);
9212 } else {
9213 value_string *vs = (value_string *)field_strings;
9214 while (vs->strptr) {
9215 g_free((char *)vs->strptr);
9216 vs++;
9217 }
9218 }
9219 break;
9220 default:
9221 break;
9222 }
9223 }
9224
9225 if (field_type != FT_FRAMENUM) {
9226 g_free((void *)field_strings);
9227 }
9228}
9229
9230static void
9231free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9232{
9233 header_field_info *hfi = (header_field_info *) data;
9234 int hf_id = hfi->id;
9235
9236 g_free((char *)hfi->name);
9237 g_free((char *)hfi->abbrev);
9238 g_free((char *)hfi->blurb);
9239
9240 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9241
9242 if (hfi->parent == -1)
9243 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)
;
9244
9245 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9246}
9247
9248static void
9249free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9250{
9251 g_free (data);
9252}
9253
9254static void
9255free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9256{
9257 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9258
9259 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9260 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)
;
9261}
9262
9263/* free deregistered fields and data */
9264void
9265proto_free_deregistered_fields (void)
9266{
9267 expert_free_deregistered_expertinfos();
9268
9269 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9270 g_ptr_array_free(deregistered_fields, true1);
9271 deregistered_fields = g_ptr_array_new();
9272
9273 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9274 g_ptr_array_free(deregistered_data, true1);
9275 deregistered_data = g_ptr_array_new();
9276
9277 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9278 g_ptr_array_free(deregistered_slice, true1);
9279 deregistered_slice = g_ptr_array_new();
9280}
9281
9282static const value_string hf_display[] = {
9283 { BASE_NONE, "BASE_NONE" },
9284 { BASE_DEC, "BASE_DEC" },
9285 { BASE_HEX, "BASE_HEX" },
9286 { BASE_OCT, "BASE_OCT" },
9287 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9288 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9289 { BASE_CUSTOM, "BASE_CUSTOM" },
9290 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9291 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9292 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9293 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9294 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9295 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9296 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9297 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9298 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9299 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9300 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9301 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9302 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9303 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9304 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9305 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9306 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9307 { BASE_PT_UDP, "BASE_PT_UDP" },
9308 { BASE_PT_TCP, "BASE_PT_TCP" },
9309 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9310 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9311 { BASE_OUI, "BASE_OUI" },
9312 { 0, NULL((void*)0) } };
9313
9314const char* proto_field_display_to_string(int field_display)
9315{
9316 return val_to_str_const(field_display, hf_display, "Unknown");
9317}
9318
9319static inline port_type
9320display_to_port_type(field_display_e e)
9321{
9322 switch (e) {
9323 case BASE_PT_UDP:
9324 return PT_UDP;
9325 case BASE_PT_TCP:
9326 return PT_TCP;
9327 case BASE_PT_DCCP:
9328 return PT_DCCP;
9329 case BASE_PT_SCTP:
9330 return PT_SCTP;
9331 default:
9332 break;
9333 }
9334 return PT_NONE;
9335}
9336
9337/* temporary function containing assert part for easier profiling */
9338static void
9339tmp_fld_check_assert(header_field_info *hfinfo)
9340{
9341 char* tmp_str;
9342
9343 /* The field must have a name (with length > 0) */
9344 if (!hfinfo->name || !hfinfo->name[0]) {
9345 if (hfinfo->abbrev)
9346 /* Try to identify the field */
9347 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)
9348 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9349 else
9350 /* Hum, no luck */
9351 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)"
)
;
9352 }
9353
9354 /* fields with an empty string for an abbreviation aren't filterable */
9355 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9356 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)
;
9357
9358 /* TODO: This check is a significant percentage of startup time (~10%),
9359 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9360 It might be nice to have a way to disable this check when, e.g.,
9361 running TShark many times with the same configuration. */
9362 /* Check that the filter name (abbreviation) is legal;
9363 * it must contain only alphanumerics, '-', "_", and ".". */
9364 unsigned char c;
9365 c = module_check_valid_name(hfinfo->abbrev, false0);
9366 if (c) {
9367 if (c == '.') {
9368 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)
;
9369 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9370 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)
;
9371 } else {
9372 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)
;
9373 }
9374 }
9375
9376 /* These types of fields are allowed to have value_strings,
9377 * true_false_strings or a protocol_t struct
9378 */
9379 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9380 switch (hfinfo->type) {
9381
9382 /*
9383 * These types are allowed to support display value_strings,
9384 * value64_strings, the extended versions of the previous
9385 * two, range strings, or unit strings.
9386 */
9387 case FT_CHAR:
9388 case FT_UINT8:
9389 case FT_UINT16:
9390 case FT_UINT24:
9391 case FT_UINT32:
9392 case FT_UINT40:
9393 case FT_UINT48:
9394 case FT_UINT56:
9395 case FT_UINT64:
9396 case FT_INT8:
9397 case FT_INT16:
9398 case FT_INT24:
9399 case FT_INT32:
9400 case FT_INT40:
9401 case FT_INT48:
9402 case FT_INT56:
9403 case FT_INT64:
9404 case FT_BOOLEAN:
9405 case FT_PROTOCOL:
9406 break;
9407
9408 /*
9409 * This is allowed to have a value of type
9410 * enum ft_framenum_type to indicate what relationship
9411 * the frame in question has to the frame in which
9412 * the field is put.
9413 */
9414 case FT_FRAMENUM:
9415 break;
9416
9417 /*
9418 * These types are allowed to support only unit strings.
9419 */
9420 case FT_FLOAT:
9421 case FT_DOUBLE:
9422 case FT_IEEE_11073_SFLOAT:
9423 case FT_IEEE_11073_FLOAT:
9424 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9425 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))
9426 " (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))
9427 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))
;
9428 }
9429 break;
9430
9431 /*
9432 * These types are allowed to support display
9433 * time_value_strings.
9434 */
9435 case FT_ABSOLUTE_TIME:
9436 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9437 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9438 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9439 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9440 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))
9441 " (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))
9442 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))
;
9443 }
9444 break;
9445
9446 /*
9447 * This type is only allowed to support a string if it's
9448 * a protocol (for pinos).
9449 */
9450 case FT_BYTES:
9451 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9452 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))
9453 " (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))
9454 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))
;
9455 }
9456 break;
9457
9458 default:
9459 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))
9460 " (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))
9461 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))
;
9462 }
9463 }
9464
9465 /* TODO: This check may slow down startup, and output quite a few warnings.
9466 It would be good to be able to enable this (and possibly other checks?)
9467 in non-release builds. */
9468#ifdef ENABLE_CHECK_FILTER
9469 /* Check for duplicate value_string values.
9470 There are lots that have the same value *and* string, so for now only
9471 report those that have same value but different string. */
9472 if ((hfinfo->strings != NULL((void*)0)) &&
9473 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9474 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9475 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9476 (
9477 (hfinfo->type == FT_CHAR) ||
9478 (hfinfo->type == FT_UINT8) ||
9479 (hfinfo->type == FT_UINT16) ||
9480 (hfinfo->type == FT_UINT24) ||
9481 (hfinfo->type == FT_UINT32) ||
9482 (hfinfo->type == FT_INT8) ||
9483 (hfinfo->type == FT_INT16) ||
9484 (hfinfo->type == FT_INT24) ||
9485 (hfinfo->type == FT_INT32) )) {
9486
9487 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9488 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9489 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9490 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9491 } else {
9492 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9493 CHECK_HF_VALUE(value_string, "u", start_values);
9494 }
9495 } else {
9496 const value_string *start_values = (const value_string*)hfinfo->strings;
9497 CHECK_HF_VALUE(value_string, "u", start_values);
9498 }
9499 }
9500
9501 if (hfinfo->type == FT_BOOLEAN) {
9502 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9503 if (tfs) {
9504 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9505 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9507
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9506 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9507
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9507 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9507
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9508 }
9509 }
9510 }
9511
9512 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9513 const range_string *rs = (const range_string*)(hfinfo->strings);
9514 if (rs) {
9515 const range_string *this_it = rs;
9516
9517 do {
9518 if (this_it->value_max < this_it->value_min) {
9519 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"
, 9523, __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)
9520 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9523, __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)
9521 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9523, __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 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9523, __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->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9523, __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;
9525 continue;
9526 }
9527
9528 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9529 /* Not OK if this one is completely hidden by an earlier one! */
9530 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9531 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"
, 9537, __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)
9532 "(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"
, 9537, __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)
9533 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9537, __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_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9537, __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 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9537, __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 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9537, __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 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9537, __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 }
9539 }
9540 ++this_it;
9541 } while (this_it->strptr);
9542 }
9543 }
9544#endif
9545
9546 switch (hfinfo->type) {
9547
9548 case FT_CHAR:
9549 /* Require the char type to have BASE_HEX, BASE_OCT,
9550 * BASE_CUSTOM, or BASE_NONE as its base.
9551 *
9552 * If the display value is BASE_NONE and there is a
9553 * strings conversion then the dissector writer is
9554 * telling us that the field's numerical value is
9555 * meaningless; we'll avoid showing the value to the
9556 * user.
9557 */
9558 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9559 case BASE_HEX:
9560 case BASE_OCT:
9561 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9562 break;
9563 case BASE_NONE:
9564 if (hfinfo->strings == NULL((void*)0))
9565 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
))
9566 " 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
))
9567 " 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
))
9568 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
))
9569 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
))
;
9570 break;
9571 default:
9572 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9573 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)
9574 " 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)
9575 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)
9576 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)
;
9577 //wmem_free(NULL, tmp_str);
9578 }
9579 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9580 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
))
9581 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
))
9582 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
))
;
9583 }
9584 break;
9585 case FT_INT8:
9586 case FT_INT16:
9587 case FT_INT24:
9588 case FT_INT32:
9589 case FT_INT40:
9590 case FT_INT48:
9591 case FT_INT56:
9592 case FT_INT64:
9593 /* Hexadecimal and octal are, in printf() and everywhere
9594 * else, unsigned so don't allow dissectors to register a
9595 * signed field to be displayed unsigned. (Else how would
9596 * we display negative values?)
9597 */
9598 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9599 case BASE_HEX:
9600 case BASE_OCT:
9601 case BASE_DEC_HEX:
9602 case BASE_HEX_DEC:
9603 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9604 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)
9605 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)
9606 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)
;
9607 //wmem_free(NULL, tmp_str);
9608 }
9609 /* FALL THROUGH */
9610 case FT_UINT8:
9611 case FT_UINT16:
9612 case FT_UINT24:
9613 case FT_UINT32:
9614 case FT_UINT40:
9615 case FT_UINT48:
9616 case FT_UINT56:
9617 case FT_UINT64:
9618 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
))
) {
9619 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9620 if (hfinfo->type != FT_UINT16) {
9621 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))
9622 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))
9623 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))
;
9624 }
9625 if (hfinfo->strings != NULL((void*)0)) {
9626 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)
9627 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)
9628 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)
;
9629 }
9630 if (hfinfo->bitmask != 0) {
9631 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)
9632 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)
9633 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)
;
9634 }
9635 wmem_free(NULL((void*)0), tmp_str);
9636 break;
9637 }
9638
9639 if (hfinfo->display == BASE_OUI) {
9640 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9641 if (hfinfo->type != FT_UINT24) {
9642 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))
9643 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))
9644 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))
;
9645 }
9646 if (hfinfo->strings != NULL((void*)0)) {
9647 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)
9648 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)
9649 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)
;
9650 }
9651 if (hfinfo->bitmask != 0) {
9652 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)
9653 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)
9654 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)
;
9655 }
9656 wmem_free(NULL((void*)0), tmp_str);
9657 break;
9658 }
9659
9660 /* Require integral types (other than frame number,
9661 * which is always displayed in decimal) to have a
9662 * number base.
9663 *
9664 * If the display value is BASE_NONE and there is a
9665 * strings conversion then the dissector writer is
9666 * telling us that the field's numerical value is
9667 * meaningless; we'll avoid showing the value to the
9668 * user.
9669 */
9670 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9671 case BASE_DEC:
9672 case BASE_HEX:
9673 case BASE_OCT:
9674 case BASE_DEC_HEX:
9675 case BASE_HEX_DEC:
9676 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9677 break;
9678 case BASE_NONE:
9679 if (hfinfo->strings == NULL((void*)0)) {
9680 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
))
9681 " 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
))
9682 " 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
))
9683 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
))
9684 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
))
;
9685 }
9686 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9687 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
))
9688 " 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
))
9689 " 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
))
9690 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
))
9691 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
))
;
9692 }
9693 break;
9694
9695 default:
9696 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9697 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)
9698 " 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)
9699 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)
9700 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)
;
9701 //wmem_free(NULL, tmp_str);
9702 }
9703 break;
9704 case FT_BYTES:
9705 case FT_UINT_BYTES:
9706 /* Require bytes to have a "display type" that could
9707 * add a character between displayed bytes.
9708 */
9709 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9710 case BASE_NONE:
9711 case SEP_DOT:
9712 case SEP_DASH:
9713 case SEP_COLON:
9714 case SEP_SPACE:
9715 break;
9716 default:
9717 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9718 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)
9719 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)
;
9720 //wmem_free(NULL, tmp_str);
9721 }
9722 if (hfinfo->bitmask != 0)
9723 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
))
9724 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
))
9725 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
))
;
9726 //allowed to support string if its a protocol (for pinos)
9727 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9728 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
))
9729 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
))
9730 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
))
;
9731 break;
9732
9733 case FT_PROTOCOL:
9734 case FT_FRAMENUM:
9735 if (hfinfo->display != BASE_NONE) {
9736 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9737 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)
9738 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)
9739 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)
;
9740 //wmem_free(NULL, tmp_str);
9741 }
9742 if (hfinfo->bitmask != 0)
9743 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
))
9744 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
))
9745 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
))
;
9746 break;
9747
9748 case FT_BOOLEAN:
9749 break;
9750
9751 case FT_ABSOLUTE_TIME:
9752 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9753 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9754 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)
9755 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)
;
9756 //wmem_free(NULL, tmp_str);
9757 }
9758 if (hfinfo->bitmask != 0)
9759 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
))
9760 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
))
9761 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
))
;
9762 break;
9763
9764 case FT_STRING:
9765 case FT_STRINGZ:
9766 case FT_UINT_STRING:
9767 case FT_STRINGZPAD:
9768 case FT_STRINGZTRUNC:
9769 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9770 case BASE_NONE:
9771 case BASE_STR_WSP:
9772 break;
9773
9774 default:
9775 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9776 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)
9777 " 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)
9778 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)
9779 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)
;
9780 //wmem_free(NULL, tmp_str);
9781 }
9782
9783 if (hfinfo->bitmask != 0)
9784 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
))
9785 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
))
9786 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
))
;
9787 if (hfinfo->strings != NULL((void*)0))
9788 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
))
9789 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
))
9790 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
))
;
9791 break;
9792
9793 case FT_IPv4:
9794 switch (hfinfo->display) {
9795 case BASE_NONE:
9796 case BASE_NETMASK:
9797 break;
9798
9799 default:
9800 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9801 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)
9802 " 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)
9803 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)
9804 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)
;
9805 //wmem_free(NULL, tmp_str);
9806 break;
9807 }
9808 break;
9809 case FT_FLOAT:
9810 case FT_DOUBLE:
9811 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9812 case BASE_NONE:
9813 case BASE_DEC:
9814 case BASE_HEX:
9815 case BASE_EXP:
9816 case BASE_CUSTOM:
9817 break;
9818 default:
9819 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9820 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)
9821 " 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)
9822 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)
9823 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)
;
9824 //wmem_free(NULL, tmp_str);
9825 }
9826 if (hfinfo->bitmask != 0)
9827 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
))
9828 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
))
9829 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
))
;
9830 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9831 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
))
9832 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
))
9833 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
))
;
9834 break;
9835 case FT_IEEE_11073_SFLOAT:
9836 case FT_IEEE_11073_FLOAT:
9837 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9838 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9839 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)
9840 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)
9841 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)
9842 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)
;
9843 //wmem_free(NULL, tmp_str);
9844 }
9845 if (hfinfo->bitmask != 0)
9846 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
))
9847 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
))
9848 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
))
;
9849 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9850 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
))
9851 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
))
9852 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
))
;
9853 break;
9854 default:
9855 if (hfinfo->display != BASE_NONE) {
9856 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9857 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)
9858 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)
9859 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)
9860 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)
;
9861 //wmem_free(NULL, tmp_str);
9862 }
9863 if (hfinfo->bitmask != 0)
9864 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
))
9865 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
))
9866 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
))
;
9867 if (hfinfo->strings != NULL((void*)0))
9868 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
))
9869 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
))
9870 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
))
;
9871 break;
9872 }
9873}
9874
9875static void
9876register_type_length_mismatch(void)
9877{
9878 static ei_register_info ei[] = {
9879 { &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)}}
}},
9880 { &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)}}
}},
9881 };
9882
9883 expert_module_t* expert_type_length_mismatch;
9884
9885 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9886
9887 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9888 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9889
9890 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9891 disabling them makes no sense. */
9892 proto_set_cant_toggle(proto_type_length_mismatch);
9893}
9894
9895static void
9896register_byte_array_string_decodinws_error(void)
9897{
9898 static ei_register_info ei[] = {
9899 { &ei_byte_array_string_decoding_failed_error,
9900 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9901 "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)}}
9902 }
9903 },
9904 };
9905
9906 expert_module_t* expert_byte_array_string_decoding_error;
9907
9908 proto_byte_array_string_decoding_error =
9909 proto_register_protocol("Byte Array-String Decoding Error",
9910 "Byte Array-string decoding error",
9911 "_ws.byte_array_string.decoding_error");
9912
9913 expert_byte_array_string_decoding_error =
9914 expert_register_protocol(proto_byte_array_string_decoding_error);
9915 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9916
9917 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9918 disabling them makes no sense. */
9919 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9920}
9921
9922static void
9923register_date_time_string_decodinws_error(void)
9924{
9925 static ei_register_info ei[] = {
9926 { &ei_date_time_string_decoding_failed_error,
9927 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9928 "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)}}
9929 }
9930 },
9931 };
9932
9933 expert_module_t* expert_date_time_string_decoding_error;
9934
9935 proto_date_time_string_decoding_error =
9936 proto_register_protocol("Date and Time-String Decoding Error",
9937 "Date and Time-string decoding error",
9938 "_ws.date_time_string.decoding_error");
9939
9940 expert_date_time_string_decoding_error =
9941 expert_register_protocol(proto_date_time_string_decoding_error);
9942 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9943
9944 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9945 disabling them makes no sense. */
9946 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9947}
9948
9949static void
9950register_string_errors(void)
9951{
9952 static ei_register_info ei[] = {
9953 { &ei_string_trailing_characters,
9954 { "_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)}}
}
9955 },
9956 };
9957
9958 expert_module_t* expert_string_errors;
9959
9960 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9961
9962 expert_string_errors = expert_register_protocol(proto_string_errors);
9963 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9964
9965 /* "String Errors" isn't really a protocol, it's an error indication;
9966 disabling them makes no sense. */
9967 proto_set_cant_toggle(proto_string_errors);
9968}
9969
9970static int
9971proto_register_field_init(header_field_info *hfinfo, const int parent)
9972{
9973
9974 tmp_fld_check_assert(hfinfo);
9975
9976 hfinfo->parent = parent;
9977 hfinfo->same_name_next = NULL((void*)0);
9978 hfinfo->same_name_prev_id = -1;
9979
9980 /* if we always add and never delete, then id == len - 1 is correct */
9981 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9982 if (!gpa_hfinfo.hfi) {
9983 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9984 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9985 /* The entry with index 0 is not used. */
9986 gpa_hfinfo.hfi[0] = NULL((void*)0);
9987 gpa_hfinfo.len = 1;
9988 } else {
9989 gpa_hfinfo.allocated_len += 1000;
9990 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9991 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9992 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9993 }
9994 }
9995 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9996 gpa_hfinfo.len++;
9997 hfinfo->id = gpa_hfinfo.len - 1;
9998
9999 /* if we have real names, enter this field in the name tree */
10000 /* Already checked in tmp_fld_check_assert */
10001 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10002 {
10003
10004 header_field_info *same_name_next_hfinfo;
10005
10006 /* We allow multiple hfinfo's to be registered under the same
10007 * abbreviation. This was done for X.25, as, depending
10008 * on whether it's modulo-8 or modulo-128 operation,
10009 * some bitfield fields may be in different bits of
10010 * a byte, and we want to be able to refer to that field
10011 * with one name regardless of whether the packets
10012 * are modulo-8 or modulo-128 packets. */
10013
10014 /* wmem_map_insert - if key is already present the previous
10015 * hfinfo with the same key/name is returned, otherwise NULL */
10016 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10017 if (same_name_hfinfo) {
10018 /* There's already a field with this name.
10019 * Put the current field *before* that field
10020 * in the list of fields with this name, Thus,
10021 * we end up with an effectively
10022 * doubly-linked-list of same-named hfinfo's,
10023 * with the head of the list (stored in the
10024 * hash) being the last seen hfinfo.
10025 */
10026 same_name_next_hfinfo =
10027 same_name_hfinfo->same_name_next;
10028
10029 hfinfo->same_name_next = same_name_next_hfinfo;
10030 if (same_name_next_hfinfo)
10031 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10032
10033 same_name_hfinfo->same_name_next = hfinfo;
10034 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10035#ifdef ENABLE_CHECK_FILTER
10036 while (same_name_hfinfo) {
10037 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10038 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", 10038
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10039 same_name_hfinfo = same_name_hfinfo->same_name_next;
10040 }
10041#endif
10042 }
10043 }
10044
10045 return hfinfo->id;
10046}
10047
10048void
10049proto_register_subtree_array(int * const *indices, const int num_indices)
10050{
10051 int i;
10052 int *const *ptr = indices;
10053
10054 /*
10055 * If we've already allocated the array of tree types, expand
10056 * it; this lets plugins such as mate add tree types after
10057 * the initial startup. (If we haven't already allocated it,
10058 * we don't allocate it; on the first pass, we just assign
10059 * ett values and keep track of how many we've assigned, and
10060 * when we're finished registering all dissectors we allocate
10061 * the array, so that we do only one allocation rather than
10062 * wasting CPU time and memory by growing the array for each
10063 * dissector that registers ett values.)
10064 */
10065 if (tree_is_expanded != NULL((void*)0)) {
10066 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10067
10068 /* set new items to 0 */
10069 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10070 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10071 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10072 }
10073
10074 /*
10075 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10076 * returning the indices through the pointers in the array whose
10077 * first element is pointed to by "indices", and update
10078 * "num_tree_types" appropriately.
10079 */
10080 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10081 if (**ptr != -1 && **ptr != 0) {
10082 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.")
10083 " 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.")
10084 " 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.")
10085 " 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.")
;
10086 }
10087 **ptr = num_tree_types;
10088 }
10089}
10090
10091static void
10092mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10093{
10094 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10095 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10096 char *last_char;
10097
10098 /* ..... field_name: dataaaaaaaaaaaaa
10099 * |
10100 * ^^^^^ name_pos
10101 *
10102 * ..... field_name […]: dataaaaaaaaaaaaa
10103 *
10104 * name_pos==0 means that we have only data or only a field_name
10105 */
10106
10107 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10107, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10108
10109 if (name_pos >= size - trunc_len) {
10110 /* No room for trunc_str after the field_name, put it first. */
10111 name_pos = 0;
10112 }
10113
10114 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10115 if (name_pos == 0) {
10116 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10117 memcpy(label_str, trunc_str + 1, trunc_len);
10118 } else {
10119 memcpy(label_str + name_pos, trunc_str, trunc_len);
10120 }
10121 /* in general, label_str is UTF-8
10122 we can truncate it only at the beginning of a new character
10123 we go backwards from the byte right after our buffer and
10124 find the next starting byte of a UTF-8 character, this is
10125 where we cut
10126 there's no need to use g_utf8_find_prev_char(), the search
10127 will always succeed since we copied trunc_str into the
10128 buffer */
10129 /* g_utf8_prev_char does not deference the memory address
10130 * passed in (until after decrementing it, so it is perfectly
10131 * legal to pass in a pointer one past the last element.
10132 */
10133 last_char = g_utf8_prev_char(label_str + size);
10134 *last_char = '\0';
10135 /* This is unnecessary (above always terminates), but try to
10136 * convince Coverity to avoid dozens of false positives. */
10137 label_str[size - 1] = '\0';
10138
10139 if (value_pos && *value_pos > 0) {
10140 if (name_pos == 0) {
10141 *value_pos += trunc_len;
10142 } else {
10143 /* Move one back to include trunc_str in the value. */
10144 *value_pos -= 1;
10145 }
10146 }
10147
10148 /* Check if value_pos is past label_str. */
10149 if (value_pos && *value_pos >= size) {
10150 *value_pos = size - 1;
10151 }
10152}
10153
10154static void
10155label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10156{
10157 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10158}
10159
10160static size_t
10161label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10162{
10163 size_t name_pos;
10164
10165 /* "%s: %s", hfinfo->name, text */
10166 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)
;
10167 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10168 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10169 if (value_pos) {
10170 *value_pos = pos;
10171 }
10172 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10173 }
10174
10175 if (pos >= ITEM_LABEL_LENGTH240) {
10176 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10177 label_mark_truncated(label_str, name_pos, value_pos);
10178 }
10179
10180 return pos;
10181}
10182
10183static size_t
10184label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10185{
10186 size_t name_pos;
10187
10188 /* "%s: %s (%s)", hfinfo->name, text, descr */
10189 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)
;
10190 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10191 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10192 if (value_pos) {
10193 *value_pos = pos;
10194 }
10195 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10196 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)
;
10197 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)
;
10198 } else {
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 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10201 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)
;
10202 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10203 }
10204 }
10205
10206 if (pos >= ITEM_LABEL_LENGTH240) {
10207 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10208 label_mark_truncated(label_str, name_pos, value_pos);
10209 }
10210
10211 return pos;
10212}
10213
10214void
10215proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10216{
10217 const header_field_info *hfinfo;
10218 const char *str;
10219 const uint8_t *bytes;
10220 uint32_t integer;
10221 const ipv4_addr_and_mask *ipv4;
10222 const ipv6_addr_and_prefix *ipv6;
10223 const e_guid_t *guid;
10224 char *name;
10225 address addr;
10226 char *addr_str;
10227 char *tmp;
10228
10229 if (!label_str) {
10230 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10230, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10231 return;
10232 }
10233
10234 label_str[0]= '\0';
10235
10236 if (!fi) {
10237 return;
10238 }
10239
10240 hfinfo = fi->hfinfo;
10241
10242 switch (hfinfo->type) {
10243 case FT_NONE:
10244 case FT_PROTOCOL:
10245 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10246 if (value_pos) {
10247 *value_pos = strlen(hfinfo->name);
10248 }
10249 break;
10250
10251 case FT_BOOLEAN:
10252 fill_label_boolean(fi, label_str, value_pos);
10253 break;
10254
10255 case FT_BYTES:
10256 case FT_UINT_BYTES:
10257 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10258 fvalue_get_bytes_data(fi->value),
10259 (unsigned)fvalue_length2(fi->value));
10260 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10261 wmem_free(NULL((void*)0), tmp);
10262 break;
10263
10264 case FT_CHAR:
10265 if (hfinfo->bitmask) {
10266 fill_label_bitfield_char(fi, label_str, value_pos);
10267 } else {
10268 fill_label_char(fi, label_str, value_pos);
10269 }
10270 break;
10271
10272 /* Four types of integers to take care of:
10273 * Bitfield, with val_string
10274 * Bitfield, w/o val_string
10275 * Non-bitfield, with val_string
10276 * Non-bitfield, w/o val_string
10277 */
10278 case FT_UINT8:
10279 case FT_UINT16:
10280 case FT_UINT24:
10281 case FT_UINT32:
10282 if (hfinfo->bitmask) {
10283 fill_label_bitfield(fi, label_str, value_pos, false0);
10284 } else {
10285 fill_label_number(fi, label_str, value_pos, false0);
10286 }
10287 break;
10288
10289 case FT_FRAMENUM:
10290 fill_label_number(fi, label_str, value_pos, false0);
10291 break;
10292
10293 case FT_UINT40:
10294 case FT_UINT48:
10295 case FT_UINT56:
10296 case FT_UINT64:
10297 if (hfinfo->bitmask) {
10298 fill_label_bitfield64(fi, label_str, value_pos, false0);
10299 } else {
10300 fill_label_number64(fi, label_str, value_pos, false0);
10301 }
10302 break;
10303
10304 case FT_INT8:
10305 case FT_INT16:
10306 case FT_INT24:
10307 case FT_INT32:
10308 if (hfinfo->bitmask) {
10309 fill_label_bitfield(fi, label_str, value_pos, true1);
10310 } else {
10311 fill_label_number(fi, label_str, value_pos, true1);
10312 }
10313 break;
10314
10315 case FT_INT40:
10316 case FT_INT48:
10317 case FT_INT56:
10318 case FT_INT64:
10319 if (hfinfo->bitmask) {
10320 fill_label_bitfield64(fi, label_str, value_pos, true1);
10321 } else {
10322 fill_label_number64(fi, label_str, value_pos, true1);
10323 }
10324 break;
10325
10326 case FT_FLOAT:
10327 case FT_DOUBLE:
10328 fill_label_float(fi, label_str, value_pos);
10329 break;
10330
10331 case FT_ABSOLUTE_TIME:
10332 {
10333 const nstime_t *value = fvalue_get_time(fi->value);
10334 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10335 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10336 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10337 }
10338 if (hfinfo->strings) {
10339 /*
10340 * Table of time valus to be displayed
10341 * specially.
10342 */
10343 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10344 if (time_string != NULL((void*)0)) {
10345 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10346 break;
10347 }
10348 }
10349 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10350 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10351 wmem_free(NULL((void*)0), tmp);
10352 break;
10353 }
10354 case FT_RELATIVE_TIME:
10355 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10356 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10357 wmem_free(NULL((void*)0), tmp);
10358 break;
10359
10360 case FT_IPXNET:
10361 integer = fvalue_get_uinteger(fi->value);
10362 tmp = get_ipxnet_name(NULL((void*)0), integer);
10363 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10364 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10365 wmem_free(NULL((void*)0), tmp);
10366 wmem_free(NULL((void*)0), addr_str);
10367 break;
10368
10369 case FT_VINES:
10370 addr.type = AT_VINES;
10371 addr.len = VINES_ADDR_LEN6;
10372 addr.data = fvalue_get_bytes_data(fi->value);
10373
10374 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10375 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10376 wmem_free(NULL((void*)0), addr_str);
10377 break;
10378
10379 case FT_ETHER:
10380 bytes = fvalue_get_bytes_data(fi->value);
10381
10382 addr.type = AT_ETHER;
10383 addr.len = 6;
10384 addr.data = bytes;
10385
10386 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10387 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10388 wmem_free(NULL((void*)0), addr_str);
10389 break;
10390
10391 case FT_IPv4:
10392 ipv4 = fvalue_get_ipv4(fi->value);
10393 set_address_ipv4(&addr, ipv4);
10394
10395 if (hfinfo->display == BASE_NETMASK) {
10396 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10397 } else {
10398 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10399 }
10400 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10401 wmem_free(NULL((void*)0), addr_str);
10402 free_address(&addr);
10403 break;
10404
10405 case FT_IPv6:
10406 ipv6 = fvalue_get_ipv6(fi->value);
10407 set_address_ipv6(&addr, ipv6);
10408
10409 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10410 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10411 wmem_free(NULL((void*)0), addr_str);
10412 free_address(&addr);
10413 break;
10414
10415 case FT_FCWWN:
10416 bytes = fvalue_get_bytes_data(fi->value);
10417 addr.type = AT_FCWWN;
10418 addr.len = FCWWN_ADDR_LEN8;
10419 addr.data = bytes;
10420
10421 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10422 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10423 wmem_free(NULL((void*)0), addr_str);
10424 break;
10425
10426 case FT_GUID:
10427 guid = fvalue_get_guid(fi->value);
10428 tmp = guid_to_str(NULL((void*)0), guid);
10429 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10430 wmem_free(NULL((void*)0), tmp);
10431 break;
10432
10433 case FT_OID:
10434 bytes = fvalue_get_bytes_data(fi->value);
10435 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10436 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10437 if (name) {
10438 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10439 wmem_free(NULL((void*)0), name);
10440 } else {
10441 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10442 }
10443 wmem_free(NULL((void*)0), tmp);
10444 break;
10445
10446 case FT_REL_OID:
10447 bytes = fvalue_get_bytes_data(fi->value);
10448 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10449 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10450 if (name) {
10451 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10452 wmem_free(NULL((void*)0), name);
10453 } else {
10454 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10455 }
10456 wmem_free(NULL((void*)0), tmp);
10457 break;
10458
10459 case FT_SYSTEM_ID:
10460 bytes = fvalue_get_bytes_data(fi->value);
10461 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10462 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10463 wmem_free(NULL((void*)0), tmp);
10464 break;
10465
10466 case FT_EUI64:
10467 bytes = fvalue_get_bytes_data(fi->value);
10468 addr.type = AT_EUI64;
10469 addr.len = EUI64_ADDR_LEN8;
10470 addr.data = bytes;
10471
10472 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10473 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10474 wmem_free(NULL((void*)0), addr_str);
10475 break;
10476 case FT_STRING:
10477 case FT_STRINGZ:
10478 case FT_UINT_STRING:
10479 case FT_STRINGZPAD:
10480 case FT_STRINGZTRUNC:
10481 case FT_AX25:
10482 str = fvalue_get_string(fi->value);
10483 label_fill(label_str, 0, hfinfo, str, value_pos);
10484 break;
10485
10486 case FT_IEEE_11073_SFLOAT:
10487 case FT_IEEE_11073_FLOAT:
10488 fill_label_ieee_11073_float(fi, label_str, value_pos);
10489 break;
10490
10491 default:
10492 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
))
10493 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
))
10494 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
))
10495 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
))
;
10496 break;
10497 }
10498}
10499
10500static void
10501fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10502{
10503 char *p;
10504 int bitfield_byte_length = 0, bitwidth;
10505 uint64_t unshifted_value;
10506 uint64_t value;
10507
10508 const header_field_info *hfinfo = fi->hfinfo;
10509
10510 value = fvalue_get_uinteger64(fi->value);
10511 if (hfinfo->bitmask) {
10512 /* Figure out the bit width */
10513 bitwidth = hfinfo_container_bitwidth(hfinfo);
10514
10515 /* Un-shift bits */
10516 unshifted_value = value;
10517 unshifted_value <<= hfinfo_bitshift(hfinfo);
10518
10519 /* Create the bitfield first */
10520 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10521 bitfield_byte_length = (int) (p - label_str);
10522 }
10523
10524 /* Fill in the textual info */
10525 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10526}
10527
10528static const char *
10529hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10530{
10531 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10532 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10533
10534 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10535 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10536 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10537 else
10538 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10539 }
10540
10541 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10542 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10543
10544 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10545 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10546
10547 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10548}
10549
10550static const char *
10551hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10552{
10553 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10554 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10555 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10556 else
10557 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10558 }
10559
10560 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10561 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10562
10563 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10564 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10565
10566 /* If this is reached somebody registered a 64-bit field with a 32-bit
10567 * value-string, which isn't right. */
10568 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)
10569 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10570
10571 /* This is necessary to squelch MSVC errors; is there
10572 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10573 never returns? */
10574 return NULL((void*)0);
10575}
10576
10577static const char *
10578hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10579{
10580 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10581 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10582
10583 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)
;
10584
10585 /* This is necessary to squelch MSVC errors; is there
10586 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10587 never returns? */
10588 return NULL((void*)0);
10589}
10590
10591static const char *
10592hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10593{
10594 const char *str = hf_try_val_to_str(value, hfinfo);
10595
10596 return (str) ? str : unknown_str;
10597}
10598
10599static const char *
10600hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10601{
10602 const char *str = hf_try_val64_to_str(value, hfinfo);
10603
10604 return (str) ? str : unknown_str;
10605}
10606
10607/* Fills data for bitfield chars with val_strings */
10608static void
10609fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10610{
10611 char *p;
10612 int bitfield_byte_length, bitwidth;
10613 uint32_t unshifted_value;
10614 uint32_t value;
10615
10616 char buf[32];
10617 const char *out;
10618
10619 const header_field_info *hfinfo = fi->hfinfo;
10620
10621 /* Figure out the bit width */
10622 bitwidth = hfinfo_container_bitwidth(hfinfo);
10623
10624 /* Un-shift bits */
10625 value = fvalue_get_uinteger(fi->value);
10626
10627 unshifted_value = value;
10628 if (hfinfo->bitmask) {
10629 unshifted_value <<= hfinfo_bitshift(hfinfo);
10630 }
10631
10632 /* Create the bitfield first */
10633 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10634 bitfield_byte_length = (int) (p - label_str);
10635
10636 /* Fill in the textual info using stored (shifted) value */
10637 if (hfinfo->display == BASE_CUSTOM) {
10638 char tmp[ITEM_LABEL_LENGTH240];
10639 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10640
10641 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10641, "fmtfunc"))))
;
10642 fmtfunc(tmp, value);
10643 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10644 }
10645 else if (hfinfo->strings) {
10646 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10647
10648 out = hfinfo_char_vals_format(hfinfo, buf, value);
10649 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10650 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10651 else
10652 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10653 }
10654 else {
10655 out = hfinfo_char_value_format(hfinfo, buf, value);
10656
10657 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10658 }
10659}
10660
10661/* Fills data for bitfield ints with val_strings */
10662static void
10663fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10664{
10665 char *p;
10666 int bitfield_byte_length, bitwidth;
10667 uint32_t value, unshifted_value;
10668 char buf[NUMBER_LABEL_LENGTH80];
10669 const char *out;
10670
10671 const header_field_info *hfinfo = fi->hfinfo;
10672
10673 /* Figure out the bit width */
10674 if (fi->flags & FI_VARINT0x00040000)
10675 bitwidth = fi->length*8;
10676 else
10677 bitwidth = hfinfo_container_bitwidth(hfinfo);
10678
10679 /* Un-shift bits */
10680 if (is_signed)
10681 value = fvalue_get_sinteger(fi->value);
10682 else
10683 value = fvalue_get_uinteger(fi->value);
10684
10685 unshifted_value = value;
10686 if (hfinfo->bitmask) {
10687 unshifted_value <<= hfinfo_bitshift(hfinfo);
10688 }
10689
10690 /* Create the bitfield first */
10691 if (fi->flags & FI_VARINT0x00040000)
10692 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10693 else
10694 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10695 bitfield_byte_length = (int) (p - label_str);
10696
10697 /* Fill in the textual info using stored (shifted) value */
10698 if (hfinfo->display == BASE_CUSTOM) {
10699 char tmp[ITEM_LABEL_LENGTH240];
10700 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10701
10702 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10702, "fmtfunc"))))
;
10703 fmtfunc(tmp, value);
10704 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10705 }
10706 else if (hfinfo->strings) {
10707 const char *val_str = hf_try_val_to_str(value, hfinfo);
10708
10709 out = hfinfo_number_vals_format(hfinfo, buf, value);
10710 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10711 /*
10712 * Unique values only display value_string string
10713 * if there is a match. Otherwise it's just a number
10714 */
10715 if (val_str) {
10716 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10717 } else {
10718 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10719 }
10720 } else {
10721 if (val_str == NULL((void*)0))
10722 val_str = "Unknown";
10723
10724 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10725 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10726 else
10727 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10728 }
10729 }
10730 else {
10731 out = hfinfo_number_value_format(hfinfo, buf, value);
10732
10733 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10734 }
10735}
10736
10737static void
10738fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10739{
10740 char *p;
10741 int bitfield_byte_length, bitwidth;
10742 uint64_t value, unshifted_value;
10743 char buf[NUMBER_LABEL_LENGTH80];
10744 const char *out;
10745
10746 const header_field_info *hfinfo = fi->hfinfo;
10747
10748 /* Figure out the bit width */
10749 if (fi->flags & FI_VARINT0x00040000)
10750 bitwidth = fi->length*8;
10751 else
10752 bitwidth = hfinfo_container_bitwidth(hfinfo);
10753
10754 /* Un-shift bits */
10755 if (is_signed)
10756 value = fvalue_get_sinteger64(fi->value);
10757 else
10758 value = fvalue_get_uinteger64(fi->value);
10759
10760 unshifted_value = value;
10761 if (hfinfo->bitmask) {
10762 unshifted_value <<= hfinfo_bitshift(hfinfo);
10763 }
10764
10765 /* Create the bitfield first */
10766 if (fi->flags & FI_VARINT0x00040000)
10767 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10768 else
10769 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10770 bitfield_byte_length = (int) (p - label_str);
10771
10772 /* Fill in the textual info using stored (shifted) value */
10773 if (hfinfo->display == BASE_CUSTOM) {
10774 char tmp[ITEM_LABEL_LENGTH240];
10775 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10776
10777 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10777, "fmtfunc64"
))))
;
10778 fmtfunc64(tmp, value);
10779 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10780 }
10781 else if (hfinfo->strings) {
10782 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10783
10784 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10785 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10786 /*
10787 * Unique values only display value_string string
10788 * if there is a match. Otherwise it's just a number
10789 */
10790 if (val_str) {
10791 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10792 } else {
10793 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10794 }
10795 } else {
10796 if (val_str == NULL((void*)0))
10797 val_str = "Unknown";
10798
10799 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10800 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10801 else
10802 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10803 }
10804 }
10805 else {
10806 out = hfinfo_number_value_format64(hfinfo, buf, value);
10807
10808 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10809 }
10810}
10811
10812static void
10813fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10814{
10815 const header_field_info *hfinfo = fi->hfinfo;
10816 uint32_t value;
10817
10818 char buf[32];
10819 const char *out;
10820
10821 value = fvalue_get_uinteger(fi->value);
10822
10823 /* Fill in the textual info */
10824 if (hfinfo->display == BASE_CUSTOM) {
10825 char tmp[ITEM_LABEL_LENGTH240];
10826 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10827
10828 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10828, "fmtfunc"))))
;
10829 fmtfunc(tmp, value);
10830 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10831 }
10832 else if (hfinfo->strings) {
10833 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10834
10835 out = hfinfo_char_vals_format(hfinfo, buf, value);
10836 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10837 }
10838 else {
10839 out = hfinfo_char_value_format(hfinfo, buf, value);
10840
10841 label_fill(label_str, 0, hfinfo, out, value_pos);
10842 }
10843}
10844
10845static void
10846fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10847{
10848 const header_field_info *hfinfo = fi->hfinfo;
10849 uint32_t value;
10850
10851 char buf[NUMBER_LABEL_LENGTH80];
10852 const char *out;
10853
10854 if (is_signed)
10855 value = fvalue_get_sinteger(fi->value);
10856 else
10857 value = fvalue_get_uinteger(fi->value);
10858
10859 /* Fill in the textual info */
10860 if (hfinfo->display == BASE_CUSTOM) {
10861 char tmp[ITEM_LABEL_LENGTH240];
10862 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10863
10864 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10864, "fmtfunc"))))
;
10865 fmtfunc(tmp, value);
10866 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10867 }
10868 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10869 /*
10870 * It makes no sense to have a value-string table for a
10871 * frame-number field - they're just integers giving
10872 * the ordinal frame number.
10873 */
10874 const char *val_str = hf_try_val_to_str(value, hfinfo);
10875
10876 out = hfinfo_number_vals_format(hfinfo, buf, value);
10877 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10878 /*
10879 * Unique values only display value_string string
10880 * if there is a match. Otherwise it's just a number
10881 */
10882 if (val_str) {
10883 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10884 } else {
10885 label_fill(label_str, 0, hfinfo, out, value_pos);
10886 }
10887 } else {
10888 if (val_str == NULL((void*)0))
10889 val_str = "Unknown";
10890
10891 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10892 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10893 else
10894 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10895 }
10896 }
10897 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
))
) {
10898 char tmp[ITEM_LABEL_LENGTH240];
10899
10900 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10901 display_to_port_type((field_display_e)hfinfo->display), value);
10902 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10903 }
10904 else {
10905 out = hfinfo_number_value_format(hfinfo, buf, value);
10906
10907 label_fill(label_str, 0, hfinfo, out, value_pos);
10908 }
10909}
10910
10911static void
10912fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10913{
10914 const header_field_info *hfinfo = fi->hfinfo;
10915 uint64_t value;
10916
10917 char buf[NUMBER_LABEL_LENGTH80];
10918 const char *out;
10919
10920 if (is_signed)
10921 value = fvalue_get_sinteger64(fi->value);
10922 else
10923 value = fvalue_get_uinteger64(fi->value);
10924
10925 /* Fill in the textual info */
10926 if (hfinfo->display == BASE_CUSTOM) {
10927 char tmp[ITEM_LABEL_LENGTH240];
10928 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10929
10930 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10930, "fmtfunc64"
))))
;
10931 fmtfunc64(tmp, value);
10932 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10933 }
10934 else if (hfinfo->strings) {
10935 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10936
10937 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10938 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10939 /*
10940 * Unique values only display value_string string
10941 * if there is a match. Otherwise it's just a number
10942 */
10943 if (val_str) {
10944 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10945 } else {
10946 label_fill(label_str, 0, hfinfo, out, value_pos);
10947 }
10948 } else {
10949 if (val_str == NULL((void*)0))
10950 val_str = "Unknown";
10951
10952 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10953 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10954 else
10955 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10956 }
10957 }
10958 else {
10959 out = hfinfo_number_value_format64(hfinfo, buf, value);
10960
10961 label_fill(label_str, 0, hfinfo, out, value_pos);
10962 }
10963}
10964
10965static size_t
10966fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10967{
10968 int display;
10969 int n;
10970 double value;
10971
10972 if (label_str_size < 12) {
10973 /* Not enough room to write an entire floating point value. */
10974 return 0;
10975 }
10976
10977 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10978 value = fvalue_get_floating(fi->value);
10979
10980 if (display == BASE_CUSTOM) {
10981 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10982 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10982, "fmtfunc"))))
;
10983 fmtfunc(label_str, value);
10984 return strlen(label_str);
10985 }
10986
10987 switch (display) {
10988 case BASE_NONE:
10989 if (fi->hfinfo->type == FT_FLOAT) {
10990 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10991 } else {
10992 n = (int)strlen(dtoa_g_fmt(label_str, value));
10993 }
10994 break;
10995 case BASE_DEC:
10996 n = snprintf(label_str, label_str_size, "%f", value);
10997 break;
10998 case BASE_HEX:
10999 n = snprintf(label_str, label_str_size, "%a", value);
11000 break;
11001 case BASE_EXP:
11002 n = snprintf(label_str, label_str_size, "%e", value);
11003 break;
11004 default:
11005 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11005
, __func__, "assertion \"not reached\" failed")
;
11006 }
11007 if (n < 0) {
11008 return 0; /* error */
11009 }
11010 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11011 const char *hf_str_val;
11012 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11013 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11014 }
11015 if (n > label_str_size) {
11016 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11016, __func__, "label length too small"); } } while (0)
;
11017 return strlen(label_str);
11018 }
11019
11020 return n;
11021}
11022
11023void
11024fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11025{
11026 char tmp[ITEM_LABEL_LENGTH240];
11027
11028 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11029 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11030}
11031
11032static size_t
11033fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11034{
11035 int display;
11036 size_t pos = 0;
11037 double value;
11038 char* tmp_str;
11039
11040 if (label_str_size < 12) {
11041 /* Not enough room to write an entire floating point value. */
11042 return 0;
11043 }
11044
11045 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11046 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11047 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11048 wmem_free(NULL((void*)0), tmp_str);
11049
11050 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11051 const char *hf_str_val;
11052 fvalue_to_double(fi->value, &value);
11053 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11054 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)
;
11055 }
11056 if ((int)pos > label_str_size) {
11057 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11057, __func__, "label length too small"); } } while (0)
;
11058 return strlen(label_str);
11059 }
11060
11061 return pos;
11062}
11063
11064void
11065fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11066{
11067 char tmp[ITEM_LABEL_LENGTH240];
11068
11069 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11070 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11071}
11072
11073int
11074hfinfo_bitshift(const header_field_info *hfinfo)
11075{
11076 return ws_ctz(hfinfo->bitmask);
11077}
11078
11079
11080static int
11081hfinfo_bitoffset(const header_field_info *hfinfo)
11082{
11083 if (!hfinfo->bitmask) {
11084 return 0;
11085 }
11086
11087 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11088 * as the first bit */
11089 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11090}
11091
11092static int
11093hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11094{
11095 if (!hfinfo->bitmask) {
11096 return 0;
11097 }
11098
11099 /* ilog2 = first set bit, ctz = last set bit */
11100 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11101}
11102
11103static int
11104hfinfo_type_bitwidth(enum ftenum type)
11105{
11106 int bitwidth = 0;
11107
11108 switch (type) {
11109 case FT_CHAR:
11110 case FT_UINT8:
11111 case FT_INT8:
11112 bitwidth = 8;
11113 break;
11114 case FT_UINT16:
11115 case FT_INT16:
11116 bitwidth = 16;
11117 break;
11118 case FT_UINT24:
11119 case FT_INT24:
11120 bitwidth = 24;
11121 break;
11122 case FT_UINT32:
11123 case FT_INT32:
11124 bitwidth = 32;
11125 break;
11126 case FT_UINT40:
11127 case FT_INT40:
11128 bitwidth = 40;
11129 break;
11130 case FT_UINT48:
11131 case FT_INT48:
11132 bitwidth = 48;
11133 break;
11134 case FT_UINT56:
11135 case FT_INT56:
11136 bitwidth = 56;
11137 break;
11138 case FT_UINT64:
11139 case FT_INT64:
11140 bitwidth = 64;
11141 break;
11142 default:
11143 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11143))
;
11144 ;
11145 }
11146 return bitwidth;
11147}
11148
11149
11150static int
11151hfinfo_container_bitwidth(const header_field_info *hfinfo)
11152{
11153 if (!hfinfo->bitmask) {
11154 return 0;
11155 }
11156
11157 if (hfinfo->type == FT_BOOLEAN) {
11158 return hfinfo->display; /* hacky? :) */
11159 }
11160
11161 return hfinfo_type_bitwidth(hfinfo->type);
11162}
11163
11164static int
11165hfinfo_hex_digits(const header_field_info *hfinfo)
11166{
11167 int bitwidth;
11168
11169 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11170 * appropriate to determine the number of hex digits for the field.
11171 * So instead, we compute it from the bitmask.
11172 */
11173 if (hfinfo->bitmask != 0) {
11174 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11175 } else {
11176 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11177 }
11178
11179 /* Divide by 4, rounding up, to get number of hex digits. */
11180 return (bitwidth + 3) / 4;
11181}
11182
11183const char *
11184hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11185{
11186 char *ptr = &buf[6];
11187 static const char hex_digits[16] =
11188 { '0', '1', '2', '3', '4', '5', '6', '7',
11189 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11190
11191 *ptr = '\0';
11192 *(--ptr) = '\'';
11193 /* Properly format value */
11194 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11195 /*
11196 * Printable, so just show the character, and, if it needs
11197 * to be escaped, escape it.
11198 */
11199 *(--ptr) = value;
11200 if (value == '\\' || value == '\'')
11201 *(--ptr) = '\\';
11202 } else {
11203 /*
11204 * Non-printable; show it as an escape sequence.
11205 */
11206 switch (value) {
11207
11208 case '\0':
11209 /*
11210 * Show a NUL with only one digit.
11211 */
11212 *(--ptr) = '0';
11213 break;
11214
11215 case '\a':
11216 case '\b':
11217 case '\f':
11218 case '\n':
11219 case '\r':
11220 case '\t':
11221 case '\v':
11222 *(--ptr) = value - '\a' + 'a';
11223 break;
11224
11225 default:
11226 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11227
11228 case BASE_OCT:
11229 *(--ptr) = (value & 0x7) + '0';
11230 value >>= 3;
11231 *(--ptr) = (value & 0x7) + '0';
11232 value >>= 3;
11233 *(--ptr) = (value & 0x7) + '0';
11234 break;
11235
11236 case BASE_HEX:
11237 *(--ptr) = hex_digits[value & 0x0F];
11238 value >>= 4;
11239 *(--ptr) = hex_digits[value & 0x0F];
11240 *(--ptr) = 'x';
11241 break;
11242
11243 default:
11244 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11245 }
11246 }
11247 *(--ptr) = '\\';
11248 }
11249 *(--ptr) = '\'';
11250 return ptr;
11251}
11252
11253static const char *
11254hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11255{
11256 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11257 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
))
;
11258
11259 *ptr = '\0';
11260 /* Properly format value */
11261 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11262 case BASE_DEC:
11263 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11264
11265 case BASE_DEC_HEX:
11266 *(--ptr) = ')';
11267 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11268 *(--ptr) = '(';
11269 *(--ptr) = ' ';
11270 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11271 return ptr;
11272
11273 case BASE_OCT:
11274 return oct_to_str_back(ptr, value);
11275
11276 case BASE_HEX:
11277 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11278
11279 case BASE_HEX_DEC:
11280 *(--ptr) = ')';
11281 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11282 *(--ptr) = '(';
11283 *(--ptr) = ' ';
11284 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11285 return ptr;
11286
11287 case BASE_PT_UDP:
11288 case BASE_PT_TCP:
11289 case BASE_PT_DCCP:
11290 case BASE_PT_SCTP:
11291 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11292 display_to_port_type((field_display_e)display), value);
11293 return buf;
11294 case BASE_OUI:
11295 {
11296 uint8_t p_oui[3];
11297 const char *manuf_name;
11298
11299 p_oui[0] = value >> 16 & 0xFF;
11300 p_oui[1] = value >> 8 & 0xFF;
11301 p_oui[2] = value & 0xFF;
11302
11303 /* Attempt an OUI lookup. */
11304 manuf_name = uint_get_manuf_name_if_known(value);
11305 if (manuf_name == NULL((void*)0)) {
11306 /* Could not find an OUI. */
11307 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11308 }
11309 else {
11310 /* Found an address string. */
11311 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11312 }
11313 return buf;
11314 }
11315
11316 default:
11317 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11318 }
11319 return ptr;
11320}
11321
11322static const char *
11323hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11324{
11325 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11326 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
))
;
11327
11328 *ptr = '\0';
11329 /* Properly format value */
11330 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11331 case BASE_DEC:
11332 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11333
11334 case BASE_DEC_HEX:
11335 *(--ptr) = ')';
11336 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11337 *(--ptr) = '(';
11338 *(--ptr) = ' ';
11339 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11340 return ptr;
11341
11342 case BASE_OCT:
11343 return oct64_to_str_back(ptr, value);
11344
11345 case BASE_HEX:
11346 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11347
11348 case BASE_HEX_DEC:
11349 *(--ptr) = ')';
11350 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11351 *(--ptr) = '(';
11352 *(--ptr) = ' ';
11353 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11354 return ptr;
11355
11356 default:
11357 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11358 }
11359
11360 return ptr;
11361}
11362
11363static const char *
11364hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11365{
11366 int display = hfinfo->display;
11367
11368 if (hfinfo->type == FT_FRAMENUM) {
11369 /*
11370 * Frame numbers are always displayed in decimal.
11371 */
11372 display = BASE_DEC;
11373 }
11374
11375 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11376}
11377
11378static const char *
11379hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11380{
11381 int display = hfinfo->display;
11382
11383 if (hfinfo->type == FT_FRAMENUM) {
11384 /*
11385 * Frame numbers are always displayed in decimal.
11386 */
11387 display = BASE_DEC;
11388 }
11389
11390 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11391}
11392
11393static const char *
11394hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11395{
11396 /* Get the underlying BASE_ value */
11397 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11398
11399 return hfinfo_char_value_format_display(display, buf, value);
11400}
11401
11402static const char *
11403hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11404{
11405 /* Get the underlying BASE_ value */
11406 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11407
11408 if (hfinfo->type == FT_FRAMENUM) {
11409 /*
11410 * Frame numbers are always displayed in decimal.
11411 */
11412 display = BASE_DEC;
11413 }
11414
11415 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11416 display = BASE_DEC;
11417 } else if (display == BASE_OUI) {
11418 display = BASE_HEX;
11419 }
11420
11421 switch (display) {
11422 case BASE_NONE:
11423 /* case BASE_DEC: */
11424 case BASE_DEC_HEX:
11425 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11426 case BASE_CUSTOM:
11427 display = BASE_DEC;
11428 break;
11429
11430 /* case BASE_HEX: */
11431 case BASE_HEX_DEC:
11432 display = BASE_HEX;
11433 break;
11434 }
11435
11436 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11437}
11438
11439static const char *
11440hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11441{
11442 /* Get the underlying BASE_ value */
11443 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11444
11445 if (hfinfo->type == FT_FRAMENUM) {
11446 /*
11447 * Frame numbers are always displayed in decimal.
11448 */
11449 display = BASE_DEC;
11450 }
11451
11452 switch (display) {
11453 case BASE_NONE:
11454 /* case BASE_DEC: */
11455 case BASE_DEC_HEX:
11456 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11457 case BASE_CUSTOM:
11458 display = BASE_DEC;
11459 break;
11460
11461 /* case BASE_HEX: */
11462 case BASE_HEX_DEC:
11463 display = BASE_HEX;
11464 break;
11465 }
11466
11467 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11468}
11469
11470static const char *
11471hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11472{
11473 /* Get the underlying BASE_ value */
11474 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11475
11476 return hfinfo_char_value_format_display(display, buf, value);
11477}
11478
11479static const char *
11480hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11481{
11482 /* Get the underlying BASE_ value */
11483 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11484
11485 if (display == BASE_NONE)
11486 return NULL((void*)0);
11487
11488 if (display == BASE_DEC_HEX)
11489 display = BASE_DEC;
11490 if (display == BASE_HEX_DEC)
11491 display = BASE_HEX;
11492
11493 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11494}
11495
11496static const char *
11497hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11498{
11499 /* Get the underlying BASE_ value */
11500 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11501
11502 if (display == BASE_NONE)
11503 return NULL((void*)0);
11504
11505 if (display == BASE_DEC_HEX)
11506 display = BASE_DEC;
11507 if (display == BASE_HEX_DEC)
11508 display = BASE_HEX;
11509
11510 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11511}
11512
11513const char *
11514proto_registrar_get_name(const int n)
11515{
11516 header_field_info *hfinfo;
11517
11518 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", 11518
, __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", 11518
, "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", 11518, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11519 return hfinfo->name;
11520}
11521
11522const char *
11523proto_registrar_get_abbrev(const int n)
11524{
11525 header_field_info *hfinfo;
11526
11527 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", 11527
, __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", 11527
, "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", 11527, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11528 return hfinfo->abbrev;
11529}
11530
11531enum ftenum
11532proto_registrar_get_ftype(const int n)
11533{
11534 header_field_info *hfinfo;
11535
11536 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", 11536
, __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", 11536
, "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", 11536, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11537 return hfinfo->type;
11538}
11539
11540int
11541proto_registrar_get_parent(const int n)
11542{
11543 header_field_info *hfinfo;
11544
11545 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", 11545
, __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", 11545
, "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", 11545, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11546 return hfinfo->parent;
11547}
11548
11549bool_Bool
11550proto_registrar_is_protocol(const int n)
11551{
11552 header_field_info *hfinfo;
11553
11554 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", 11554
, __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", 11554
, "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", 11554, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11555 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11556}
11557
11558/* Returns length of field in packet (not necessarily the length
11559 * in our internal representation, as in the case of IPv4).
11560 * 0 means undeterminable at time of registration
11561 * -1 means the field is not registered. */
11562int
11563proto_registrar_get_length(const int n)
11564{
11565 header_field_info *hfinfo;
11566
11567 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", 11567
, __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", 11567
, "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", 11567, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11568 return ftype_wire_size(hfinfo->type);
11569}
11570
11571size_t
11572proto_registrar_get_count(struct proto_registrar_stats *stats)
11573{
11574 header_field_info *hfinfo;
11575
11576 // Index zero is not used. We have to skip it.
11577 size_t total_count = gpa_hfinfo.len - 1;
11578 if (stats == NULL((void*)0)) {
11579 return total_count;
11580 }
11581 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11582 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11583 stats->deregistered_count++;
11584 continue; /* This is a deregistered protocol or header field */
11585 }
11586
11587 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", 11587
, __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", 11587, "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", 11587, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11588
11589 if (proto_registrar_is_protocol(id))
11590 stats->protocol_count++;
11591
11592 if (hfinfo->same_name_prev_id != -1)
11593 stats->same_name_count++;
11594 }
11595
11596 return total_count;
11597}
11598
11599/* Looks for a protocol or a field in a proto_tree. Returns true if
11600 * it exists anywhere, or false if it exists nowhere. */
11601bool_Bool
11602proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11603{
11604 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11605
11606 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11607 return true1;
11608 }
11609 else {
11610 return false0;
11611 }
11612}
11613
11614/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11615 * This only works if the hfindex was "primed" before the dissection
11616 * took place, as we just pass back the already-created GPtrArray*.
11617 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11618 * handles that. */
11619GPtrArray *
11620proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11621{
11622 if (!tree)
11623 return NULL((void*)0);
11624
11625 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11626 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11627 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11628 else
11629 return NULL((void*)0);
11630}
11631
11632bool_Bool
11633proto_tracking_interesting_fields(const proto_tree *tree)
11634{
11635 GHashTable *interesting_hfids;
11636
11637 if (!tree)
11638 return false0;
11639
11640 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11641
11642 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11643}
11644
11645/* Helper struct for proto_find_info() and proto_all_finfos() */
11646typedef struct {
11647 GPtrArray *array;
11648 int id;
11649} ffdata_t;
11650
11651/* Helper function for proto_find_info() */
11652static bool_Bool
11653find_finfo(proto_node *node, void * data)
11654{
11655 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11656 if (fi && fi->hfinfo) {
11657 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11658 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11659 }
11660 }
11661
11662 /* Don't stop traversing. */
11663 return false0;
11664}
11665
11666/* Helper function for proto_find_first_info() */
11667static bool_Bool
11668find_first_finfo(proto_node *node, void *data)
11669{
11670 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11671 if (fi && fi->hfinfo) {
11672 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11673 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11674
11675 /* Stop traversing. */
11676 return true1;
11677 }
11678 }
11679
11680 /* Continue traversing. */
11681 return false0;
11682}
11683
11684/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11685* This works on any proto_tree, primed or unprimed, but actually searches
11686* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11687* The caller does need to free the returned GPtrArray with
11688* g_ptr_array_free(<array>, true).
11689*/
11690GPtrArray *
11691proto_find_finfo(proto_tree *tree, const int id)
11692{
11693 ffdata_t ffdata;
11694
11695 ffdata.array = g_ptr_array_new();
11696 ffdata.id = id;
11697
11698 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11699
11700 return ffdata.array;
11701}
11702
11703/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11704* This works on any proto_tree, primed or unprimed, but actually searches
11705* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11706* The caller does need to free the returned GPtrArray with
11707* g_ptr_array_free(<array>, true).
11708*/
11709GPtrArray *
11710proto_find_first_finfo(proto_tree *tree, const int id)
11711{
11712 ffdata_t ffdata;
11713
11714 ffdata.array = g_ptr_array_new();
11715 ffdata.id = id;
11716
11717 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11718
11719 return ffdata.array;
11720}
11721
11722/* Helper function for proto_all_finfos() */
11723static bool_Bool
11724every_finfo(proto_node *node, void * data)
11725{
11726 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11727 if (fi && fi->hfinfo) {
11728 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11729 }
11730
11731 /* Don't stop traversing. */
11732 return false0;
11733}
11734
11735/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11736 * The caller does need to free the returned GPtrArray with
11737 * g_ptr_array_free(<array>, true).
11738 */
11739GPtrArray *
11740proto_all_finfos(proto_tree *tree)
11741{
11742 ffdata_t ffdata;
11743
11744 /* Pre allocate enough space to hold all fields in most cases */
11745 ffdata.array = g_ptr_array_sized_new(512);
11746 ffdata.id = 0;
11747
11748 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11749
11750 return ffdata.array;
11751}
11752
11753
11754typedef struct {
11755 unsigned offset;
11756 field_info *finfo;
11757 tvbuff_t *tvb;
11758} offset_search_t;
11759
11760static bool_Bool
11761check_for_offset(proto_node *node, void * data)
11762{
11763 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11764 offset_search_t *offsearch = (offset_search_t *)data;
11765
11766 /* !fi == the top most container node which holds nothing */
11767 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11768 if (offsearch->offset >= (unsigned) fi->start &&
11769 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11770
11771 offsearch->finfo = fi;
11772 return false0; /* keep traversing */
11773 }
11774 }
11775 return false0; /* keep traversing */
11776}
11777
11778/* Search a proto_tree backwards (from leaves to root) looking for the field
11779 * whose start/length occupies 'offset' */
11780/* XXX - I couldn't find an easy way to search backwards, so I search
11781 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11782 * the one I want to return to the user. This algorithm is inefficient
11783 * and could be re-done, but I'd have to handle all the children and
11784 * siblings of each node myself. When I have more time I'll do that.
11785 * (yeah right) */
11786field_info *
11787proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11788{
11789 offset_search_t offsearch;
11790
11791 offsearch.offset = offset;
11792 offsearch.finfo = NULL((void*)0);
11793 offsearch.tvb = tvb;
11794
11795 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11796
11797 return offsearch.finfo;
11798}
11799
11800typedef struct {
11801 unsigned length;
11802 char *buf;
11803} decoded_data_t;
11804
11805static bool_Bool
11806check_for_undecoded(proto_node *node, void * data)
11807{
11808 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11809 decoded_data_t* decoded = (decoded_data_t*)data;
11810 unsigned i;
11811 unsigned byte;
11812 unsigned bit;
11813
11814 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11815 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11816 byte = i / 8;
11817 bit = i % 8;
11818 decoded->buf[byte] |= (1 << bit);
11819 }
11820 }
11821
11822 return false0;
11823}
11824
11825char*
11826proto_find_undecoded_data(proto_tree *tree, unsigned length)
11827{
11828 decoded_data_t decoded;
11829 decoded.length = length;
11830 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11831
11832 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11833 return decoded.buf;
11834}
11835
11836/* Dumps the protocols in the registration database to stdout. An independent
11837 * program can take this output and format it into nice tables or HTML or
11838 * whatever.
11839 *
11840 * There is one record per line. The fields are tab-delimited.
11841 *
11842 * Field 1 = protocol name
11843 * Field 2 = protocol short name
11844 * Field 3 = protocol filter name
11845 * Field 4 = protocol enabled
11846 * Field 5 = protocol enabled by default
11847 * Field 6 = protocol can toggle
11848 */
11849void
11850proto_registrar_dump_protocols(void)
11851{
11852 protocol_t *protocol;
11853 int i;
11854 void *cookie = NULL((void*)0);
11855
11856
11857 i = proto_get_first_protocol(&cookie);
11858 while (i != -1) {
11859 protocol = find_protocol_by_id(i);
11860 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11861 protocol->name,
11862 protocol->short_name,
11863 protocol->filter_name,
11864 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11865 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11866 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11867 i = proto_get_next_protocol(&cookie);
11868 }
11869}
11870
11871/* Dumps the value_strings, extended value string headers, range_strings
11872 * or true/false strings for fields that have them.
11873 * There is one record per line. Fields are tab-delimited.
11874 * There are four types of records: Value String, Extended Value String Header,
11875 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11876 * the type of record.
11877 *
11878 * Note that a record will be generated only if the value_string,... is referenced
11879 * in a registered hfinfo entry.
11880 *
11881 *
11882 * Value Strings
11883 * -------------
11884 * Field 1 = 'V'
11885 * Field 2 = Field abbreviation to which this value string corresponds
11886 * Field 3 = Integer value
11887 * Field 4 = String
11888 *
11889 * Extended Value String Headers
11890 * -----------------------------
11891 * Field 1 = 'E'
11892 * Field 2 = Field abbreviation to which this extended value string header corresponds
11893 * Field 3 = Extended Value String "Name"
11894 * Field 4 = Number of entries in the associated value_string array
11895 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11896 *
11897 * Range Strings
11898 * -------------
11899 * Field 1 = 'R'
11900 * Field 2 = Field abbreviation to which this range string corresponds
11901 * Field 3 = Integer value: lower bound
11902 * Field 4 = Integer value: upper bound
11903 * Field 5 = String
11904 *
11905 * True/False Strings
11906 * ------------------
11907 * Field 1 = 'T'
11908 * Field 2 = Field abbreviation to which this true/false string corresponds
11909 * Field 3 = True String
11910 * Field 4 = False String
11911 */
11912void
11913proto_registrar_dump_values(void)
11914{
11915 header_field_info *hfinfo;
11916 int i, len, vi;
11917 const value_string *vals;
11918 const val64_string *vals64;
11919 const range_string *range;
11920 const true_false_string *tfs;
11921 const unit_name_string *units;
11922
11923 len = gpa_hfinfo.len;
11924 for (i = 1; i < len ; i++) {
11925 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11926 continue; /* This is a deregistered protocol or field */
11927
11928 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", 11928
, __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", 11928
, "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", 11928, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11929
11930 if (hfinfo->id == hf_text_only) {
11931 continue;
11932 }
11933
11934 /* ignore protocols */
11935 if (proto_registrar_is_protocol(i)) {
11936 continue;
11937 }
11938 /* process header fields */
11939#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11940 /*
11941 * If this field isn't at the head of the list of
11942 * fields with this name, skip this field - all
11943 * fields with the same name are really just versions
11944 * of the same field stored in different bits, and
11945 * should have the same type/radix/value list, and
11946 * just differ in their bit masks. (If a field isn't
11947 * a bitfield, but can be, say, 1 or 2 bytes long,
11948 * it can just be made FT_UINT16, meaning the
11949 * *maximum* length is 2 bytes, and be used
11950 * for all lengths.)
11951 */
11952 if (hfinfo->same_name_prev_id != -1)
11953 continue;
11954#endif
11955 vals = NULL((void*)0);
11956 vals64 = NULL((void*)0);
11957 range = NULL((void*)0);
11958 tfs = NULL((void*)0);
11959 units = NULL((void*)0);
11960
11961 if (hfinfo->strings != NULL((void*)0)) {
11962 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11963 (hfinfo->type == FT_CHAR ||
11964 hfinfo->type == FT_UINT8 ||
11965 hfinfo->type == FT_UINT16 ||
11966 hfinfo->type == FT_UINT24 ||
11967 hfinfo->type == FT_UINT32 ||
11968 hfinfo->type == FT_UINT40 ||
11969 hfinfo->type == FT_UINT48 ||
11970 hfinfo->type == FT_UINT56 ||
11971 hfinfo->type == FT_UINT64 ||
11972 hfinfo->type == FT_INT8 ||
11973 hfinfo->type == FT_INT16 ||
11974 hfinfo->type == FT_INT24 ||
11975 hfinfo->type == FT_INT32 ||
11976 hfinfo->type == FT_INT40 ||
11977 hfinfo->type == FT_INT48 ||
11978 hfinfo->type == FT_INT56 ||
11979 hfinfo->type == FT_INT64 ||
11980 hfinfo->type == FT_FLOAT ||
11981 hfinfo->type == FT_DOUBLE)) {
11982
11983 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11984 range = (const range_string *)hfinfo->strings;
11985 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11986 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11987 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11988 } else {
11989 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11990 }
11991 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11992 vals64 = (const val64_string *)hfinfo->strings;
11993 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11994 units = (const unit_name_string *)hfinfo->strings;
11995 } else {
11996 vals = (const value_string *)hfinfo->strings;
11997 }
11998 }
11999 else if (hfinfo->type == FT_BOOLEAN) {
12000 tfs = (const struct true_false_string *)hfinfo->strings;
12001 }
12002 }
12003
12004 /* Print value strings? */
12005 if (vals) {
12006 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12007 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12008 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12009 if (!val64_string_ext_validate(vse_p)) {
12010 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12010, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12011 continue;
12012 }
12013 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12014 printf("E\t%s\t%u\t%s\t%s\n",
12015 hfinfo->abbrev,
12016 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12017 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12018 val64_string_ext_match_type_str(vse_p));
12019 } else {
12020 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12021 if (!value_string_ext_validate(vse_p)) {
12022 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12022, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12023 continue;
12024 }
12025 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12026 printf("E\t%s\t%u\t%s\t%s\n",
12027 hfinfo->abbrev,
12028 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12029 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12030 value_string_ext_match_type_str(vse_p));
12031 }
12032 }
12033 vi = 0;
12034 while (vals[vi].strptr) {
12035 /* Print in the proper base */
12036 if (hfinfo->type == FT_CHAR) {
12037 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12038 printf("V\t%s\t'%c'\t%s\n",
12039 hfinfo->abbrev,
12040 vals[vi].value,
12041 vals[vi].strptr);
12042 } else {
12043 if (hfinfo->display == BASE_HEX) {
12044 printf("V\t%s\t'\\x%02x'\t%s\n",
12045 hfinfo->abbrev,
12046 vals[vi].value,
12047 vals[vi].strptr);
12048 }
12049 else {
12050 printf("V\t%s\t'\\%03o'\t%s\n",
12051 hfinfo->abbrev,
12052 vals[vi].value,
12053 vals[vi].strptr);
12054 }
12055 }
12056 } else {
12057 if (hfinfo->display == BASE_HEX) {
12058 printf("V\t%s\t0x%x\t%s\n",
12059 hfinfo->abbrev,
12060 vals[vi].value,
12061 vals[vi].strptr);
12062 }
12063 else {
12064 printf("V\t%s\t%u\t%s\n",
12065 hfinfo->abbrev,
12066 vals[vi].value,
12067 vals[vi].strptr);
12068 }
12069 }
12070 vi++;
12071 }
12072 }
12073 else if (vals64) {
12074 vi = 0;
12075 while (vals64[vi].strptr) {
12076 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12077 hfinfo->abbrev,
12078 vals64[vi].value,
12079 vals64[vi].strptr);
12080 vi++;
12081 }
12082 }
12083
12084 /* print range strings? */
12085 else if (range) {
12086 vi = 0;
12087 while (range[vi].strptr) {
12088 /* Print in the proper base */
12089 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12090 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12091 hfinfo->abbrev,
12092 range[vi].value_min,
12093 range[vi].value_max,
12094 range[vi].strptr);
12095 }
12096 else {
12097 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12098 hfinfo->abbrev,
12099 range[vi].value_min,
12100 range[vi].value_max,
12101 range[vi].strptr);
12102 }
12103 vi++;
12104 }
12105 }
12106
12107 /* Print true/false strings? */
12108 else if (tfs) {
12109 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12110 tfs->true_string, tfs->false_string);
12111 }
12112 /* Print unit strings? */
12113 else if (units) {
12114 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12115 units->singular, units->plural ? units->plural : "(no plural)");
12116 }
12117 }
12118}
12119
12120/* Prints the number of registered fields.
12121 * Useful for determining an appropriate value for
12122 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12123 *
12124 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12125 * the number of fields, true otherwise.
12126 */
12127bool_Bool
12128proto_registrar_dump_fieldcount(void)
12129{
12130 struct proto_registrar_stats stats = {0, 0, 0};
12131 size_t total_count = proto_registrar_get_count(&stats);
12132
12133 printf("There are %zu header fields registered, of which:\n"
12134 "\t%zu are deregistered\n"
12135 "\t%zu are protocols\n"
12136 "\t%zu have the same name as another field\n\n",
12137 total_count, stats.deregistered_count, stats.protocol_count,
12138 stats.same_name_count);
12139
12140 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12141 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12142 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12143 "\n");
12144
12145 printf("The header field table consumes %u KiB of memory.\n",
12146 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12147 printf("The fields themselves consume %u KiB of memory.\n",
12148 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12149
12150 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12151}
12152
12153static void
12154elastic_add_base_mapping(json_dumper *dumper)
12155{
12156 json_dumper_set_member_name(dumper, "index_patterns");
12157 json_dumper_begin_array(dumper);
12158 // The index names from write_json_index() in print.c
12159 json_dumper_value_string(dumper, "packets-*");
12160 json_dumper_end_array(dumper);
12161
12162 json_dumper_set_member_name(dumper, "settings");
12163 json_dumper_begin_object(dumper);
12164 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12165 json_dumper_value_anyf(dumper, "%d", 1000000);
12166 json_dumper_end_object(dumper);
12167}
12168
12169static char*
12170ws_type_to_elastic(unsigned type)
12171{
12172 switch(type) {
12173 case FT_INT8:
12174 return "byte";
12175 case FT_UINT8:
12176 case FT_INT16:
12177 return "short";
12178 case FT_UINT16:
12179 case FT_INT32:
12180 case FT_UINT24:
12181 case FT_INT24:
12182 return "integer";
12183 case FT_FRAMENUM:
12184 case FT_UINT32:
12185 case FT_UINT40:
12186 case FT_UINT48:
12187 case FT_UINT56:
12188 case FT_INT40:
12189 case FT_INT48:
12190 case FT_INT56:
12191 case FT_INT64:
12192 return "long";
12193 case FT_UINT64:
12194 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12195 case FT_FLOAT:
12196 return "float";
12197 case FT_DOUBLE:
12198 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12199 return "double";
12200 case FT_IPv6:
12201 case FT_IPv4:
12202 return "ip";
12203 case FT_ABSOLUTE_TIME:
12204 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12205 case FT_BOOLEAN:
12206 return "boolean";
12207 default:
12208 return NULL((void*)0);
12209 }
12210}
12211
12212static char*
12213dot_to_underscore(char* str)
12214{
12215 unsigned i;
12216 for (i = 0; i < strlen(str); i++) {
12217 if (str[i] == '.')
12218 str[i] = '_';
12219 }
12220 return str;
12221}
12222
12223/* Dumps a mapping file for ElasticSearch
12224 * This is the v1 (legacy) _template API.
12225 * At some point it may need to be updated with the composable templates
12226 * introduced in Elasticsearch 7.8 (_index_template)
12227 */
12228void
12229proto_registrar_dump_elastic(const char* filter)
12230{
12231 header_field_info *hfinfo;
12232 header_field_info *parent_hfinfo;
12233 unsigned i;
12234 bool_Bool open_object = true1;
12235 const char* prev_proto = NULL((void*)0);
12236 char* str;
12237 char** protos = NULL((void*)0);
12238 char* proto;
12239 bool_Bool found;
12240 unsigned j;
12241 char* type;
12242 char* prev_item = NULL((void*)0);
12243
12244 /* We have filtering protocols. Extract them. */
12245 if (filter) {
12246 protos = g_strsplit(filter, ",", -1);
12247 }
12248
12249 /*
12250 * To help tracking down the json tree, objects have been appended with a comment:
12251 * n.label -> where n is the indentation level and label the name of the object
12252 */
12253
12254 json_dumper dumper = {
12255 .output_file = stdoutstdout,
12256 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12257 };
12258 json_dumper_begin_object(&dumper); // 1.root
12259 elastic_add_base_mapping(&dumper);
12260
12261 json_dumper_set_member_name(&dumper, "mappings");
12262 json_dumper_begin_object(&dumper); // 2.mappings
12263
12264 json_dumper_set_member_name(&dumper, "properties");
12265 json_dumper_begin_object(&dumper); // 3.properties
12266 json_dumper_set_member_name(&dumper, "timestamp");
12267 json_dumper_begin_object(&dumper); // 4.timestamp
12268 json_dumper_set_member_name(&dumper, "type");
12269 json_dumper_value_string(&dumper, "date");
12270 json_dumper_end_object(&dumper); // 4.timestamp
12271
12272 json_dumper_set_member_name(&dumper, "layers");
12273 json_dumper_begin_object(&dumper); // 4.layers
12274 json_dumper_set_member_name(&dumper, "properties");
12275 json_dumper_begin_object(&dumper); // 5.properties
12276
12277 for (i = 1; i < gpa_hfinfo.len; i++) {
12278 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12279 continue; /* This is a deregistered protocol or header field */
12280
12281 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", 12281
, __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", 12281
, "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", 12281, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12282
12283 /*
12284 * Skip the pseudo-field for "proto_tree_add_text()" since
12285 * we don't want it in the list of filterable protocols.
12286 */
12287 if (hfinfo->id == hf_text_only)
12288 continue;
12289
12290 if (!proto_registrar_is_protocol(i)) {
12291 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", 12291
, __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", 12291
, "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", 12291
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12292
12293 /*
12294 * Skip the field if filter protocols have been set and this one's
12295 * parent is not listed.
12296 */
12297 if (protos) {
12298 found = false0;
12299 j = 0;
12300 proto = protos[0];
12301 while(proto) {
12302 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12303 found = true1;
12304 break;
12305 }
12306 j++;
12307 proto = protos[j];
12308 }
12309 if (!found)
12310 continue;
12311 }
12312
12313 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12314 json_dumper_end_object(&dumper); // 7.properties
12315 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12316 open_object = true1;
12317 }
12318
12319 prev_proto = parent_hfinfo->abbrev;
12320
12321 if (open_object) {
12322 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12323 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12324 json_dumper_set_member_name(&dumper, "properties");
12325 json_dumper_begin_object(&dumper); // 7.properties
12326 open_object = false0;
12327 }
12328 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12329 type = ws_type_to_elastic(hfinfo->type);
12330 /* when type is NULL, we have the default mapping: string */
12331 if (type) {
12332 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12333 dot_to_underscore(str);
12334 if (g_strcmp0(prev_item, str)) {
12335 json_dumper_set_member_name(&dumper, str);
12336 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12337 json_dumper_set_member_name(&dumper, "type");
12338 json_dumper_value_string(&dumper, type);
12339 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12340 }
12341 g_free(prev_item);
12342 prev_item = str;
12343 }
12344 }
12345 }
12346 g_free(prev_item);
12347
12348 if (prev_proto) {
12349 json_dumper_end_object(&dumper); // 7.properties
12350 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12351 }
12352
12353 json_dumper_end_object(&dumper); // 5.properties
12354 json_dumper_end_object(&dumper); // 4.layers
12355 json_dumper_end_object(&dumper); // 3.properties
12356 json_dumper_end_object(&dumper); // 2.mappings
12357 json_dumper_end_object(&dumper); // 1.root
12358 bool_Bool ret = json_dumper_finish(&dumper);
12359 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12359, "ret"))))
;
12360
12361 g_strfreev(protos);
12362}
12363
12364/* Dumps the contents of the registration database to stdout. An independent
12365 * program can take this output and format it into nice tables or HTML or
12366 * whatever.
12367 *
12368 * There is one record per line. Each record is either a protocol or a header
12369 * field, differentiated by the first field. The fields are tab-delimited.
12370 *
12371 * Protocols
12372 * ---------
12373 * Field 1 = 'P'
12374 * Field 2 = descriptive protocol name
12375 * Field 3 = protocol abbreviation
12376 *
12377 * Header Fields
12378 * -------------
12379 * Field 1 = 'F'
12380 * Field 2 = descriptive field name
12381 * Field 3 = field abbreviation
12382 * Field 4 = type ( textual representation of the ftenum type )
12383 * Field 5 = parent protocol abbreviation
12384 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12385 * Field 7 = bitmask: format: hex: 0x....
12386 * Field 8 = blurb describing field
12387 */
12388void
12389proto_registrar_dump_fields(void)
12390{
12391 header_field_info *hfinfo, *parent_hfinfo;
12392 int i, len;
12393 const char *enum_name;
12394 const char *base_name;
12395 const char *blurb;
12396 char width[5];
12397
12398 len = gpa_hfinfo.len;
12399 for (i = 1; i < len ; i++) {
12400 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12401 continue; /* This is a deregistered protocol or header field */
12402
12403 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", 12403
, __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", 12403
, "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", 12403, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12404
12405 /*
12406 * Skip the pseudo-field for "proto_tree_add_text()" since
12407 * we don't want it in the list of filterable fields.
12408 */
12409 if (hfinfo->id == hf_text_only)
12410 continue;
12411
12412 /* format for protocols */
12413 if (proto_registrar_is_protocol(i)) {
12414 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12415 }
12416 /* format for header fields */
12417 else {
12418 /*
12419 * If this field isn't at the head of the list of
12420 * fields with this name, skip this field - all
12421 * fields with the same name are really just versions
12422 * of the same field stored in different bits, and
12423 * should have the same type/radix/value list, and
12424 * just differ in their bit masks. (If a field isn't
12425 * a bitfield, but can be, say, 1 or 2 bytes long,
12426 * it can just be made FT_UINT16, meaning the
12427 * *maximum* length is 2 bytes, and be used
12428 * for all lengths.)
12429 */
12430 if (hfinfo->same_name_prev_id != -1)
12431 continue;
12432
12433 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", 12433
, __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", 12433
, "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", 12433
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12434
12435 enum_name = ftype_name(hfinfo->type);
12436 base_name = "";
12437
12438 if (hfinfo->type == FT_CHAR ||
12439 hfinfo->type == FT_UINT8 ||
12440 hfinfo->type == FT_UINT16 ||
12441 hfinfo->type == FT_UINT24 ||
12442 hfinfo->type == FT_UINT32 ||
12443 hfinfo->type == FT_UINT40 ||
12444 hfinfo->type == FT_UINT48 ||
12445 hfinfo->type == FT_UINT56 ||
12446 hfinfo->type == FT_UINT64 ||
12447 hfinfo->type == FT_INT8 ||
12448 hfinfo->type == FT_INT16 ||
12449 hfinfo->type == FT_INT24 ||
12450 hfinfo->type == FT_INT32 ||
12451 hfinfo->type == FT_INT40 ||
12452 hfinfo->type == FT_INT48 ||
12453 hfinfo->type == FT_INT56 ||
12454 hfinfo->type == FT_INT64) {
12455
12456 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12457 case BASE_NONE:
12458 case BASE_DEC:
12459 case BASE_HEX:
12460 case BASE_OCT:
12461 case BASE_DEC_HEX:
12462 case BASE_HEX_DEC:
12463 case BASE_CUSTOM:
12464 case BASE_PT_UDP:
12465 case BASE_PT_TCP:
12466 case BASE_PT_DCCP:
12467 case BASE_PT_SCTP:
12468 case BASE_OUI:
12469 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12470 break;
12471 default:
12472 base_name = "????";
12473 break;
12474 }
12475 } else if (hfinfo->type == FT_BOOLEAN) {
12476 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12477 snprintf(width, sizeof(width), "%d", hfinfo->display);
12478 base_name = width;
12479 }
12480
12481 blurb = hfinfo->blurb;
12482 if (blurb == NULL((void*)0))
12483 blurb = "";
12484 else if (strlen(blurb) == 0)
12485 blurb = "\"\"";
12486
12487 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12488 hfinfo->name, hfinfo->abbrev, enum_name,
12489 parent_hfinfo->abbrev, base_name,
12490 hfinfo->bitmask, blurb);
12491 }
12492 }
12493}
12494
12495/* Dumps all abbreviated field and protocol completions of the given string to
12496 * stdout. An independent program may use this for command-line tab completion
12497 * of fields.
12498 */
12499bool_Bool
12500proto_registrar_dump_field_completions(const char *prefix)
12501{
12502 header_field_info *hfinfo;
12503 int i, len;
12504 size_t prefix_len;
12505 bool_Bool matched = false0;
12506
12507 prefix_len = strlen(prefix);
12508 len = gpa_hfinfo.len;
12509 for (i = 1; i < len ; i++) {
12510 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12511 continue; /* This is a deregistered protocol or header field */
12512
12513 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", 12513
, __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", 12513
, "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", 12513, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12514
12515 /*
12516 * Skip the pseudo-field for "proto_tree_add_text()" since
12517 * we don't want it in the list of filterable fields.
12518 */
12519 if (hfinfo->id == hf_text_only)
12520 continue;
12521
12522 /* format for protocols */
12523 if (proto_registrar_is_protocol(i)) {
12524 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12525 matched = true1;
12526 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12527 }
12528 }
12529 /* format for header fields */
12530 else {
12531 /*
12532 * If this field isn't at the head of the list of
12533 * fields with this name, skip this field - all
12534 * fields with the same name are really just versions
12535 * of the same field stored in different bits, and
12536 * should have the same type/radix/value list, and
12537 * just differ in their bit masks. (If a field isn't
12538 * a bitfield, but can be, say, 1 or 2 bytes long,
12539 * it can just be made FT_UINT16, meaning the
12540 * *maximum* length is 2 bytes, and be used
12541 * for all lengths.)
12542 */
12543 if (hfinfo->same_name_prev_id != -1)
12544 continue;
12545
12546 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12547 matched = true1;
12548 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12549 }
12550 }
12551 }
12552 return matched;
12553}
12554
12555/* Dumps field types and descriptive names to stdout. An independent
12556 * program can take this output and format it into nice tables or HTML or
12557 * whatever.
12558 *
12559 * There is one record per line. The fields are tab-delimited.
12560 *
12561 * Field 1 = field type name, e.g. FT_UINT8
12562 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12563 */
12564void
12565proto_registrar_dump_ftypes(void)
12566{
12567 int fte;
12568
12569 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12570 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12571 }
12572}
12573
12574/* This function indicates whether it's possible to construct a
12575 * "match selected" display filter string for the specified field,
12576 * returns an indication of whether it's possible, and, if it's
12577 * possible and "filter" is non-null, constructs the filter and
12578 * sets "*filter" to point to it.
12579 * You do not need to [g_]free() this string since it will be automatically
12580 * freed once the next packet is dissected.
12581 */
12582static bool_Bool
12583construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12584 char **filter)
12585{
12586 const header_field_info *hfinfo;
12587 int start, length, length_remaining;
12588
12589 if (!finfo)
12590 return false0;
12591
12592 hfinfo = finfo->hfinfo;
12593 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12593, "hfinfo"))))
;
12594
12595 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12596 * then "the numeric value ... is not used when preparing
12597 * filters for the field in question." If it's any other
12598 * base, we'll generate the filter normally (which will
12599 * be numeric, even though the human-readable string does
12600 * work for filtering.)
12601 *
12602 * XXX - It might be nice to use fvalue_to_string_repr() in
12603 * "proto_item_fill_label()" as well, although, there, you'd
12604 * have to deal with the base *and* with resolved values for
12605 * addresses.
12606 *
12607 * Perhaps in addition to taking the repr type (DISPLAY
12608 * or DFILTER) and the display (base), fvalue_to_string_repr()
12609 * should have the the "strings" values in the header_field_info
12610 * structure for the field as a parameter, so it can have
12611 * if the field is Boolean or an enumerated integer type,
12612 * the tables used to generate human-readable values.
12613 */
12614 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12615 const char *str = NULL((void*)0);
12616
12617 switch (hfinfo->type) {
12618
12619 case FT_INT8:
12620 case FT_INT16:
12621 case FT_INT24:
12622 case FT_INT32:
12623 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12624 break;
12625
12626 case FT_CHAR:
12627 case FT_UINT8:
12628 case FT_UINT16:
12629 case FT_UINT24:
12630 case FT_UINT32:
12631 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12632 break;
12633
12634 default:
12635 break;
12636 }
12637
12638 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12639 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12640 return true1;
12641 }
12642 }
12643
12644 switch (hfinfo->type) {
12645
12646 case FT_PROTOCOL:
12647 if (filter != NULL((void*)0))
12648 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12649 break;
12650
12651 case FT_NONE:
12652 /*
12653 * If the length is 0, just match the name of the
12654 * field.
12655 *
12656 * (Also check for negative values, just in case,
12657 * as we'll cast it to an unsigned value later.)
12658 */
12659 length = finfo->length;
12660 if (length == 0) {
12661 if (filter != NULL((void*)0))
12662 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12663 break;
12664 }
12665 if (length < 0)
12666 return false0;
12667
12668 /*
12669 * This doesn't have a value, so we'd match
12670 * on the raw bytes at this address.
12671 *
12672 * Should we be allowed to access to the raw bytes?
12673 * If "edt" is NULL, the answer is "no".
12674 */
12675 if (edt == NULL((void*)0))
12676 return false0;
12677
12678 /*
12679 * Is this field part of the raw frame tvbuff?
12680 * If not, we can't use "frame[N:M]" to match
12681 * it.
12682 *
12683 * XXX - should this be frame-relative, or
12684 * protocol-relative?
12685 *
12686 * XXX - does this fallback for non-registered
12687 * fields even make sense?
12688 */
12689 if (finfo->ds_tvb != edt->tvb)
12690 return false0; /* you lose */
12691
12692 /*
12693 * Don't go past the end of that tvbuff.
12694 */
12695 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12696 if (length > length_remaining)
12697 length = length_remaining;
12698 if (length <= 0)
12699 return false0;
12700
12701 if (filter != NULL((void*)0)) {
12702 start = finfo->start;
12703 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12704 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12705 wmem_free(NULL((void*)0), str);
12706 }
12707 break;
12708
12709 /* By default, use the fvalue's "to_string_repr" method. */
12710 default:
12711 if (filter != NULL((void*)0)) {
12712 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12713 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12714 wmem_free(NULL((void*)0), str);
12715 }
12716 break;
12717 }
12718
12719 return true1;
12720}
12721
12722/*
12723 * Returns true if we can do a "match selected" on the field, false
12724 * otherwise.
12725 */
12726bool_Bool
12727proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12728{
12729 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12730}
12731
12732/* This function attempts to construct a "match selected" display filter
12733 * string for the specified field; if it can do so, it returns a pointer
12734 * to the string, otherwise it returns NULL.
12735 *
12736 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12737 */
12738char *
12739proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12740{
12741 char *filter = NULL((void*)0);
12742
12743 if (!construct_match_selected_string(finfo, edt, &filter))
12744 {
12745 wmem_free(NULL((void*)0), filter);
12746 return NULL((void*)0);
12747 }
12748 return filter;
12749}
12750
12751/* This function is common code for all proto_tree_add_bitmask... functions.
12752 */
12753
12754static bool_Bool
12755proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12756 const int len, const int ett, int * const *fields,
12757 const int flags, bool_Bool first,
12758 bool_Bool use_parent_tree,
12759 proto_tree* tree, uint64_t value)
12760{
12761 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12762 uint64_t bitmask = 0;
12763 uint64_t tmpval;
12764 header_field_info *hf;
12765 uint32_t integer32;
12766 int bit_offset;
12767 int no_of_bits;
12768
12769 if (!*fields)
12770 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"
)
;
12771
12772 if (len < 0 || len > 8)
12773 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12774 /**
12775 * packet-frame.c uses len=0 since the value is taken from the packet
12776 * metadata, not the packet bytes. In that case, assume that all bits
12777 * in the provided value are valid.
12778 */
12779 if (len > 0) {
12780 available_bits >>= (8 - (unsigned)len)*8;
12781 }
12782
12783 if (use_parent_tree == false0)
12784 tree = proto_item_add_subtree(item, ett);
12785
12786 while (*fields) {
12787 uint64_t present_bits;
12788 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", 12788, __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", 12788
, "**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", 12788, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12789 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", 12789
, "hf->bitmask != 0", hf->abbrev))))
;
12790
12791 bitmask |= hf->bitmask;
12792
12793 /* Skip fields that aren't fully present */
12794 present_bits = available_bits & hf->bitmask;
12795 if (present_bits != hf->bitmask) {
12796 fields++;
12797 continue;
12798 }
12799
12800 switch (hf->type) {
12801 case FT_CHAR:
12802 case FT_UINT8:
12803 case FT_UINT16:
12804 case FT_UINT24:
12805 case FT_UINT32:
12806 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12807 break;
12808
12809 case FT_INT8:
12810 case FT_INT16:
12811 case FT_INT24:
12812 case FT_INT32:
12813 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12814 break;
12815
12816 case FT_UINT40:
12817 case FT_UINT48:
12818 case FT_UINT56:
12819 case FT_UINT64:
12820 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12821 break;
12822
12823 case FT_INT40:
12824 case FT_INT48:
12825 case FT_INT56:
12826 case FT_INT64:
12827 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12828 break;
12829
12830 case FT_BOOLEAN:
12831 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12832 break;
12833
12834 default:
12835 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))
12836 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))
12837 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))
12838 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))
;
12839 break;
12840 }
12841 if (flags & BMT_NO_APPEND0x01) {
12842 fields++;
12843 continue;
12844 }
12845 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12846
12847 /* XXX: README.developer and the comments have always defined
12848 * BMT_NO_INT as "only boolean flags are added to the title /
12849 * don't add non-boolean (integral) fields", but the
12850 * implementation has always added BASE_CUSTOM and fields with
12851 * value_strings, though not fields with unit_strings.
12852 * Possibly this is because some dissectors use a FT_UINT8
12853 * with a value_string for fields that should be a FT_BOOLEAN.
12854 */
12855 switch (hf->type) {
12856 case FT_CHAR:
12857 if (hf->display == BASE_CUSTOM) {
12858 char lbl[ITEM_LABEL_LENGTH240];
12859 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12860
12861 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12861, "fmtfunc"))))
;
12862 fmtfunc(lbl, (uint32_t) tmpval);
12863 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12864 hf->name, lbl);
12865 first = false0;
12866 }
12867 else if (hf->strings) {
12868 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12869 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12870 first = false0;
12871 }
12872 else if (!(flags & BMT_NO_INT0x02)) {
12873 char buf[32];
12874 const char *out;
12875
12876 if (!first) {
12877 proto_item_append_text(item, ", ");
12878 }
12879
12880 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12881 proto_item_append_text(item, "%s: %s", hf->name, out);
12882 first = false0;
12883 }
12884
12885 break;
12886
12887 case FT_UINT8:
12888 case FT_UINT16:
12889 case FT_UINT24:
12890 case FT_UINT32:
12891 if (hf->display == BASE_CUSTOM) {
12892 char lbl[ITEM_LABEL_LENGTH240];
12893 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12894
12895 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12895, "fmtfunc"))))
;
12896 fmtfunc(lbl, (uint32_t) tmpval);
12897 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12898 hf->name, lbl);
12899 first = false0;
12900 }
12901 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12902 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12903 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12904 first = false0;
12905 }
12906 else if (!(flags & BMT_NO_INT0x02)) {
12907 char buf[NUMBER_LABEL_LENGTH80];
12908 const char *out = NULL((void*)0);
12909
12910 if (!first) {
12911 proto_item_append_text(item, ", ");
12912 }
12913
12914 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12915 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12916 }
12917 if (out == NULL((void*)0)) {
12918 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12919 }
12920 proto_item_append_text(item, "%s: %s", hf->name, out);
12921 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12922 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12923 }
12924 first = false0;
12925 }
12926
12927 break;
12928
12929 case FT_INT8:
12930 case FT_INT16:
12931 case FT_INT24:
12932 case FT_INT32:
12933 integer32 = (uint32_t) tmpval;
12934 if (hf->bitmask) {
12935 no_of_bits = ws_count_ones(hf->bitmask);
12936 integer32 = ws_sign_ext32(integer32, no_of_bits);
12937 }
12938 if (hf->display == BASE_CUSTOM) {
12939 char lbl[ITEM_LABEL_LENGTH240];
12940 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12941
12942 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12942, "fmtfunc"))))
;
12943 fmtfunc(lbl, (int32_t) integer32);
12944 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12945 hf->name, lbl);
12946 first = false0;
12947 }
12948 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12949 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12950 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12951 first = false0;
12952 }
12953 else if (!(flags & BMT_NO_INT0x02)) {
12954 char buf[NUMBER_LABEL_LENGTH80];
12955 const char *out = NULL((void*)0);
12956
12957 if (!first) {
12958 proto_item_append_text(item, ", ");
12959 }
12960
12961 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12962 out = hf_try_val_to_str((int32_t) integer32, hf);
12963 }
12964 if (out == NULL((void*)0)) {
12965 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12966 }
12967 proto_item_append_text(item, "%s: %s", hf->name, out);
12968 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12969 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12970 }
12971 first = false0;
12972 }
12973
12974 break;
12975
12976 case FT_UINT40:
12977 case FT_UINT48:
12978 case FT_UINT56:
12979 case FT_UINT64:
12980 if (hf->display == BASE_CUSTOM) {
12981 char lbl[ITEM_LABEL_LENGTH240];
12982 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12983
12984 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12984, "fmtfunc"))))
;
12985 fmtfunc(lbl, tmpval);
12986 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12987 hf->name, lbl);
12988 first = false0;
12989 }
12990 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12991 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12992 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12993 first = false0;
12994 }
12995 else if (!(flags & BMT_NO_INT0x02)) {
12996 char buf[NUMBER_LABEL_LENGTH80];
12997 const char *out = NULL((void*)0);
12998
12999 if (!first) {
13000 proto_item_append_text(item, ", ");
13001 }
13002
13003 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13004 out = hf_try_val64_to_str(tmpval, hf);
13005 }
13006 if (out == NULL((void*)0)) {
13007 out = hfinfo_number_value_format64(hf, buf, tmpval);
13008 }
13009 proto_item_append_text(item, "%s: %s", hf->name, out);
13010 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13011 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13012 }
13013 first = false0;
13014 }
13015
13016 break;
13017
13018 case FT_INT40:
13019 case FT_INT48:
13020 case FT_INT56:
13021 case FT_INT64:
13022 if (hf->bitmask) {
13023 no_of_bits = ws_count_ones(hf->bitmask);
13024 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13025 }
13026 if (hf->display == BASE_CUSTOM) {
13027 char lbl[ITEM_LABEL_LENGTH240];
13028 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13029
13030 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13030, "fmtfunc"))))
;
13031 fmtfunc(lbl, (int64_t) tmpval);
13032 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13033 hf->name, lbl);
13034 first = false0;
13035 }
13036 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13037 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13038 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13039 first = false0;
13040 }
13041 else if (!(flags & BMT_NO_INT0x02)) {
13042 char buf[NUMBER_LABEL_LENGTH80];
13043 const char *out = NULL((void*)0);
13044
13045 if (!first) {
13046 proto_item_append_text(item, ", ");
13047 }
13048
13049 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13050 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13051 }
13052 if (out == NULL((void*)0)) {
13053 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13054 }
13055 proto_item_append_text(item, "%s: %s", hf->name, out);
13056 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13057 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13058 }
13059 first = false0;
13060 }
13061
13062 break;
13063
13064 case FT_BOOLEAN:
13065 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13066 /* If we have true/false strings, emit full - otherwise messages
13067 might look weird */
13068 const struct true_false_string *tfs =
13069 (const struct true_false_string *)hf->strings;
13070
13071 if (tmpval) {
13072 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13073 hf->name, tfs->true_string);
13074 first = false0;
13075 } else if (!(flags & BMT_NO_FALSE0x04)) {
13076 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13077 hf->name, tfs->false_string);
13078 first = false0;
13079 }
13080 } else if (hf->bitmask & value) {
13081 /* If the flag is set, show the name */
13082 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13083 first = false0;
13084 }
13085 break;
13086 default:
13087 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))
13088 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))
13089 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))
13090 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))
;
13091 break;
13092 }
13093
13094 fields++;
13095 }
13096
13097 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13098 * but then again most dissectors don't set the bitmask field for
13099 * the higher level bitmask hfi, so calculate the bitmask from the
13100 * fields present. */
13101 if (item) {
13102 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13103 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13104 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)
;
13105 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)
;
13106 }
13107 return first;
13108}
13109
13110/* This function will dissect a sequence of bytes that describe a
13111 * bitmask and supply the value of that sequence through a pointer.
13112 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13113 * to be dissected.
13114 * This field will form an expansion under which the individual fields of the
13115 * bitmask is dissected and displayed.
13116 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13117 *
13118 * fields is an array of pointers to int that lists all the fields of the
13119 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13120 * or another integer of the same type/size as hf_hdr with a mask specified.
13121 * This array is terminated by a NULL entry.
13122 *
13123 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13124 * FT_integer fields that have a value_string attached will have the
13125 * matched string displayed on the expansion line.
13126 */
13127proto_item *
13128proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13129 const unsigned offset, const int hf_hdr,
13130 const int ett, int * const *fields,
13131 const unsigned encoding, uint64_t *retval)
13132{
13133 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);
13134}
13135
13136/* This function will dissect a sequence of bytes that describe a
13137 * bitmask.
13138 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13139 * to be dissected.
13140 * This field will form an expansion under which the individual fields of the
13141 * bitmask is dissected and displayed.
13142 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13143 *
13144 * fields is an array of pointers to int that lists all the fields of the
13145 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13146 * or another integer of the same type/size as hf_hdr with a mask specified.
13147 * This array is terminated by a NULL entry.
13148 *
13149 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13150 * FT_integer fields that have a value_string attached will have the
13151 * matched string displayed on the expansion line.
13152 */
13153proto_item *
13154proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13155 const unsigned offset, const int hf_hdr,
13156 const int ett, int * const *fields,
13157 const unsigned encoding)
13158{
13159 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13160}
13161
13162/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13163 * what data is appended to the header.
13164 */
13165proto_item *
13166proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13167 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13168 uint64_t *retval)
13169{
13170 proto_item *item = NULL((void*)0);
13171 header_field_info *hf;
13172 int len;
13173 uint64_t value;
13174
13175 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", 13175, __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", 13175
, "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", 13175, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13176 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", 13176, (hf)->abbrev)))
;
13177 len = ftype_wire_size(hf->type);
13178 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13179
13180 if (parent_tree) {
13181 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13182 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13183 flags, false0, false0, NULL((void*)0), value);
13184 }
13185
13186 *retval = value;
13187 if (hf->bitmask) {
13188 /* Mask out irrelevant portions */
13189 *retval &= hf->bitmask;
13190 /* Shift bits */
13191 *retval >>= hfinfo_bitshift(hf);
13192 }
13193
13194 return item;
13195}
13196
13197/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13198 * what data is appended to the header.
13199 */
13200proto_item *
13201proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13202 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13203{
13204 proto_item *item = NULL((void*)0);
13205 header_field_info *hf;
13206 int len;
13207 uint64_t value;
13208
13209 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", 13209, __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", 13209
, "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", 13209, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13210 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", 13210, (hf)->abbrev)))
;
13211
13212 if (parent_tree) {
13213 len = ftype_wire_size(hf->type);
13214 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13215 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13216 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13217 flags, false0, false0, NULL((void*)0), value);
13218 }
13219
13220 return item;
13221}
13222
13223/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13224 can't be retrieved directly from tvb) */
13225proto_item *
13226proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13227 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13228{
13229 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13230 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13231}
13232
13233/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13234WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13235proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13236 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13237{
13238 proto_item *item = NULL((void*)0);
13239 header_field_info *hf;
13240 int len;
13241
13242 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", 13242, __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", 13242
, "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", 13242, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13243 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", 13243, (hf)->abbrev)))
;
13244 /* the proto_tree_add_uint/_uint64() calls below
13245 will fail if tvb==NULL and len!=0 */
13246 len = tvb ? ftype_wire_size(hf->type) : 0;
13247
13248 if (parent_tree) {
13249 if (len <= 4)
13250 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13251 else
13252 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13253
13254 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13255 flags, false0, false0, NULL((void*)0), value);
13256 }
13257
13258 return item;
13259}
13260
13261/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13262void
13263proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13264 const int len, int * const *fields, const unsigned encoding)
13265{
13266 uint64_t value;
13267
13268 if (tree) {
13269 value = get_uint64_value(tree, tvb, offset, len, encoding);
13270 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13271 BMT_NO_APPEND0x01, false0, true1, tree, value);
13272 }
13273}
13274
13275WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13276proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13277 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13278{
13279 uint64_t value;
13280
13281 value = get_uint64_value(tree, tvb, offset, len, encoding);
13282 if (tree) {
13283 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13284 BMT_NO_APPEND0x01, false0, true1, tree, value);
13285 }
13286 if (retval) {
13287 *retval = value;
13288 }
13289}
13290
13291WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13292proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13293 const int len, int * const *fields, const uint64_t value)
13294{
13295 if (tree) {
13296 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13297 BMT_NO_APPEND0x01, false0, true1, tree, value);
13298 }
13299}
13300
13301
13302/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13303 * This is intended to support bitmask fields whose lengths can vary, perhaps
13304 * as the underlying standard evolves over time.
13305 * With this API there is the possibility of being called to display more or
13306 * less data than the dissector was coded to support.
13307 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13308 * Thus when presented with "too much" or "too little" data, MSbits will be
13309 * ignored or MSfields sacrificed.
13310 *
13311 * Only fields for which all defined bits are available are displayed.
13312 */
13313proto_item *
13314proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13315 const unsigned offset, const unsigned len, const int hf_hdr,
13316 const int ett, int * const *fields, struct expert_field* exp,
13317 const unsigned encoding)
13318{
13319 proto_item *item = NULL((void*)0);
13320 header_field_info *hf;
13321 unsigned decodable_len;
13322 unsigned decodable_offset;
13323 uint32_t decodable_value;
13324 uint64_t value;
13325
13326 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", 13326, __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", 13326
, "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", 13326, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13327 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", 13327, (hf)->abbrev)))
;
13328
13329 decodable_offset = offset;
13330 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13331
13332 /* If we are ftype_wire_size-limited,
13333 * make sure we decode as many LSBs as possible.
13334 */
13335 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13336 decodable_offset += (len - decodable_len);
13337 }
13338
13339 if (parent_tree) {
13340 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13341 decodable_len, encoding);
13342
13343 /* The root item covers all the bytes even if we can't decode them all */
13344 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13345 decodable_value);
13346 }
13347
13348 if (decodable_len < len) {
13349 /* Dissector likely requires updating for new protocol revision */
13350 expert_add_info_format(NULL((void*)0), item, exp,
13351 "Only least-significant %d of %d bytes decoded",
13352 decodable_len, len);
13353 }
13354
13355 if (item) {
13356 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13357 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13358 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13359 }
13360
13361 return item;
13362}
13363
13364/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13365proto_item *
13366proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13367 const unsigned offset, const unsigned len,
13368 const char *name, const char *fallback,
13369 const int ett, int * const *fields,
13370 const unsigned encoding, const int flags)
13371{
13372 proto_item *item = NULL((void*)0);
13373 uint64_t value;
13374
13375 if (parent_tree) {
13376 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13377 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13378 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13379 flags, true1, false0, NULL((void*)0), value) && fallback) {
13380 /* Still at first item - append 'fallback' text if any */
13381 proto_item_append_text(item, "%s", fallback);
13382 }
13383 }
13384
13385 return item;
13386}
13387
13388proto_item *
13389proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13390 const unsigned bit_offset, const int no_of_bits,
13391 const unsigned encoding)
13392{
13393 header_field_info *hfinfo;
13394 int octet_length;
13395 int octet_offset;
13396
13397 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", 13397, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13397
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13397, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13398
13399 if (no_of_bits < 0) {
13400 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13401 }
13402 octet_length = (no_of_bits + 7) >> 3;
13403 octet_offset = bit_offset >> 3;
13404 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13405
13406 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13407 * but only after doing a bunch more work (which we can, in the common
13408 * case, shortcut here).
13409 */
13410 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13411 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", 13411
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13411, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13411, "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", 13411, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13412
13413 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13414}
13415
13416/*
13417 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13418 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13419 * Offset should be given in bits from the start of the tvb.
13420 */
13421
13422static proto_item *
13423_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13424 const unsigned bit_offset, const int no_of_bits,
13425 uint64_t *return_value, const unsigned encoding)
13426{
13427 int offset;
13428 unsigned length;
13429 uint8_t tot_no_bits;
13430 char *bf_str;
13431 char lbl_str[ITEM_LABEL_LENGTH240];
13432 uint64_t value = 0;
13433 uint8_t *bytes = NULL((void*)0);
13434 size_t bytes_length = 0;
13435
13436 proto_item *pi;
13437 header_field_info *hf_field;
13438
13439 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13440 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", 13440, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13440
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13440, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13441
13442 if (hf_field->bitmask != 0) {
13443 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)
13444 " 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)
13445 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)
;
13446 }
13447
13448 if (no_of_bits < 0) {
13449 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13450 } else if (no_of_bits == 0) {
13451 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)
13452 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)
;
13453 }
13454
13455 /* Byte align offset */
13456 offset = bit_offset>>3;
13457
13458 /*
13459 * Calculate the number of octets used to hold the bits
13460 */
13461 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13462 length = (tot_no_bits + 7) >> 3;
13463
13464 if (no_of_bits < 65) {
13465 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13466 } else if (hf_field->type != FT_BYTES) {
13467 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)
13468 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)
;
13469 return NULL((void*)0);
13470 }
13471
13472 /* Sign extend for signed types */
13473 switch (hf_field->type) {
13474 case FT_INT8:
13475 case FT_INT16:
13476 case FT_INT24:
13477 case FT_INT32:
13478 case FT_INT40:
13479 case FT_INT48:
13480 case FT_INT56:
13481 case FT_INT64:
13482 value = ws_sign_ext64(value, no_of_bits);
13483 break;
13484
13485 default:
13486 break;
13487 }
13488
13489 if (return_value) {
13490 *return_value = value;
13491 }
13492
13493 /* Coast clear. Try and fake it */
13494 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13495 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", 13495
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13495, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13495, "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", 13495, __func__, "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); } } }
;
13496
13497 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13498
13499 switch (hf_field->type) {
13500 case FT_BOOLEAN:
13501 /* Boolean field */
13502 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13503 "%s = %s: %s",
13504 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13505 break;
13506
13507 case FT_CHAR:
13508 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13509 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13510 break;
13511
13512 case FT_UINT8:
13513 case FT_UINT16:
13514 case FT_UINT24:
13515 case FT_UINT32:
13516 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13517 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13518 break;
13519
13520 case FT_INT8:
13521 case FT_INT16:
13522 case FT_INT24:
13523 case FT_INT32:
13524 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13525 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13526 break;
13527
13528 case FT_UINT40:
13529 case FT_UINT48:
13530 case FT_UINT56:
13531 case FT_UINT64:
13532 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13533 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13534 break;
13535
13536 case FT_INT40:
13537 case FT_INT48:
13538 case FT_INT56:
13539 case FT_INT64:
13540 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13541 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13542 break;
13543
13544 case FT_BYTES:
13545 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13546 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13547 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13548 proto_item_set_text(pi, "%s", lbl_str);
13549 return pi;
13550
13551 /* TODO: should handle FT_UINT_BYTES ? */
13552
13553 default:
13554 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))
13555 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))
13556 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))
13557 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))
;
13558 return NULL((void*)0);
13559 }
13560
13561 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13562 return pi;
13563}
13564
13565proto_item *
13566proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13567 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13568 uint64_t *return_value)
13569{
13570 proto_item *pi;
13571 int no_of_bits;
13572 int octet_offset;
13573 unsigned mask_initial_bit_offset;
13574 unsigned mask_greatest_bit_offset;
13575 unsigned octet_length;
13576 uint8_t i;
13577 char bf_str[256];
13578 char lbl_str[ITEM_LABEL_LENGTH240];
13579 uint64_t value;
13580 uint64_t composite_bitmask;
13581 uint64_t composite_bitmap;
13582
13583 header_field_info *hf_field;
13584
13585 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13586 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", 13586, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13586
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13586, "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
13587
13588 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13589 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)
13590 " 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)
13591 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)
;
13592 }
13593
13594 mask_initial_bit_offset = bit_offset % 8;
13595
13596 no_of_bits = 0;
13597 value = 0;
13598 i = 0;
13599 mask_greatest_bit_offset = 0;
13600 composite_bitmask = 0;
13601 composite_bitmap = 0;
13602
13603 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
13604 uint64_t crumb_mask, crumb_value;
13605 uint8_t crumb_end_bit_offset;
13606
13607 crumb_value = tvb_get_bits64(tvb,
13608 bit_offset + crumb_spec[i].crumb_bit_offset,
13609 crumb_spec[i].crumb_bit_length,
13610 ENC_BIG_ENDIAN0x00000000);
13611 value += crumb_value;
13612 no_of_bits += crumb_spec[i].crumb_bit_length;
13613 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", 13613
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13614
13615 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13616 octet containing the initial offset.
13617 If the mask is beyond 32 bits, then give up on bit map display.
13618 This could be improved in future, probably showing a table
13619 of 32 or 64 bits per row */
13620 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13621 crumb_end_bit_offset = mask_initial_bit_offset
13622 + crumb_spec[i].crumb_bit_offset
13623 + crumb_spec[i].crumb_bit_length;
13624 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'
13625
13626 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13627 mask_greatest_bit_offset = crumb_end_bit_offset;
13628 }
13629 /* Currently the bitmap of the crumbs are only shown if
13630 * smaller than 32 bits. Do not bother calculating the
13631 * mask if it is larger than that. */
13632 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13633 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'
13634 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13635 }
13636 }
13637 /* Shift left for the next segment */
13638 value <<= crumb_spec[++i].crumb_bit_length;
13639 }
13640
13641 /* Sign extend for signed types */
13642 switch (hf_field->type) {
13643 case FT_INT8:
13644 case FT_INT16:
13645 case FT_INT24:
13646 case FT_INT32:
13647 case FT_INT40:
13648 case FT_INT48:
13649 case FT_INT56:
13650 case FT_INT64:
13651 value = ws_sign_ext64(value, no_of_bits);
13652 break;
13653 default:
13654 break;
13655 }
13656
13657 if (return_value) {
13658 *return_value = value;
13659 }
13660
13661 /* Coast clear. Try and fake it */
13662 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13663 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", 13663
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13663, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13663, "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", 13663, __func__, "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); } } }
;
13664
13665 /* initialise the format string */
13666 bf_str[0] = '\0';
13667
13668 octet_offset = bit_offset >> 3;
13669
13670 /* Round up mask length to nearest octet */
13671 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13672 mask_greatest_bit_offset = octet_length << 3;
13673
13674 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13675 It would be a useful enhancement to eliminate this restriction. */
13676 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13677 other_decode_bitfield_value(bf_str,
13678 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13679 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13680 mask_greatest_bit_offset);
13681 } else {
13682 /* If the bitmask is too large, try to describe its contents. */
13683 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13684 }
13685
13686 switch (hf_field->type) {
13687 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13688 /* Boolean field */
13689 return proto_tree_add_boolean_format(tree, hfindex,
13690 tvb, octet_offset, octet_length, value,
13691 "%s = %s: %s",
13692 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13693 break;
13694
13695 case FT_CHAR:
13696 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13697 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13698 break;
13699
13700 case FT_UINT8:
13701 case FT_UINT16:
13702 case FT_UINT24:
13703 case FT_UINT32:
13704 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13705 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13706 break;
13707
13708 case FT_INT8:
13709 case FT_INT16:
13710 case FT_INT24:
13711 case FT_INT32:
13712 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13713 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13714 break;
13715
13716 case FT_UINT40:
13717 case FT_UINT48:
13718 case FT_UINT56:
13719 case FT_UINT64:
13720 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13721 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13722 break;
13723
13724 case FT_INT40:
13725 case FT_INT48:
13726 case FT_INT56:
13727 case FT_INT64:
13728 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13729 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13730 break;
13731
13732 default:
13733 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))
13734 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))
13735 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))
13736 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))
;
13737 return NULL((void*)0);
13738 }
13739 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13740 return pi;
13741}
13742
13743void
13744proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13745 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13746{
13747 header_field_info *hfinfo;
13748 int start = bit_offset >> 3;
13749 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13750
13751 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13752 * so that we can use the tree's memory scope in calculating the string */
13753 if (length == -1) {
13754 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13755 } else {
13756 tvb_ensure_bytes_exist(tvb, start, length);
13757 }
13758 if (!tree) return;
13759
13760 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", 13760, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13760
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13760, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13761 proto_tree_add_text_internal(tree, tvb, start, length,
13762 "%s crumb %d of %s (decoded above)",
13763 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13764 tvb_get_bits32(tvb,
13765 bit_offset,
13766 crumb_spec[crumb_index].crumb_bit_length,
13767 ENC_BIG_ENDIAN0x00000000),
13768 ENC_BIG_ENDIAN0x00000000),
13769 crumb_index,
13770 hfinfo->name);
13771}
13772
13773proto_item *
13774proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13775 const unsigned bit_offset, const int no_of_bits,
13776 uint64_t *return_value, const unsigned encoding)
13777{
13778 proto_item *item;
13779
13780 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13781 bit_offset, no_of_bits,
13782 return_value, encoding))) {
13783 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)
;
13784 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)
;
13785 }
13786 return item;
13787}
13788
13789static proto_item *
13790_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13791 tvbuff_t *tvb, const unsigned bit_offset,
13792 const int no_of_bits, void *value_ptr,
13793 const unsigned encoding, char *value_str)
13794{
13795 int offset;
13796 unsigned length;
13797 uint8_t tot_no_bits;
13798 char *str;
13799 uint64_t value = 0;
13800 header_field_info *hf_field;
13801
13802 /* We do not have to return a value, try to fake it as soon as possible */
13803 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13804 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", 13804
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13804, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13804, "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", 13804, __func__, "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); } } }
;
13805
13806 if (hf_field->bitmask != 0) {
13807 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)
13808 " 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)
13809 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)
;
13810 }
13811
13812 if (no_of_bits < 0) {
13813 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13814 } else if (no_of_bits == 0) {
13815 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)
13816 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)
;
13817 }
13818
13819 /* Byte align offset */
13820 offset = bit_offset>>3;
13821
13822 /*
13823 * Calculate the number of octets used to hold the bits
13824 */
13825 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13826 length = tot_no_bits>>3;
13827 /* If we are using part of the next octet, increase length by 1 */
13828 if (tot_no_bits & 0x07)
13829 length++;
13830
13831 if (no_of_bits < 65) {
13832 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13833 } else {
13834 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)
13835 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)
;
13836 return NULL((void*)0);
13837 }
13838
13839 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13840
13841 (void) g_strlcat(str, " = ", 256+64);
13842 (void) g_strlcat(str, hf_field->name, 256+64);
13843
13844 /*
13845 * This function does not receive an actual value but a dimensionless pointer to that value.
13846 * For this reason, the type of the header field is examined in order to determine
13847 * what kind of value we should read from this address.
13848 * The caller of this function must make sure that for the specific header field type the address of
13849 * a compatible value is provided.
13850 */
13851 switch (hf_field->type) {
13852 case FT_BOOLEAN:
13853 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13854 "%s: %s", str, value_str);
13855 break;
13856
13857 case FT_CHAR:
13858 case FT_UINT8:
13859 case FT_UINT16:
13860 case FT_UINT24:
13861 case FT_UINT32:
13862 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13863 "%s: %s", str, value_str);
13864 break;
13865
13866 case FT_UINT40:
13867 case FT_UINT48:
13868 case FT_UINT56:
13869 case FT_UINT64:
13870 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13871 "%s: %s", str, value_str);
13872 break;
13873
13874 case FT_INT8:
13875 case FT_INT16:
13876 case FT_INT24:
13877 case FT_INT32:
13878 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13879 "%s: %s", str, value_str);
13880 break;
13881
13882 case FT_INT40:
13883 case FT_INT48:
13884 case FT_INT56:
13885 case FT_INT64:
13886 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13887 "%s: %s", str, value_str);
13888 break;
13889
13890 case FT_FLOAT:
13891 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13892 "%s: %s", str, value_str);
13893 break;
13894
13895 default:
13896 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))
13897 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))
13898 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))
13899 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))
;
13900 return NULL((void*)0);
13901 }
13902}
13903
13904static proto_item *
13905proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13906 tvbuff_t *tvb, const unsigned bit_offset,
13907 const int no_of_bits, void *value_ptr,
13908 const unsigned encoding, char *value_str)
13909{
13910 proto_item *item;
13911
13912 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13913 tvb, bit_offset, no_of_bits,
13914 value_ptr, encoding, value_str))) {
13915 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)
;
13916 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)
;
13917 }
13918 return item;
13919}
13920
13921#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);
\
13922 va_start(ap, format)__builtin_va_start(ap, format); \
13923 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13924 va_end(ap)__builtin_va_end(ap);
13925
13926proto_item *
13927proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13928 tvbuff_t *tvb, const unsigned bit_offset,
13929 const int no_of_bits, uint32_t value,
13930 const unsigned encoding,
13931 const char *format, ...)
13932{
13933 va_list ap;
13934 char *dst;
13935 header_field_info *hf_field;
13936
13937 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13938
13939 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", 13939
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13939, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13939, "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", 13939, __func__, "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); } } }
;
13940
13941 switch (hf_field->type) {
13942 case FT_UINT8:
13943 case FT_UINT16:
13944 case FT_UINT24:
13945 case FT_UINT32:
13946 break;
13947
13948 default:
13949 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)
13950 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)
;
13951 return NULL((void*)0);
13952 }
13953
13954 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);
;
13955
13956 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13957}
13958
13959proto_item *
13960proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13961 tvbuff_t *tvb, const unsigned bit_offset,
13962 const int no_of_bits, uint64_t value,
13963 const unsigned encoding,
13964 const char *format, ...)
13965{
13966 va_list ap;
13967 char *dst;
13968 header_field_info *hf_field;
13969
13970 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13971
13972 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", 13972
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13972, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13972, "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", 13972, __func__, "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); } } }
;
13973
13974 switch (hf_field->type) {
13975 case FT_UINT40:
13976 case FT_UINT48:
13977 case FT_UINT56:
13978 case FT_UINT64:
13979 break;
13980
13981 default:
13982 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)
13983 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)
;
13984 return NULL((void*)0);
13985 }
13986
13987 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);
;
13988
13989 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13990}
13991
13992proto_item *
13993proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13994 tvbuff_t *tvb, const unsigned bit_offset,
13995 const int no_of_bits, float value,
13996 const unsigned encoding,
13997 const char *format, ...)
13998{
13999 va_list ap;
14000 char *dst;
14001 header_field_info *hf_field;
14002
14003 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14004
14005 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", 14005
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14005, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14005, "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", 14005, __func__, "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); } } }
;
14006
14007 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",
14007, ((hf_field))->abbrev))))
;
14008
14009 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);
;
14010
14011 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14012}
14013
14014proto_item *
14015proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14016 tvbuff_t *tvb, const unsigned bit_offset,
14017 const int no_of_bits, int32_t value,
14018 const unsigned encoding,
14019 const char *format, ...)
14020{
14021 va_list ap;
14022 char *dst;
14023 header_field_info *hf_field;
14024
14025 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14026
14027 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", 14027
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14027, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14027, "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", 14027, __func__, "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); } } }
;
14028
14029 switch (hf_field->type) {
14030 case FT_INT8:
14031 case FT_INT16:
14032 case FT_INT24:
14033 case FT_INT32:
14034 break;
14035
14036 default:
14037 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)
14038 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)
;
14039 return NULL((void*)0);
14040 }
14041
14042 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);
;
14043
14044 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14045}
14046
14047proto_item *
14048proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14049 tvbuff_t *tvb, const unsigned bit_offset,
14050 const int no_of_bits, int64_t value,
14051 const unsigned encoding,
14052 const char *format, ...)
14053{
14054 va_list ap;
14055 char *dst;
14056 header_field_info *hf_field;
14057
14058 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14059
14060 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", 14060
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14060, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14060, "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", 14060, __func__, "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); } } }
;
14061
14062 switch (hf_field->type) {
14063 case FT_INT40:
14064 case FT_INT48:
14065 case FT_INT56:
14066 case FT_INT64:
14067 break;
14068
14069 default:
14070 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)
14071 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)
;
14072 return NULL((void*)0);
14073 }
14074
14075 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);
;
14076
14077 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14078}
14079
14080proto_item *
14081proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14082 tvbuff_t *tvb, const unsigned bit_offset,
14083 const int no_of_bits, uint64_t value,
14084 const unsigned encoding,
14085 const char *format, ...)
14086{
14087 va_list ap;
14088 char *dst;
14089 header_field_info *hf_field;
14090
14091 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14092
14093 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", 14093
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14093, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14093, "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", 14093, __func__, "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); } } }
;
14094
14095 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"
, 14095, ((hf_field))->abbrev))))
;
14096
14097 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);
;
14098
14099 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14100}
14101
14102proto_item *
14103proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14104 const unsigned bit_offset, const int no_of_chars)
14105{
14106 proto_item *pi;
14107 header_field_info *hfinfo;
14108 int byte_length;
14109 int byte_offset;
14110 char *string;
14111
14112 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14113
14114 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", 14114
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14114, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14114, "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", 14114, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14115
14116 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"
, 14116, ((hfinfo))->abbrev))))
;
14117
14118 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14119 byte_offset = bit_offset >> 3;
14120
14121 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14122
14123 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14124 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14124, "byte_length >= 0"
))))
;
14125 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14126
14127 return pi;
14128}
14129
14130proto_item *
14131proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14132 const unsigned bit_offset, const int no_of_chars)
14133{
14134 proto_item *pi;
14135 header_field_info *hfinfo;
14136 int byte_length;
14137 int byte_offset;
14138 char *string;
14139
14140 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14141
14142 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", 14142
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14142, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14142, "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", 14142, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14143
14144 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"
, 14144, ((hfinfo))->abbrev))))
;
14145
14146 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14147 byte_offset = bit_offset >> 3;
14148
14149 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14150
14151 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14152 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14152, "byte_length >= 0"
))))
;
14153 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14154
14155 return pi;
14156}
14157
14158const value_string proto_checksum_vals[] = {
14159 { PROTO_CHECKSUM_E_BAD, "Bad" },
14160 { PROTO_CHECKSUM_E_GOOD, "Good" },
14161 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14162 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14163 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14164
14165 { 0, NULL((void*)0) }
14166};
14167
14168proto_item *
14169proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14170 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14171 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14172{
14173 header_field_info *hfinfo;
14174 uint32_t checksum;
14175 uint32_t len;
14176 proto_item* ti = NULL((void*)0);
14177 proto_item* ti2;
14178 bool_Bool incorrect_checksum = true1;
14179
14180 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", 14180, __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", 14180
, "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", 14180, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14181
14182 switch (hfinfo->type) {
14183 case FT_UINT8:
14184 len = 1;
14185 break;
14186 case FT_UINT16:
14187 len = 2;
14188 break;
14189 case FT_UINT24:
14190 len = 3;
14191 break;
14192 case FT_UINT32:
14193 len = 4;
14194 break;
14195 default:
14196 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)
14197 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14198 }
14199
14200 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14201 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14202 proto_item_set_generated(ti);
14203 if (hf_checksum_status != -1) {
14204 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14205 proto_item_set_generated(ti2);
14206 }
14207 return ti;
14208 }
14209
14210 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14211 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14212 proto_item_set_generated(ti);
14213 } else {
14214 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14215 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14216 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14217 if (computed_checksum == 0) {
14218 proto_item_append_text(ti, " [correct]");
14219 if (hf_checksum_status != -1) {
14220 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14221 proto_item_set_generated(ti2);
14222 }
14223 incorrect_checksum = false0;
14224 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14225 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14226 /* XXX - This can't distinguish between "shouldbe"
14227 * 0x0000 and 0xFFFF unless we know whether there
14228 * were any nonzero bits (other than the checksum).
14229 * Protocols should not use this path if they might
14230 * have an all zero packet.
14231 * Some implementations put the wrong zero; maybe
14232 * we should have a special expert info for that?
14233 */
14234 }
14235 } else {
14236 if (checksum == computed_checksum) {
14237 proto_item_append_text(ti, " [correct]");
14238 if (hf_checksum_status != -1) {
14239 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14240 proto_item_set_generated(ti2);
14241 }
14242 incorrect_checksum = false0;
14243 }
14244 }
14245
14246 if (incorrect_checksum) {
14247 if (hf_checksum_status != -1) {
14248 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14249 proto_item_set_generated(ti2);
14250 }
14251 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14252 proto_item_append_text(ti, " [incorrect]");
14253 if (bad_checksum_expert != NULL((void*)0))
14254 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14255 } else {
14256 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14257 if (bad_checksum_expert != NULL((void*)0))
14258 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);
14259 }
14260 }
14261 } else {
14262 if (hf_checksum_status != -1) {
14263 proto_item_append_text(ti, " [unverified]");
14264 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14265 proto_item_set_generated(ti2);
14266 }
14267 }
14268 }
14269
14270 return ti;
14271}
14272
14273proto_item *
14274proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14275 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14276 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14277{
14278 header_field_info *hfinfo;
14279 uint8_t *checksum = NULL((void*)0);
14280 proto_item* ti = NULL((void*)0);
14281 proto_item* ti2;
14282 bool_Bool incorrect_checksum = true1;
14283
14284 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", 14284, __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", 14284
, "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", 14284, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14285
14286 if (hfinfo->type != FT_BYTES) {
14287 REPORT_DISSECTOR_BUG("field %s is not of type FT_BYTES",proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
14288 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14289 }
14290
14291 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14292 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14293 proto_item_set_generated(ti);
14294 if (hf_checksum_status != -1) {
14295 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14296 proto_item_set_generated(ti2);
14297 }
14298 return ti;
14299 }
14300
14301 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14302 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14303 proto_item_set_generated(ti);
14304 } else {
14305 checksum = (uint8_t*)wmem_alloc0_array(pinfo->pool, uint8_t, checksum_len)((uint8_t*)wmem_alloc0((pinfo->pool), (((((checksum_len)) <=
0) || ((size_t)sizeof(uint8_t) > (9223372036854775807L / (
size_t)((checksum_len))))) ? 0 : (sizeof(uint8_t) * ((checksum_len
))))))
;
14306 tvb_memcpy(tvb, checksum, offset, checksum_len);
14307 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14308 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14309 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14310 if (computed_checksum == 0) {
14311 proto_item_append_text(ti, " [correct]");
14312 if (hf_checksum_status != -1) {
14313 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14314 proto_item_set_generated(ti2);
14315 }
14316 incorrect_checksum = false0;
14317 }
14318 } else {
14319 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14320 proto_item_append_text(ti, " [correct]");
14321 if (hf_checksum_status != -1) {
14322 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14323 proto_item_set_generated(ti2);
14324 }
14325 incorrect_checksum = false0;
14326 }
14327 }
14328
14329 if (incorrect_checksum) {
14330 if (hf_checksum_status != -1) {
14331 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14332 proto_item_set_generated(ti2);
14333 }
14334 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14335 proto_item_append_text(ti, " [incorrect]");
14336 if (bad_checksum_expert != NULL((void*)0))
14337 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14338 } else {
14339 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14340 char *computed_checksum_str = (char*)wmem_alloc0_array(pinfo->pool, char, computed_checksum_str_len)((char*)wmem_alloc0((pinfo->pool), (((((computed_checksum_str_len
)) <= 0) || ((size_t)sizeof(char) > (9223372036854775807L
/ (size_t)((computed_checksum_str_len))))) ? 0 : (sizeof(char
) * ((computed_checksum_str_len))))))
;
14341 for (size_t counter = 0; counter < checksum_len; ++counter) {
14342 snprintf(
14343 /* On ecah iteration inserts two characters */
14344 (char*)&computed_checksum_str[counter << 1],
14345 computed_checksum_str_len - (counter << 1),
14346 "%02x",
14347 computed_checksum[counter]);
14348 }
14349 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14350 if (bad_checksum_expert != NULL((void*)0))
14351 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14352 }
14353 }
14354 } else {
14355 if (hf_checksum_status != -1) {
14356 proto_item_append_text(ti, " [unverified]");
14357 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14358 proto_item_set_generated(ti2);
14359 }
14360 }
14361 }
14362
14363 return ti;
14364}
14365
14366unsigned char
14367proto_check_field_name(const char *field_name)
14368{
14369 return module_check_valid_name(field_name, false0);
14370}
14371
14372unsigned char
14373proto_check_field_name_lower(const char *field_name)
14374{
14375 return module_check_valid_name(field_name, true1);
14376}
14377
14378bool_Bool
14379tree_expanded(int tree_type)
14380{
14381 if (tree_type <= 0) {
14382 return false0;
14383 }
14384 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", 14384, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14385 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14386}
14387
14388void
14389tree_expanded_set(int tree_type, bool_Bool value)
14390{
14391 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", 14391, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14392
14393 if (value)
14394 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14395 else
14396 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14397}
14398
14399/*
14400 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14401 *
14402 * Local variables:
14403 * c-basic-offset: 8
14404 * tab-width: 8
14405 * indent-tabs-mode: t
14406 * End:
14407 *
14408 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14409 * :indentSize=8:tabSize=8:noTabs=false:
14410 */