Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/lua5.5 -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-06-100400-3595-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 unsigned cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is equal to 0 */
102#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
103 if (length == 0) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is equal to 0 */
111#define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
112 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (length == 0) { ((void)0); return ((void*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const unsigned start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 unsigned start, int *length);
300
301static proto_item *
302proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303 unsigned start, unsigned *length);
304
305static void
306proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307static void
308proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309
310static void
311proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312static void
313proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314static void
315proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316static void
317proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318static void
319proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320static void
321proto_tree_set_string(field_info *fi, const char* value);
322static void
323proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326static void
327proto_tree_set_vines(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330static void
331proto_tree_set_ether(field_info *fi, const uint8_t* value);
332static void
333proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334static void
335proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336static void
337proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338static void
339proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340static void
341proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342static void
343proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344static void
345proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346static void
347proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348static void
349proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350static void
351proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352static void
353proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354static void
355proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356static void
357proto_tree_set_boolean(field_info *fi, uint64_t value);
358static void
359proto_tree_set_float(field_info *fi, float value);
360static void
361proto_tree_set_double(field_info *fi, double value);
362static void
363proto_tree_set_uint(field_info *fi, uint32_t value);
364static void
365proto_tree_set_int(field_info *fi, int32_t value);
366static void
367proto_tree_set_uint64(field_info *fi, uint64_t value);
368static void
369proto_tree_set_int64(field_info *fi, int64_t value);
370static void
371proto_tree_set_eui64(field_info *fi, const uint64_t value);
372static void
373proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374
375/* Handle type length mismatch (now filterable) expert info */
376static int proto_type_length_mismatch;
377static expert_field ei_type_length_mismatch_error;
378static expert_field ei_type_length_mismatch_warn;
379static void register_type_length_mismatch(void);
380
381/* Handle byte array string decoding errors with expert info */
382static int proto_byte_array_string_decoding_error;
383static expert_field ei_byte_array_string_decoding_failed_error;
384static void register_byte_array_string_decodinws_error(void);
385
386/* Handle date and time string decoding errors with expert info */
387static int proto_date_time_string_decoding_error;
388static expert_field ei_date_time_string_decoding_failed_error;
389static void register_date_time_string_decodinws_error(void);
390
391/* Handle string errors expert info */
392static int proto_string_errors;
393static expert_field ei_string_trailing_characters;
394static void register_string_errors(void);
395
396static int proto_register_field_init(header_field_info *hfinfo, const int parent);
397
398/* special-case header field used within proto.c */
399static header_field_info hfi_text_only =
400 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
401int hf_text_only;
402
403/* Structure for information about a protocol */
404struct _protocol {
405 const char *name; /* long description */
406 const char *short_name; /* short description */
407 const char *filter_name; /* name of this protocol in filters */
408 GPtrArray *fields; /* fields for this protocol */
409 int proto_id; /* field ID for this protocol */
410 bool_Bool is_enabled; /* true if protocol is enabled */
411 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
412 bool_Bool can_toggle; /* true if is_enabled can be changed */
413 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
414 For dissectors that need a protocol name so they
415 can be added to a dissector table, but use the
416 parent_proto_id for things like enable/disable */
417 GList *heur_list; /* Heuristic dissectors associated with this protocol */
418};
419
420/* List of all protocols */
421static GList *protocols;
422
423/* Structure stored for deregistered g_slice */
424struct g_slice_data {
425 size_t block_size;
426 void *mem_block;
427};
428
429/* Deregistered fields */
430static GPtrArray *deregistered_fields;
431static GPtrArray *deregistered_data;
432static GPtrArray *deregistered_slice;
433
434/* indexed by prefix, contains initializers */
435static GHashTable* prefixes;
436
437/* Contains information about a field when a dissector calls
438 * proto_tree_add_item. */
439#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
440#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
441
442/* Contains the space for proto_nodes. */
443#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
444 node->first_child = NULL((void*)0); \
445 node->last_child = NULL((void*)0); \
446 node->next = NULL((void*)0);
447
448#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
449 wmem_free(pool, node)
450
451/* String space for protocol and field items for the GUI */
452#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
453 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
454 il->value_pos = 0; \
455 il->value_len = 0;
456#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
457 wmem_free(pool, il);
458
459#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 459, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 459, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
460 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
461 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 461
, __func__, "Unregistered hf! index=%d", hfindex)
; \
462 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 462, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
463 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
464 hfinfo = gpa_hfinfo.hfi[hfindex];
465
466#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
467
468/* List which stores protocols and fields that have been registered */
469typedef struct _gpa_hfinfo_t {
470 uint32_t len;
471 uint32_t allocated_len;
472 header_field_info **hfi;
473} gpa_hfinfo_t;
474
475static gpa_hfinfo_t gpa_hfinfo;
476
477/* Hash table of abbreviations and IDs */
478static wmem_map_t *gpa_name_map;
479static header_field_info *same_name_hfinfo;
480
481/* Hash table protocol aliases. const char * -> const char * */
482static GHashTable *gpa_protocol_aliases;
483
484/*
485 * We're called repeatedly with the same field name when sorting a column.
486 * Cache our last gpa_name_map hit for faster lookups.
487 */
488static char *last_field_name;
489static header_field_info *last_hfinfo;
490
491/* Points to the first element of an array of bits, indexed by
492 a subtree item type; that array element is true if subtrees of
493 an item of that type are to be expanded. */
494static uint32_t *tree_is_expanded;
495
496/* Number of elements in that array. The entry with index 0 is not used. */
497int num_tree_types = 1;
498
499/* Name hashtables for fast detection of duplicate names */
500static GHashTable* proto_names;
501static GHashTable* proto_short_names;
502static GHashTable* proto_filter_names;
503
504static const char * const reserved_filter_names[] = {
505 /* Display filter keywords. */
506 "eq",
507 "ne",
508 "all_eq",
509 "any_eq",
510 "all_ne",
511 "any_ne",
512 "gt",
513 "ge",
514 "lt",
515 "le",
516 "bitand",
517 "bitwise_and",
518 "contains",
519 "matches",
520 "not",
521 "and",
522 "or",
523 "xor",
524 "in",
525 "any",
526 "all",
527 "true",
528 "false",
529 "nan",
530 "inf",
531 "infinity",
532 NULL((void*)0)
533};
534
535static GHashTable *proto_reserved_filter_names;
536static GQueue* saved_dir_queue;
537
538static int
539proto_compare_name(const void *p1_arg, const void *p2_arg)
540{
541 const protocol_t *p1 = (const protocol_t *)p1_arg;
542 const protocol_t *p2 = (const protocol_t *)p2_arg;
543
544 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
545}
546
547static GSList *dissector_plugins;
548
549#ifdef HAVE_PLUGINS1
550void
551proto_register_plugin(const proto_plugin *plug)
552{
553 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
554}
555#else /* HAVE_PLUGINS */
556void
557proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
558{
559 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 559, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
560}
561#endif /* HAVE_PLUGINS */
562
563static void
564call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
565{
566 proto_plugin *plug = (proto_plugin *)data;
567
568 if (plug->register_protoinfo) {
569 plug->register_protoinfo();
570 }
571}
572
573static void
574call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
575{
576 proto_plugin *plug = (proto_plugin *)data;
577
578 if (plug->register_handoff) {
579 plug->register_handoff();
580 }
581}
582
583void proto_pre_init(void)
584{
585 saved_dir_queue = g_queue_new();
586
587 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
589 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
590
591 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
592 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
593 /* GHashTable has no key destructor so the cast is safe. */
594 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
595 }
596
597 gpa_hfinfo.len = 0;
598 gpa_hfinfo.allocated_len = 0;
599 gpa_hfinfo.hfi = NULL((void*)0);
600 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
601 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
602 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
603 deregistered_fields = g_ptr_array_new();
604 deregistered_data = g_ptr_array_new();
605 deregistered_slice = g_ptr_array_new();
606}
607
608/* initialize data structures and register protocols and fields */
609void
610proto_init(GSList *register_all_plugin_protocols_list,
611 GSList *register_all_plugin_handoffs_list,
612 register_entity_func register_func, register_entity_func handoff_func,
613 register_cb cb,
614 void *client_data)
615{
616 /* Initialize the ftype subsystem */
617 ftypes_initialize();
618
619 /* Initialize the address type subsystem */
620 address_types_initialize();
621
622 /* Register one special-case FT_TEXT_ONLY field for use when
623 converting wireshark to new-style proto_tree. These fields
624 are merely strings on the GUI tree; they are not filterable */
625 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
626
627 /* Register the pseudo-protocols used for exceptions. */
628 register_show_exception();
629 register_type_length_mismatch();
630 register_byte_array_string_decodinws_error();
631 register_date_time_string_decodinws_error();
632 register_string_errors();
633 ftypes_register_pseudofields();
634 col_register_protocol();
635
636 /* Have each built-in dissector register its protocols, fields,
637 dissector tables, and dissectors to be called through a
638 handle, and do whatever one-time initialization it needs to
639 do. */
640 if (register_func != NULL((void*)0))
641 register_func(cb, client_data);
642
643 /* Now call the registration routines for all epan plugins. */
644 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
645 ((void (*)(register_cb, void *))l->data)(cb, client_data);
646 }
647
648 /* Now call the registration routines for all dissector plugins. */
649 if (cb)
650 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
651 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
652
653 /* Now call the "handoff registration" routines of all built-in
654 dissectors; those routines register the dissector in other
655 dissectors' handoff tables, and fetch any dissector handles
656 they need. */
657 if (handoff_func != NULL((void*)0))
658 handoff_func(cb, client_data);
659
660 /* Now do the same with epan plugins. */
661 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
662 ((void (*)(register_cb, void *))l->data)(cb, client_data);
663 }
664
665 /* Now do the same with dissector plugins. */
666 if (cb)
667 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
668 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
669
670 /* sort the protocols by protocol name */
671 protocols = g_list_sort(protocols, proto_compare_name);
672
673 /* sort the dissector handles in dissector tables (for -G reports
674 * and -d error messages. The GUI sorts the handles itself.) */
675 packet_all_tables_sort_handles();
676
677 /* We've assigned all the subtree type values; allocate the array
678 for them, and zero it out. */
679 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
680}
681
682static void
683proto_cleanup_base(void)
684{
685 protocol_t *protocol;
686 header_field_info *hfinfo;
687
688 /* Free the abbrev/ID hash table */
689 if (gpa_name_map) {
690 // XXX - We don't have a wmem_map_destroy, but
691 // it does get cleaned up when epan scope is
692 // destroyed
693 //g_hash_table_destroy(gpa_name_map);
694 gpa_name_map = NULL((void*)0);
695 }
696 if (gpa_protocol_aliases) {
697 g_hash_table_destroy(gpa_protocol_aliases);
698 gpa_protocol_aliases = NULL((void*)0);
699 }
700 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
701 last_field_name = NULL((void*)0);
702
703 while (protocols) {
704 protocol = (protocol_t *)protocols->data;
705 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 705
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 705, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 705, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
706 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 706, "protocol->proto_id == hfinfo->id"
))))
;
707
708 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
709 if (protocol->parent_proto_id != -1) {
710 // pino protocol
711 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 711, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
712 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 712, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
713 } else {
714 if (protocol->fields) {
715 g_ptr_array_free(protocol->fields, true1);
716 }
717 g_list_free(protocol->heur_list);
718 }
719 protocols = g_list_remove(protocols, protocol);
720 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
721 }
722
723 if (proto_names) {
724 g_hash_table_destroy(proto_names);
725 proto_names = NULL((void*)0);
726 }
727
728 if (proto_short_names) {
729 g_hash_table_destroy(proto_short_names);
730 proto_short_names = NULL((void*)0);
731 }
732
733 if (proto_filter_names) {
734 g_hash_table_destroy(proto_filter_names);
735 proto_filter_names = NULL((void*)0);
736 }
737
738 if (proto_reserved_filter_names) {
739 g_hash_table_destroy(proto_reserved_filter_names);
740 proto_reserved_filter_names = NULL((void*)0);
741 }
742
743 if (gpa_hfinfo.allocated_len) {
744 gpa_hfinfo.len = 0;
745 gpa_hfinfo.allocated_len = 0;
746 g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1
)) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo
.hfi), 0)) : (g_free) (gpa_hfinfo.hfi)
;
747 gpa_hfinfo.hfi = NULL((void*)0);
748 }
749
750 if (deregistered_fields) {
751 g_ptr_array_free(deregistered_fields, true1);
752 deregistered_fields = NULL((void*)0);
753 }
754
755 if (deregistered_data) {
756 g_ptr_array_free(deregistered_data, true1);
757 deregistered_data = NULL((void*)0);
758 }
759
760 if (deregistered_slice) {
761 g_ptr_array_free(deregistered_slice, true1);
762 deregistered_slice = NULL((void*)0);
763 }
764
765 g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) -
1)) ? g_free_sized (tree_is_expanded, __builtin_object_size (
(tree_is_expanded), 0)) : (g_free) (tree_is_expanded)
;
766 tree_is_expanded = NULL((void*)0);
767
768 if (prefixes)
769 g_hash_table_destroy(prefixes);
770
771 if (saved_dir_queue != NULL((void*)0)) {
772 g_queue_clear_full(saved_dir_queue, g_free);
773 g_queue_free(saved_dir_queue);
774 saved_dir_queue = NULL((void*)0);
775 }
776}
777
778void
779proto_cleanup(void)
780{
781 proto_free_deregistered_fields();
782 proto_cleanup_base();
783
784 g_slist_free(dissector_plugins);
785 dissector_plugins = NULL((void*)0);
786}
787
788static bool_Bool
789ws_pushd(const char* dir)
790{
791 //Save the current working directory
792 const char* save_wd = get_current_working_dir();
793 if (save_wd != NULL((void*)0))
794 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
795
796 //Change to the new one
797#ifdef _WIN32
798 SetCurrentDirectory(utf_8to16(dir));
799 return true1;
800#else
801 return (chdir(dir) == 0);
802#endif
803}
804
805static bool_Bool
806ws_popd(void)
807{
808 int ret = 0;
809 char* saved_wd = g_queue_pop_head(saved_dir_queue);
810 if (saved_wd == NULL((void*)0))
811 return false0;
812
813 //Restore the previous one
814#ifdef _WIN32
815 SetCurrentDirectory(utf_8to16(saved_wd));
816#else
817 ret = chdir(saved_wd);
818#endif
819 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
820 return (ret == 0);
821}
822
823void
824proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
825{
826 if (ws_pushd(dir))
827 {
828 func(param);
829 ws_popd();
830 }
831}
832
833static bool_Bool
834// NOLINTNEXTLINE(misc-no-recursion)
835proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
836 void *data)
837{
838 proto_node *pnode = tree;
839 proto_node *child;
840 proto_node *current;
841
842 if (func(pnode, data))
843 return true1;
844
845 child = pnode->first_child;
846 while (child != NULL((void*)0)) {
847 /*
848 * The routine we call might modify the child, e.g. by
849 * freeing it, so we get the child's successor before
850 * calling that routine.
851 */
852 current = child;
853 child = current->next;
854 // We recurse here, but we're limited by prefs.gui_max_tree_depth
855 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
856 return true1;
857 }
858
859 return false0;
860}
861
862void
863proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
864 void *data)
865{
866 proto_node *node = tree;
867 proto_node *current;
868
869 if (!node)
870 return;
871
872 node = node->first_child;
873 while (node != NULL((void*)0)) {
874 current = node;
875 node = current->next;
876 func((proto_tree *)current, data);
877 }
878}
879
880static void
881free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
882{
883 GPtrArray *ptrs = (GPtrArray *)value;
884 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
885 header_field_info *hfinfo;
886
887 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 887, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 887, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 887, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
888 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
889 /* when a field is referenced by a filter this also
890 affects the refcount for the parent protocol so we need
891 to adjust the refcount for the parent as well
892 */
893 if (hfinfo->parent != -1) {
894 header_field_info *parent_hfinfo;
895 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 895
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 895, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 895, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
896 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
897 }
898 hfinfo->ref_type = HF_REF_TYPE_NONE;
899 }
900
901 g_ptr_array_free(ptrs, true1);
902}
903
904static void
905proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
906{
907 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
908
909 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
910
911 if (finfo) {
912 // The fvalue_t structure was allocated using fvalue_new_pool()
913 // (see new_field_info()) and will be reclaimed when the pool is
914 // freed, so we only release the type-specific data it owns here.
915 fvalue_cleanup(finfo->value);
916 finfo->value = NULL((void*)0);
917 }
918}
919
920void
921proto_tree_reset(proto_tree *tree)
922{
923 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
924
925 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
926
927 /* free tree data */
928 if (tree_data->interesting_hfids) {
929 /* Free all the GPtrArray's in the interesting_hfids hash. */
930 g_hash_table_foreach(tree_data->interesting_hfids,
931 free_GPtrArray_value, NULL((void*)0));
932
933 /* And then remove all values. */
934 g_hash_table_remove_all(tree_data->interesting_hfids);
935 }
936
937 /* Reset track of the number of children */
938 tree_data->count = 0;
939
940 /* Reset our loop checks */
941 tree_data->idle_count_ds_tvb = NULL((void*)0);
942 tree_data->max_start = 0;
943 tree_data->start_idle_count = 0;
944
945 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
946}
947
948/* frees the resources that the dissection a proto_tree uses */
949void
950proto_tree_free(proto_tree *tree)
951{
952 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
953
954 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
955
956 /* free tree data */
957 if (tree_data->interesting_hfids) {
958 /* Free all the GPtrArray's in the interesting_hfids hash. */
959 g_hash_table_foreach(tree_data->interesting_hfids,
960 free_GPtrArray_value, NULL((void*)0));
961
962 /* And then destroy the hash. */
963 g_hash_table_destroy(tree_data->interesting_hfids);
964 }
965
966 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)
;
967
968 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
969}
970
971/* Is the parsing being done for a visible proto_tree or an invisible one?
972 * By setting this correctly, the proto_tree creation is sped up by not
973 * having to call vsnprintf and copy strings around.
974 */
975bool_Bool
976proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
977{
978 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
979
980 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
981
982 return old_visible;
983}
984
985void
986proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
987{
988 if (tree)
989 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
990}
991
992/* Assume dissector set only its protocol fields.
993 This function is called by dissectors and allows the speeding up of filtering
994 in wireshark; if this function returns false it is safe to reset tree to NULL
995 and thus skip calling most of the expensive proto_tree_add_...()
996 functions.
997 If the tree is visible we implicitly assume the field is referenced.
998*/
999bool_Bool
1000proto_field_is_referenced(proto_tree *tree, int proto_id)
1001{
1002 register header_field_info *hfinfo;
1003
1004
1005 if (!tree)
1006 return false0;
1007
1008 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1009 return true1;
1010
1011 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", 1011, __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", 1011,
"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", 1011, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1012 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1013 return true1;
1014
1015 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1016 return true1;
1017
1018 return false0;
1019}
1020
1021
1022/* Finds a record in the hfinfo array by id. */
1023header_field_info *
1024proto_registrar_get_nth(unsigned hfindex)
1025{
1026 register header_field_info *hfinfo;
1027
1028 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", 1028, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1028,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1028, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1029 return hfinfo;
1030}
1031
1032
1033/* Prefix initialization
1034 * this allows for a dissector to register a display filter name prefix
1035 * so that it can delay the initialization of the hf array as long as
1036 * possible.
1037 */
1038
1039/* compute a hash for the part before the dot of a display filter */
1040static unsigned
1041prefix_hash (const void *key) {
1042 /* end the string at the dot and compute its hash */
1043 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1044 char* c = copy;
1045 unsigned tmp;
1046
1047 for (; *c; c++) {
1048 if (*c == '.') {
1049 *c = 0;
1050 break;
1051 }
1052 }
1053
1054 tmp = wmem_str_hash(copy);
1055 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1056 return tmp;
1057}
1058
1059/* are both strings equal up to the end or the dot? */
1060static gboolean
1061prefix_equal (const void *ap, const void *bp) {
1062 const char* a = (const char *)ap;
1063 const char* b = (const char *)bp;
1064
1065 do {
1066 char ac = *a++;
1067 char bc = *b++;
1068
1069 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1070
1071 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1072 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1073
1074 if (ac != bc) return FALSE(0);
1075 } while (1);
1076
1077 return FALSE(0);
1078}
1079
1080/* Register a new prefix for "delayed" initialization of field arrays */
1081void
1082proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1083 if (! prefixes ) {
1084 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1085 }
1086
1087 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1088}
1089
1090/* helper to call all prefix initializers */
1091static gboolean
1092initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1093 ((prefix_initializer_t)v)((const char *)k);
1094 return TRUE(!(0));
1095}
1096
1097/** Initialize every remaining uninitialized prefix. */
1098void
1099proto_initialize_all_prefixes(void) {
1100 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1101}
1102
1103/* Finds a record in the hfinfo array by name.
1104 * If it fails to find it in the already registered fields,
1105 * it tries to find and call an initializer in the prefixes
1106 * table and if so it looks again.
1107 */
1108
1109header_field_info *
1110proto_registrar_get_byname(const char *field_name)
1111{
1112 header_field_info *hfinfo;
1113 prefix_initializer_t pi;
1114
1115 if (!field_name)
1116 return NULL((void*)0);
1117
1118 if (g_strcmp0(field_name, last_field_name) == 0) {
1119 return last_hfinfo;
1120 }
1121
1122 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1123
1124 if (hfinfo) {
1125 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1126 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1127 last_hfinfo = hfinfo;
1128 return hfinfo;
1129 }
1130
1131 if (!prefixes)
1132 return NULL((void*)0);
1133
1134 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1135 pi(field_name);
1136 g_hash_table_remove(prefixes, field_name);
1137 } else {
1138 return NULL((void*)0);
1139 }
1140
1141 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1142
1143 if (hfinfo) {
1144 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1145 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1146 last_hfinfo = hfinfo;
1147 }
1148 return hfinfo;
1149}
1150
1151header_field_info*
1152proto_registrar_get_byalias(const char *alias_name)
1153{
1154 if (!alias_name) {
1155 return NULL((void*)0);
1156 }
1157
1158 /* Find our aliased protocol. */
1159 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1160 char *dot = strchr(an_copy, '.');
1161 if (dot) {
1162 *dot = '\0';
1163 }
1164 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1165 if (!proto_pfx) {
1166 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1167 return NULL((void*)0);
1168 }
1169
1170 /* Construct our aliased field and look it up. */
1171 GString *filter_name = g_string_new(proto_pfx);
1172 if (dot) {
1173 g_string_append_printf(filter_name, ".%s", dot+1);
1174 }
1175 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1176 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1177 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)))))
;
1178
1179 return hfinfo;
1180}
1181
1182int
1183proto_registrar_get_id_byname(const char *field_name)
1184{
1185 header_field_info *hfinfo;
1186
1187 hfinfo = proto_registrar_get_byname(field_name);
1188
1189 if (!hfinfo)
1190 return -1;
1191
1192 return hfinfo->id;
1193}
1194
1195static int
1196label_strcat_flags(const header_field_info *hfinfo)
1197{
1198 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1199 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1200
1201 return 0;
1202}
1203
1204static char *
1205format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1206 const uint8_t *bytes, unsigned length, size_t max_str_len)
1207{
1208 char *str = NULL((void*)0);
1209 const uint8_t *p;
1210 bool_Bool is_printable;
1211
1212 if (bytes) {
1213 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1214 /*
1215 * If all bytes are valid and printable UTF-8, show the
1216 * bytes as a string - in quotes to indicate that it's
1217 * a string.
1218 */
1219 if (isprint_utf8_string((const char*)bytes, length)) {
1220 str = wmem_strdup_printf(scope, "\"%.*s\"",
1221 (int)length, bytes);
1222 return str;
1223 }
1224 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1225 /*
1226 * Check whether all bytes are printable.
1227 */
1228 is_printable = true1;
1229 for (p = bytes; p < bytes+length; p++) {
1230 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1231 /* Not printable. */
1232 is_printable = false0;
1233 break;
1234 }
1235 }
1236
1237 /*
1238 * If all bytes are printable ASCII, show the bytes
1239 * as a string - in quotes to indicate that it's
1240 * a string.
1241 */
1242 if (is_printable) {
1243 str = wmem_strdup_printf(scope, "\"%.*s\"",
1244 (int)length, bytes);
1245 return str;
1246 }
1247 }
1248
1249 /*
1250 * Either it's not printable ASCII, or we don't care whether
1251 * it's printable ASCII; show it as hex bytes.
1252 */
1253 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1254 case SEP_DOT:
1255 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1256 break;
1257 case SEP_DASH:
1258 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1259 break;
1260 case SEP_COLON:
1261 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1262 break;
1263 case SEP_SPACE:
1264 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1265 break;
1266 case BASE_NONE:
1267 default:
1268 if (prefs.display_byte_fields_with_spaces) {
1269 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1270 } else {
1271 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1272 }
1273 break;
1274 }
1275 }
1276 else {
1277 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1278 str = wmem_strdup(scope, "<none>");
1279 } else {
1280 str = wmem_strdup(scope, "<MISSING>");
1281 }
1282 }
1283 return str;
1284}
1285
1286static char *
1287format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1288 const uint8_t *bytes, unsigned length)
1289{
1290 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1291}
1292
1293static void
1294ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1295{
1296 subtree_lvl *pushed_tree;
1297
1298 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"
, 1298, "ptvc->pushed_tree_max <= 256-8"))))
;
1299 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1300
1301 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1302 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1302, "pushed_tree != ((void*)0)"
))))
;
1303 ptvc->pushed_tree = pushed_tree;
1304}
1305
1306static void
1307ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1308{
1309 ptvc->pushed_tree = NULL((void*)0);
1310 ptvc->pushed_tree_max = 0;
1311 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", 1311, "ptvc->pushed_tree_index == 0"
))))
;
1312 ptvc->pushed_tree_index = 0;
1313}
1314
1315/* Allocates an initializes a ptvcursor_t with 3 variables:
1316 * proto_tree, tvbuff, and offset. */
1317ptvcursor_t *
1318ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1319{
1320 ptvcursor_t *ptvc;
1321
1322 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1323 ptvc->scope = scope;
1324 ptvc->tree = tree;
1325 ptvc->tvb = tvb;
1326 ptvc->offset = offset;
1327 ptvc->pushed_tree = NULL((void*)0);
1328 ptvc->pushed_tree_max = 0;
1329 ptvc->pushed_tree_index = 0;
1330 return ptvc;
1331}
1332
1333
1334/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1335void
1336ptvcursor_free(ptvcursor_t *ptvc)
1337{
1338 ptvcursor_free_subtree_levels(ptvc);
1339 wmem_free(ptvc->scope, ptvc);
1340}
1341
1342/* Returns tvbuff. */
1343tvbuff_t *
1344ptvcursor_tvbuff(ptvcursor_t *ptvc)
1345{
1346 return ptvc->tvb;
1347}
1348
1349/* Returns current offset. */
1350unsigned
1351ptvcursor_current_offset(ptvcursor_t *ptvc)
1352{
1353 return ptvc->offset;
1354}
1355
1356proto_tree *
1357ptvcursor_tree(ptvcursor_t *ptvc)
1358{
1359 if (!ptvc)
1360 return NULL((void*)0);
1361
1362 return ptvc->tree;
1363}
1364
1365void
1366ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1367{
1368 ptvc->tree = tree;
1369}
1370
1371/* creates a subtree, sets it as the working tree and pushes the old working tree */
1372proto_tree *
1373ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1374{
1375 subtree_lvl *subtree;
1376 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1377 ptvcursor_new_subtree_levels(ptvc);
1378
1379 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1380 subtree->tree = ptvc->tree;
1381 subtree->it= NULL((void*)0);
1382 ptvc->pushed_tree_index++;
1383 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1384}
1385
1386/* pops a subtree */
1387void
1388ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1389{
1390 subtree_lvl *subtree;
1391
1392 if (ptvc->pushed_tree_index <= 0)
1393 return;
1394
1395 ptvc->pushed_tree_index--;
1396 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1397 if (subtree->it != NULL((void*)0))
1398 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1399
1400 ptvc->tree = subtree->tree;
1401}
1402
1403/* saves the current tvb offset and the item in the current subtree level */
1404static void
1405ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1406{
1407 subtree_lvl *subtree;
1408
1409 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", 1409, "ptvc->pushed_tree_index > 0"
))))
;
1410
1411 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1412 subtree->it = it;
1413 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1414}
1415
1416/* Creates a subtree and adds it to the cursor as the working tree but does not
1417 * save the old working tree */
1418proto_tree *
1419ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1420{
1421 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1422 return ptvc->tree;
1423}
1424
1425static proto_tree *
1426ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1427{
1428 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1429 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1430 ptvcursor_subtree_set_item(ptvc, it);
1431 return ptvcursor_tree(ptvc);
1432}
1433
1434/* Add an item to the tree and create a subtree
1435 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1436 * In this case, when the subtree will be closed, the parent item length will
1437 * be equal to the advancement of the cursor since the creation of the subtree.
1438 */
1439proto_tree *
1440ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1441 const unsigned encoding, int ett_subtree)
1442{
1443 proto_item *it;
1444
1445 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1446 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1447}
1448
1449static proto_item *
1450proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1451
1452/* Add a text node to the tree and create a subtree
1453 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1454 * In this case, when the subtree will be closed, the item length will be equal
1455 * to the advancement of the cursor since the creation of the subtree.
1456 */
1457proto_tree *
1458ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1459 int ett_subtree, const char *format, ...)
1460{
1461 proto_item *pi;
1462 va_list ap;
1463 header_field_info *hfinfo;
1464 proto_tree *tree;
1465
1466 tree = ptvcursor_tree(ptvc);
1467
1468 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1469
1470 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", 1470
, __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", 1470, "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", 1470, "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", 1470, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1471
1472 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1473 ptvcursor_current_offset(ptvc), length);
1474
1475 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1475, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1476
1477 va_start(ap, format)__builtin_va_start(ap, format);
1478 proto_tree_set_representation(pi, format, ap);
1479 va_end(ap)__builtin_va_end(ap);
1480
1481 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1482}
1483
1484/* Add a text-only node, leaving it to our caller to fill the text in */
1485static proto_item *
1486proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1487{
1488 proto_item *pi;
1489
1490 if (tree == NULL((void*)0))
1491 return NULL((void*)0);
1492
1493 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1494
1495 return pi;
1496}
1497
1498/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1499proto_item *
1500proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1501 const char *format, ...)
1502{
1503 proto_item *pi;
1504 va_list ap;
1505 header_field_info *hfinfo;
1506
1507 tvb_ensure_bytes_exist(tvb, start, length);
1508
1509 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1510
1511 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", 1511
, __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", 1511, "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", 1511, "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", 1511, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1512
1513 pi = proto_tree_add_text_node(tree, tvb, start, length);
1514
1515 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1515, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1516
1517 va_start(ap, format)__builtin_va_start(ap, format);
1518 proto_tree_set_representation(pi, format, ap);
1519 va_end(ap)__builtin_va_end(ap);
1520
1521 return pi;
1522}
1523
1524/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1525proto_item *
1526proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1527 unsigned length, const char *format, va_list ap)
1528{
1529 proto_item *pi;
1530 header_field_info *hfinfo;
1531
1532 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1533 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1534 * the length to be what's in the tvbuff if length is -1, and the
1535 * minimum of length and what's in the tvbuff if not.
1536 */
1537
1538 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1539
1540 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", 1540
, __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", 1540, "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", 1540, "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", 1540, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1541
1542 pi = proto_tree_add_text_node(tree, tvb, start, length);
1543
1544 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1544, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1545
1546 proto_tree_set_representation(pi, format, ap);
1547
1548 return pi;
1549}
1550
1551/* Add a text-only node that creates a subtree underneath.
1552 */
1553proto_tree *
1554proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1555{
1556 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1557}
1558
1559/* Add a text-only node that creates a subtree underneath.
1560 */
1561proto_tree *
1562proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1563{
1564 proto_tree *pt;
1565 proto_item *pi;
1566 va_list ap;
1567
1568 if (length == -1) {
1569 length = tvb_captured_length_remaining(tvb, start);
1570 }
1571
1572 va_start(ap, format)__builtin_va_start(ap, format);
1573 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1574 va_end(ap)__builtin_va_end(ap);
1575
1576 if (tree_item != NULL((void*)0))
1577 *tree_item = pi;
1578
1579 pt = proto_item_add_subtree(pi, idx);
1580
1581 return pt;
1582}
1583
1584/* Add a text-only node for debugging purposes. The caller doesn't need
1585 * to worry about tvbuff, start, or length. Debug message gets sent to
1586 * STDOUT, too */
1587proto_item *
1588proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1589{
1590 proto_item *pi;
1591 va_list ap;
1592
1593 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1594
1595 if (pi) {
1596 va_start(ap, format)__builtin_va_start(ap, format);
1597 proto_tree_set_representation(pi, format, ap);
1598 va_end(ap)__builtin_va_end(ap);
1599 }
1600 va_start(ap, format)__builtin_va_start(ap, format);
1601 vprintf(format, ap);
1602 va_end(ap)__builtin_va_end(ap);
1603 printf("\n");
1604
1605 return pi;
1606}
1607
1608proto_item *
1609proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1610{
1611 proto_item *pi;
1612 header_field_info *hfinfo;
1613
1614 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1615
1616 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", 1616
, __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", 1616, "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", 1616, "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", 1616, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1617
1618 pi = proto_tree_add_text_node(tree, tvb, start, length);
1619
1620 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1620, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1621
1622 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1623
1624 return pi;
1625}
1626
1627proto_item *
1628proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1629{
1630 proto_item *pi;
1631 header_field_info *hfinfo;
1632 char *str;
1633
1634 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1635
1636 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", 1636
, __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", 1636, "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", 1636, "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", 1636, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1637
1638 pi = proto_tree_add_text_node(tree, tvb, start, length);
1639
1640 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1640, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1641
1642 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1643 proto_item_set_text(pi, "%s", str);
1644 wmem_free(NULL((void*)0), str);
1645
1646 return pi;
1647}
1648
1649void proto_report_dissector_bug(const char *format, ...)
1650{
1651 va_list args;
1652
1653 if (wireshark_abort_on_dissector_bug) {
1654 /*
1655 * Try to have the error message show up in the crash
1656 * information.
1657 */
1658 va_start(args, format)__builtin_va_start(args, format);
1659 ws_vadd_crash_info(format, args);
1660 va_end(args)__builtin_va_end(args);
1661
1662 /*
1663 * Print the error message.
1664 */
1665 va_start(args, format)__builtin_va_start(args, format);
1666 vfprintf(stderrstderr, format, args);
1667 va_end(args)__builtin_va_end(args);
1668 putc('\n', stderrstderr);
1669
1670 /*
1671 * And crash.
1672 */
1673 abort();
1674 } else {
1675 va_start(args, format)__builtin_va_start(args, format);
1676 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1677 va_end(args)__builtin_va_end(args);
1678 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1678
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1679 }
1680}
1681
1682/* We could probably get away with changing is_error to a minimum length value. */
1683static void
1684report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1685{
1686 if (is_error) {
1687 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1688 } else {
1689 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1690 }
1691
1692 if (is_error) {
1693 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1694 }
1695}
1696
1697static uint32_t
1698get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1699{
1700 uint32_t value;
1701 bool_Bool length_error;
1702
1703 switch (length) {
1704
1705 case 1:
1706 value = tvb_get_uint8(tvb, offset);
1707 if (encoding & ENC_ZIGBEE0x40000000) {
1708 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1709 value = 0;
1710 }
1711 }
1712 break;
1713
1714 case 2:
1715 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1716 : tvb_get_ntohs(tvb, offset);
1717 if (encoding & ENC_ZIGBEE0x40000000) {
1718 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1719 value = 0;
1720 }
1721 }
1722 break;
1723
1724 case 3:
1725 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1726 : tvb_get_ntoh24(tvb, offset);
1727 break;
1728
1729 case 4:
1730 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1731 : tvb_get_ntohl(tvb, offset);
1732 break;
1733
1734 default:
1735 if (length < 1) {
1736 length_error = true1;
1737 value = 0;
1738 } else {
1739 length_error = false0;
1740 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1741 : tvb_get_ntohl(tvb, offset);
1742 }
1743 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1744 break;
1745 }
1746 return value;
1747}
1748
1749static inline uint64_t
1750get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1751{
1752 uint64_t value;
1753
1754 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1755
1756 if (length < 1 || length > 8) {
1757 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1758 }
1759
1760 return value;
1761}
1762
1763static int32_t
1764get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1765{
1766 int32_t value;
1767 bool_Bool length_error;
1768
1769 switch (length) {
1770
1771 case 1:
1772 value = tvb_get_int8(tvb, offset);
1773 break;
1774
1775 case 2:
1776 value = encoding ? tvb_get_letohis(tvb, offset)
1777 : tvb_get_ntohis(tvb, offset);
1778 break;
1779
1780 case 3:
1781 value = encoding ? tvb_get_letohi24(tvb, offset)
1782 : tvb_get_ntohi24(tvb, offset);
1783 break;
1784
1785 case 4:
1786 value = encoding ? tvb_get_letohil(tvb, offset)
1787 : tvb_get_ntohil(tvb, offset);
1788 break;
1789
1790 default:
1791 if (length < 1) {
1792 length_error = true1;
1793 value = 0;
1794 } else {
1795 length_error = false0;
1796 value = encoding ? tvb_get_letohil(tvb, offset)
1797 : tvb_get_ntohil(tvb, offset);
1798 }
1799 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1800 break;
1801 }
1802 return value;
1803}
1804
1805/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1806 * be cast-able as a int64_t. This is weird, but what the code has always done.
1807 */
1808static inline uint64_t
1809get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1810{
1811 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1812
1813 switch (length) {
1814 case 7:
1815 value = ws_sign_ext64(value, 56);
1816 break;
1817 case 6:
1818 value = ws_sign_ext64(value, 48);
1819 break;
1820 case 5:
1821 value = ws_sign_ext64(value, 40);
1822 break;
1823 case 4:
1824 value = ws_sign_ext64(value, 32);
1825 break;
1826 case 3:
1827 value = ws_sign_ext64(value, 24);
1828 break;
1829 case 2:
1830 value = ws_sign_ext64(value, 16);
1831 break;
1832 case 1:
1833 value = ws_sign_ext64(value, 8);
1834 break;
1835 }
1836
1837 return value;
1838}
1839
1840/* For FT_STRING */
1841static inline const uint8_t *
1842get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1843 int length, unsigned *ret_length, const unsigned encoding)
1844{
1845 if (length == -1) {
1846 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1847 } else {
1848 *ret_length = length;
1849 }
1850 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1851}
1852
1853/* For FT_STRINGZ */
1854static inline const uint8_t *
1855get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1856 unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1857{
1858 const uint8_t *value;
1859
1860 if (length < -1) {
1861 report_type_length_mismatch(tree, "a string", length, true1);
1862 }
1863
1864 /* XXX - Ideally, every "null-terminated string which fits into a
1865 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1866 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1867 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1868 * as unknown length as well (since there is a trailing '\0', the real
1869 * length is never zero), allowing switching to unsigned lengths.
1870 */
1871 if (length == -1) {
1872 /* This can throw an exception */
1873 value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1874 } else {
1875 /* In this case, length signifies the length of the string.
1876 *
1877 * This could either be a null-padded string, which doesn't
1878 * necessarily have a '\0' at the end, or a null-terminated
1879 * string, with a trailing '\0'. (Yes, there are cases
1880 * where you have a string that's both counted and null-
1881 * terminated.)
1882 *
1883 * In the first case, we must allocate a buffer of length
1884 * "length+1", to make room for a trailing '\0'.
1885 *
1886 * In the second case, we don't assume that there is a
1887 * trailing '\0' there, as the packet might be malformed.
1888 * (XXX - should we throw an exception if there's no
1889 * trailing '\0'?) Therefore, we allocate a buffer of
1890 * length "length+1", and put in a trailing '\0', just to
1891 * be safe.
1892 *
1893 * (XXX - this would change if we made string values counted
1894 * rather than null-terminated.)
1895 */
1896 *ret_length = length;
1897 value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1898 }
1899 return value;
1900}
1901
1902/* For FT_UINT_STRING */
1903static inline const uint8_t *
1904get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1905 tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1906 const unsigned encoding)
1907{
1908 uint32_t n;
1909 const uint8_t *value;
1910
1911 /* I believe it's ok if this is called with a NULL tree */
1912 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1913 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1914 *ret_length = length + n;
1915 return value;
1916}
1917
1918/* For FT_STRINGZPAD */
1919static inline const uint8_t *
1920get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1921 int length, unsigned *ret_length, const unsigned encoding)
1922{
1923 /*
1924 * XXX - currently, string values are null-
1925 * terminated, so a "zero-padded" string
1926 * isn't special. If we represent string
1927 * values as something that includes a counted
1928 * array of bytes, we'll need to strip the
1929 * trailing NULs.
1930 */
1931 if (length == -1) {
1932 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1933 } else {
1934 *ret_length = length;
1935 }
1936 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1937}
1938
1939/* For FT_STRINGZTRUNC */
1940static inline const uint8_t *
1941get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1942 int length, unsigned *ret_length, const unsigned encoding)
1943{
1944 /*
1945 * XXX - currently, string values are null-
1946 * terminated, so a "zero-truncated" string
1947 * isn't special. If we represent string
1948 * values as something that includes a counted
1949 * array of bytes, we'll need to strip everything
1950 * starting with the terminating NUL.
1951 */
1952 if (length == -1) {
1953 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1954 } else {
1955 *ret_length = length;
1956 }
1957 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1958}
1959
1960/*
1961 * Deltas between the epochs for various non-UN*X time stamp formats and
1962 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1963 * stamp format.
1964 */
1965
1966/*
1967 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1968 * XXX - if it's OK if this is unsigned, can we just use
1969 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1970 */
1971#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1972
1973/*
1974 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1975 */
1976#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1977
1978/* this can be called when there is no tree, so tree may be null */
1979static void
1980get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1981 const int length, const unsigned encoding, nstime_t *time_stamp,
1982 const bool_Bool is_relative)
1983{
1984 uint32_t tmpsecs;
1985 uint64_t tmp64secs;
1986 uint64_t todusecs;
1987
1988 switch (encoding) {
1989
1990 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1991 /*
1992 * If the length is 16, 8-byte seconds, followed
1993 * by 8-byte fractional time in nanoseconds,
1994 * both big-endian.
1995 *
1996 * If the length is 12, 8-byte seconds, followed
1997 * by 4-byte fractional time in nanoseconds,
1998 * both big-endian.
1999 *
2000 * If the length is 8, 4-byte seconds, followed
2001 * by 4-byte fractional time in nanoseconds,
2002 * both big-endian.
2003 *
2004 * For absolute times, the seconds are seconds
2005 * since the UN*X epoch.
2006 */
2007 if (length == 16) {
2008 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2009 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2010 } else if (length == 12) {
2011 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2012 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2013 } else if (length == 8) {
2014 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2015 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2016 } else if (length == 4) {
2017 /*
2018 * Backwards compatibility.
2019 * ENC_TIME_SECS_NSECS is 0; using
2020 * ENC_BIG_ENDIAN by itself with a 4-byte
2021 * time-in-seconds value was done in the
2022 * past.
2023 */
2024 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2025 time_stamp->nsecs = 0;
2026 } else {
2027 time_stamp->secs = 0;
2028 time_stamp->nsecs = 0;
2029 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2030 }
2031 break;
2032
2033 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2034 /*
2035 * If the length is 16, 8-byte seconds, followed
2036 * by 8-byte fractional time in nanoseconds,
2037 * both little-endian.
2038 *
2039 * If the length is 12, 8-byte seconds, followed
2040 * by 4-byte fractional time in nanoseconds,
2041 * both little-endian.
2042 *
2043 * If the length is 8, 4-byte seconds, followed
2044 * by 4-byte fractional time in nanoseconds,
2045 * both little-endian.
2046 *
2047 * For absolute times, the seconds are seconds
2048 * since the UN*X epoch.
2049 */
2050 if (length == 16) {
2051 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2052 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2053 } else if (length == 12) {
2054 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2055 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2056 } else if (length == 8) {
2057 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2058 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2059 } else if (length == 4) {
2060 /*
2061 * Backwards compatibility.
2062 * ENC_TIME_SECS_NSECS is 0; using
2063 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2064 * time-in-seconds value was done in the
2065 * past.
2066 */
2067 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2068 time_stamp->nsecs = 0;
2069 } else {
2070 time_stamp->secs = 0;
2071 time_stamp->nsecs = 0;
2072 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2073 }
2074 break;
2075
2076 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2077 /*
2078 * NTP time stamp, big-endian.
2079 * Only supported for absolute times.
2080 */
2081 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2081, "!is_relative"
))))
;
2082
2083 /* We need a temporary variable here so the unsigned math
2084 * works correctly (for years > 2036 according to RFC 2030
2085 * chapter 3).
2086 *
2087 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2088 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2089 * If bit 0 is not set, the time is in the range 2036-2104 and
2090 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2091 */
2092 tmpsecs = tvb_get_ntohl(tvb, start);
2093 if ((tmpsecs & 0x80000000) != 0)
2094 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2095 else
2096 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2097
2098 if (length == 8) {
2099 tmp64secs = tvb_get_ntoh64(tvb, start);
2100 if (tmp64secs == 0) {
2101 //This is "NULL" time
2102 time_stamp->secs = 0;
2103 time_stamp->nsecs = 0;
2104 } else {
2105 /*
2106 * Convert 1/2^32s of a second to
2107 * nanoseconds.
2108 */
2109 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2110 }
2111 } else if (length == 4) {
2112 /*
2113 * Backwards compatibility.
2114 */
2115 if (tmpsecs == 0) {
2116 //This is "NULL" time
2117 time_stamp->secs = 0;
2118 }
2119 time_stamp->nsecs = 0;
2120 } else {
2121 time_stamp->secs = 0;
2122 time_stamp->nsecs = 0;
2123 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2124 }
2125 break;
2126
2127 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2128 /*
2129 * NTP time stamp, little-endian.
2130 * Only supported for absolute times.
2131 *
2132 * NTP doesn't use this, because it's an Internet format
2133 * and hence big-endian. Any implementation must decide
2134 * whether the NTP timestamp is a 64-bit unsigned fixed
2135 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2136 * with a 32-bit unsigned seconds field followed by a
2137 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2138 * the previous two).
2139 *
2140 * XXX: We do the latter, but no dissector uses this format.
2141 * OTOH, ERF timestamps do the former, so perhaps we
2142 * should switch the interpretation so that packet-erf.c
2143 * could use this directly?
2144 */
2145 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2145, "!is_relative"
))))
;
2146
2147 /* We need a temporary variable here so the unsigned math
2148 * works correctly (for years > 2036 according to RFC 2030
2149 * chapter 3).
2150 *
2151 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2152 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2153 * If bit 0 is not set, the time is in the range 2036-2104 and
2154 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2155 */
2156 tmpsecs = tvb_get_letohl(tvb, start);
2157 if ((tmpsecs & 0x80000000) != 0)
2158 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2159 else
2160 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2161
2162 if (length == 8) {
2163 tmp64secs = tvb_get_letoh64(tvb, start);
2164 if (tmp64secs == 0) {
2165 //This is "NULL" time
2166 time_stamp->secs = 0;
2167 time_stamp->nsecs = 0;
2168 } else {
2169 /*
2170 * Convert 1/2^32s of a second to
2171 * nanoseconds.
2172 */
2173 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2174 }
2175 } else if (length == 4) {
2176 /*
2177 * Backwards compatibility.
2178 */
2179 if (tmpsecs == 0) {
2180 //This is "NULL" time
2181 time_stamp->secs = 0;
2182 }
2183 time_stamp->nsecs = 0;
2184 } else {
2185 time_stamp->secs = 0;
2186 time_stamp->nsecs = 0;
2187 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2188 }
2189 break;
2190
2191 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2192 /*
2193 * S/3x0 and z/Architecture TOD clock time stamp,
2194 * big-endian. The epoch is January 1, 1900,
2195 * 00:00:00 (proleptic?) UTC.
2196 *
2197 * Only supported for absolute times.
2198 */
2199 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2199, "!is_relative"
))))
;
2200 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2200, "length == 8"
))))
;
2201
2202 if (length == 8) {
2203 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2204 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2205 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2206 } else {
2207 time_stamp->secs = 0;
2208 time_stamp->nsecs = 0;
2209 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2210 }
2211 break;
2212
2213 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2214 /*
2215 * S/3x0 and z/Architecture TOD clock time stamp,
2216 * little-endian. The epoch is January 1, 1900,
2217 * 00:00:00 (proleptic?) UTC.
2218 *
2219 * Only supported for absolute times.
2220 */
2221 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2221, "!is_relative"
))))
;
2222
2223 if (length == 8) {
2224 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2225 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2226 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2227 } else {
2228 time_stamp->secs = 0;
2229 time_stamp->nsecs = 0;
2230 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2231 }
2232 break;
2233
2234 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2235 /*
2236 * Time stamp using the same seconds/fraction format
2237 * as NTP, but with the origin of the time stamp being
2238 * the UNIX epoch rather than the NTP epoch; big-
2239 * endian.
2240 *
2241 * Only supported for absolute times.
2242 */
2243 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2243, "!is_relative"
))))
;
2244
2245 if (length == 8) {
2246 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2247 /*
2248 * Convert 1/2^32s of a second to nanoseconds.
2249 */
2250 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2251 } else {
2252 time_stamp->secs = 0;
2253 time_stamp->nsecs = 0;
2254 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2255 }
2256 break;
2257
2258 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2259 /*
2260 * Time stamp using the same seconds/fraction format
2261 * as NTP, but with the origin of the time stamp being
2262 * the UNIX epoch rather than the NTP epoch; little-
2263 * endian.
2264 *
2265 * Only supported for absolute times.
2266 *
2267 * The RTPS specification explicitly supports Little
2268 * Endian encoding. In one place, it states that its
2269 * Time_t representation "is the one defined by ...
2270 * RFC 1305", but in another explicitly defines it as
2271 * a struct consisting of an 32 bit unsigned seconds
2272 * field and a 32 bit unsigned fraction field, not a 64
2273 * bit fixed point, so we do that here.
2274 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2275 */
2276 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2276, "!is_relative"
))))
;
2277
2278 if (length == 8) {
2279 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2280 /*
2281 * Convert 1/2^32s of a second to nanoseconds.
2282 */
2283 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2284 } else {
2285 time_stamp->secs = 0;
2286 time_stamp->nsecs = 0;
2287 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2288 }
2289 break;
2290
2291 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2292 /*
2293 * MIP6 time stamp, big-endian.
2294 * A 64-bit unsigned integer field containing a timestamp. The
2295 * value indicates the number of seconds since January 1, 1970,
2296 * 00:00 UTC, by using a fixed point format. In this format, the
2297 * integer number of seconds is contained in the first 48 bits of
2298 * the field, and the remaining 16 bits indicate the number of
2299 * 1/65536 fractions of a second.
2300
2301 * Only supported for absolute times.
2302 */
2303 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2303, "!is_relative"
))))
;
2304
2305 if (length == 8) {
2306 /* We need a temporary variable here so the casting and fractions
2307 * of a second work correctly.
2308 */
2309 tmp64secs = tvb_get_ntoh48(tvb, start);
2310 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2311 tmpsecs <<= 16;
2312
2313 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2314 //This is "NULL" time
2315 time_stamp->secs = 0;
2316 time_stamp->nsecs = 0;
2317 } else {
2318 time_stamp->secs = (time_t)tmp64secs;
2319 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2320 }
2321 } else {
2322 time_stamp->secs = 0;
2323 time_stamp->nsecs = 0;
2324 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2325 }
2326 break;
2327
2328 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2329 /*
2330 * If the length is 16, 8-byte seconds, followed
2331 * by 8-byte fractional time in microseconds,
2332 * both big-endian.
2333 *
2334 * If the length is 12, 8-byte seconds, followed
2335 * by 4-byte fractional time in microseconds,
2336 * both big-endian.
2337 *
2338 * If the length is 8, 4-byte seconds, followed
2339 * by 4-byte fractional time in microseconds,
2340 * both big-endian.
2341 *
2342 * For absolute times, the seconds are seconds
2343 * since the UN*X epoch.
2344 */
2345 if (length == 16) {
2346 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2347 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2348 } else if (length == 12) {
2349 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2350 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2351 } else if (length == 8) {
2352 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2353 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2354 } else {
2355 time_stamp->secs = 0;
2356 time_stamp->nsecs = 0;
2357 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2358 }
2359 break;
2360
2361 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2362 /*
2363 * If the length is 16, 8-byte seconds, followed
2364 * by 8-byte fractional time in microseconds,
2365 * both little-endian.
2366 *
2367 * If the length is 12, 8-byte seconds, followed
2368 * by 4-byte fractional time in microseconds,
2369 * both little-endian.
2370 *
2371 * If the length is 8, 4-byte seconds, followed
2372 * by 4-byte fractional time in microseconds,
2373 * both little-endian.
2374 *
2375 * For absolute times, the seconds are seconds
2376 * since the UN*X epoch.
2377 */
2378 if (length == 16) {
2379 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2380 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2381 } else if (length == 12) {
2382 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2383 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2384 } else if (length == 8) {
2385 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2386 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2387 } else {
2388 time_stamp->secs = 0;
2389 time_stamp->nsecs = 0;
2390 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2391 }
2392 break;
2393
2394 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2395 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2396 /*
2397 * Seconds, 1 to 8 bytes.
2398 * For absolute times, it's seconds since the
2399 * UN*X epoch.
2400 */
2401 if (length >= 1 && length <= 8) {
2402 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2403 time_stamp->nsecs = 0;
2404 } else {
2405 time_stamp->secs = 0;
2406 time_stamp->nsecs = 0;
2407 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2408 }
2409 break;
2410
2411 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2412 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2413 /*
2414 * Milliseconds, 1 to 8 bytes.
2415 * For absolute times, it's milliseconds since the
2416 * UN*X epoch.
2417 */
2418 if (length >= 1 && length <= 8) {
2419 uint64_t msecs;
2420
2421 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2422 time_stamp->secs = (time_t)(msecs / 1000);
2423 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2424 } else {
2425 time_stamp->secs = 0;
2426 time_stamp->nsecs = 0;
2427 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2428 }
2429 break;
2430
2431 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2432 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2433 /*
2434 * Microseconds, 1 to 8 bytes.
2435 * For absolute times, it's microseconds since the
2436 * UN*X epoch.
2437 */
2438 if (length >= 1 && length <= 8) {
2439 uint64_t usecs;
2440
2441 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2442 time_stamp->secs = (time_t)(usecs / 1000000);
2443 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2444 } else {
2445 time_stamp->secs = 0;
2446 time_stamp->nsecs = 0;
2447 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2448 }
2449 break;
2450
2451 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2452 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2453 /*
2454 * nanoseconds, 1 to 8 bytes.
2455 * For absolute times, it's nanoseconds since the
2456 * UN*X epoch.
2457 */
2458
2459 if (length >= 1 && length <= 8) {
2460 uint64_t nsecs;
2461
2462 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2463 time_stamp->secs = (time_t)(nsecs / 1000000000);
2464 time_stamp->nsecs = (int)(nsecs % 1000000000);
2465 } else {
2466 time_stamp->secs = 0;
2467 time_stamp->nsecs = 0;
2468 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2469 }
2470 break;
2471
2472 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2473 /*
2474 * 1/64ths of a second since the UN*X epoch,
2475 * big-endian.
2476 *
2477 * Only supported for absolute times.
2478 */
2479 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2479, "!is_relative"
))))
;
2480
2481 if (length == 8) {
2482 /*
2483 * The upper 48 bits are seconds since the
2484 * UN*X epoch.
2485 */
2486 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2487 /*
2488 * The lower 16 bits are 1/2^16s of a second;
2489 * convert them to nanoseconds.
2490 *
2491 * XXX - this may give the impression of higher
2492 * precision than you actually get.
2493 */
2494 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2495 } else {
2496 time_stamp->secs = 0;
2497 time_stamp->nsecs = 0;
2498 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2499 }
2500 break;
2501
2502 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2503 /*
2504 * 1/64ths of a second since the UN*X epoch,
2505 * little-endian.
2506 *
2507 * Only supported for absolute times.
2508 */
2509 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2509, "!is_relative"
))))
;
2510
2511 if (length == 8) {
2512 /*
2513 * XXX - this is assuming that, if anybody
2514 * were ever to use this format - RFC 3971
2515 * doesn't, because that's an Internet
2516 * protocol, and those use network byte
2517 * order, i.e. big-endian - they'd treat it
2518 * as a 64-bit count of 1/2^16s of a second,
2519 * putting the upper 48 bits at the end.
2520 *
2521 * The lower 48 bits are seconds since the
2522 * UN*X epoch.
2523 */
2524 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2525 /*
2526 * The upper 16 bits are 1/2^16s of a second;
2527 * convert them to nanoseconds.
2528 *
2529 * XXX - this may give the impression of higher
2530 * precision than you actually get.
2531 */
2532 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2533 } else {
2534 time_stamp->secs = 0;
2535 time_stamp->nsecs = 0;
2536 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2537 }
2538 break;
2539
2540 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2541 /*
2542 * NTP time stamp, with 1-second resolution (i.e.,
2543 * seconds since the NTP epoch), big-endian.
2544 * Only supported for absolute times.
2545 */
2546 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2546, "!is_relative"
))))
;
2547
2548 if (length == 4) {
2549 /*
2550 * We need a temporary variable here so the unsigned math
2551 * works correctly (for years > 2036 according to RFC 2030
2552 * chapter 3).
2553 *
2554 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2555 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2556 * If bit 0 is not set, the time is in the range 2036-2104 and
2557 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2558 */
2559 tmpsecs = tvb_get_ntohl(tvb, start);
2560 if ((tmpsecs & 0x80000000) != 0)
2561 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2562 else
2563 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2564 time_stamp->nsecs = 0;
2565 } else {
2566 time_stamp->secs = 0;
2567 time_stamp->nsecs = 0;
2568 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2569 }
2570 break;
2571
2572 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2573 /*
2574 * NTP time stamp, with 1-second resolution (i.e.,
2575 * seconds since the NTP epoch), little-endian.
2576 * Only supported for absolute times.
2577 */
2578 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2578, "!is_relative"
))))
;
2579
2580 /*
2581 * We need a temporary variable here so the unsigned math
2582 * works correctly (for years > 2036 according to RFC 2030
2583 * chapter 3).
2584 *
2585 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2586 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2587 * If bit 0 is not set, the time is in the range 2036-2104 and
2588 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2589 */
2590 if (length == 4) {
2591 tmpsecs = tvb_get_letohl(tvb, start);
2592 if ((tmpsecs & 0x80000000) != 0)
2593 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2594 else
2595 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2596 time_stamp->nsecs = 0;
2597 } else {
2598 time_stamp->secs = 0;
2599 time_stamp->nsecs = 0;
2600 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2601 }
2602 break;
2603
2604 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2605 /*
2606 * Milliseconds, 6 to 8 bytes.
2607 * For absolute times, it's milliseconds since the
2608 * NTP epoch.
2609 *
2610 * ETSI TS 129.274 8.119 defines this as:
2611 * "a 48 bit unsigned integer in network order format
2612 * ...encoded as the number of milliseconds since
2613 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2614 * rounded value of 1000 x the value of the 64-bit
2615 * timestamp (Seconds + (Fraction / (1<<32))) defined
2616 * in clause 6 of IETF RFC 5905."
2617 *
2618 * Taken literally, the part after "i.e." would
2619 * mean that the value rolls over before reaching
2620 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2621 * when the 64 bit timestamp rolls over, and we have
2622 * to pick an NTP Era equivalence class to support
2623 * (such as 1968-01-20 to 2104-02-06).
2624 *
2625 * OTOH, the extra room might be used to store Era
2626 * information instead, in which case times until
2627 * 10819-08-03 can be represented with 6 bytes without
2628 * ambiguity. We handle both implementations, and assume
2629 * that times before 1968-01-20 are not represented.
2630 *
2631 * Only 6 bytes or more makes sense as an absolute
2632 * time. 5 bytes or fewer could express a span of
2633 * less than 35 years, either 1900-1934 or 2036-2070.
2634 */
2635 if (length >= 6 && length <= 8) {
2636 uint64_t msecs;
2637
2638 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2639 tmp64secs = (msecs / 1000);
2640 /*
2641 * Assume that times in the first half of NTP
2642 * Era 0 really represent times in the NTP
2643 * Era 1.
2644 */
2645 if (tmp64secs >= 0x80000000)
2646 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2647 else
2648 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2649 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2650 }
2651 else {
2652 time_stamp->secs = 0;
2653 time_stamp->nsecs = 0;
2654 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2655 }
2656 break;
2657
2658 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2659 /*
2660 * MP4 file time stamps, big-endian.
2661 * Only supported for absolute times.
2662 */
2663 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2663, "!is_relative"
))))
;
2664
2665 if (length == 8) {
2666 tmp64secs = tvb_get_ntoh64(tvb, start);
2667 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2668 time_stamp->nsecs = 0;
2669 } else if (length == 4) {
2670 tmpsecs = tvb_get_ntohl(tvb, start);
2671 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2672 time_stamp->nsecs = 0;
2673 } else {
2674 time_stamp->secs = 0;
2675 time_stamp->nsecs = 0;
2676 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2677 }
2678 break;
2679
2680 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2681 /*
2682 * Zigbee ZCL time stamps, big-endian.
2683 * Only supported for absolute times.
2684 */
2685 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2685, "!is_relative"
))))
;
2686
2687 if (length == 8) {
2688 tmp64secs = tvb_get_ntoh64(tvb, start);
2689 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2690 /* There are several other possible choices for what to do
2691 * with overflow; make sure to coordinate with whatever
2692 * packet-zbee-zcl.h does. */
2693 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2694 }
2695 time_stamp->nsecs = 0;
2696 } else if (length == 4) {
2697 tmpsecs = tvb_get_ntohl(tvb, start);
2698 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2699 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2700 }
2701 time_stamp->nsecs = 0;
2702 } else {
2703 time_stamp->secs = 0;
2704 time_stamp->nsecs = 0;
2705 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2706 }
2707 break;
2708
2709 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2710 /*
2711 * Zigbee ZCL time stamps, little-endian.
2712 * Only supported for absolute times.
2713 */
2714 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2714, "!is_relative"
))))
;
2715
2716 if (length == 8) {
2717 tmp64secs = tvb_get_letoh64(tvb, start);
2718 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2719 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2720 }
2721 time_stamp->nsecs = 0;
2722 } else if (length == 4) {
2723 tmpsecs = tvb_get_letohl(tvb, start);
2724 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2725 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2726 }
2727 time_stamp->nsecs = 0;
2728 } else {
2729 time_stamp->secs = 0;
2730 time_stamp->nsecs = 0;
2731 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2732 }
2733 break;
2734
2735 default:
2736 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2736))
;
2737 break;
2738 }
2739}
2740
2741static void
2742tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2743{
2744 const header_field_info *hfinfo = fi->hfinfo;
2745
2746 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2747 GPtrArray *ptrs = NULL((void*)0);
2748
2749 if (tree_data->interesting_hfids == NULL((void*)0)) {
2750 /* Initialize the hash because we now know that it is needed */
2751 tree_data->interesting_hfids =
2752 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2753 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2754 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2755 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2756 }
2757
2758 if (!ptrs) {
2759 /* First element triggers the creation of pointer array */
2760 ptrs = g_ptr_array_new();
2761 g_hash_table_insert(tree_data->interesting_hfids,
2762 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2763 }
2764
2765 g_ptr_array_add(ptrs, fi);
2766 }
2767}
2768
2769
2770/*
2771 * Validates that field length bytes are available starting from
2772 * start (pos/neg). Throws an exception if they aren't.
2773 */
2774static void
2775test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2776 unsigned start, int length, const unsigned encoding)
2777{
2778 int size = length;
2779
2780 if (!tvb)
2781 return;
2782
2783 if ((hfinfo->type == FT_STRINGZ) ||
2784 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2785 (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
))
))) {
2786 /* If we're fetching until the end of the TVB, only validate
2787 * that the offset is within range.
2788 */
2789 if (length == -1)
2790 size = 0;
2791 }
2792
2793 tvb_ensure_bytes_exist(tvb, start, size);
2794}
2795
2796static void
2797detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2798{
2799 bool_Bool found_stray_character = false0;
2800
2801 if (!string)
2802 return;
2803
2804 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2805 case ENC_ASCII0x00000000:
2806 case ENC_UTF_80x00000002:
2807 for (int i = (int)strlen(string); i < length; i++) {
2808 if (string[i] != '\0') {
2809 found_stray_character = true1;
2810 break;
2811 }
2812 }
2813 break;
2814
2815 default:
2816 break;
2817 }
2818
2819 if (found_stray_character) {
2820 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2821 }
2822}
2823
2824/* Add an item to a proto_tree, using the text label registered to that item;
2825 the item is extracted from the tvbuff handed to it. */
2826static proto_item *
2827proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2828 tvbuff_t *tvb, unsigned start, int length,
2829 unsigned encoding)
2830{
2831 proto_item *pi;
2832 uint32_t value, n;
2833 uint64_t value64;
2834 ws_in4_addr ipv4_value;
2835 float floatval;
2836 double doubleval;
2837 const char *stringval = NULL((void*)0);
2838 nstime_t time_stamp;
2839 bool_Bool length_error;
2840 unsigned item_length;
2841
2842 // new_fi->value is allocated from the packet-scoped pool (see
2843 // new_field_info()), so if a tvbuff accessor below throws before the
2844 // node is added to the tree the fvalue_t structure is still reclaimed
2845 // when the pool is freed; no explicit cleanup handler is needed. This
2846 // relies on the invariant that the type-specific data an fvalue owns
2847 // (byte arrays, string buffers, ...) is only allocated *after* the
2848 // throwing tvbuff read that produced it succeeds, so nothing that would
2849 // need fvalue_cleanup() is ever leaked on the exception path.
2850 switch (new_fi->hfinfo->type) {
2851 case FT_NONE:
2852 /* no value to set for FT_NONE */
2853 break;
2854
2855 case FT_PROTOCOL:
2856 /* Set the protocol_tvb via the start offset, but include
2857 * rest of the ds_tvb so that if finfo_set_len is called
2858 * later it can be lengthened as much as possible. */
2859 proto_tree_set_protocol_tvb(new_fi, new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0), new_fi->hfinfo->name, length);
2860 break;
2861
2862 case FT_BYTES:
2863 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2864 break;
2865
2866 case FT_UINT_BYTES:
2867 n = get_uint_value(tree, tvb, start, length, encoding);
2868 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2869
2870 /* Instead of calling proto_item_set_len(), since we don't yet
2871 * have a proto_item, we set the field_info's length ourselves. */
2872 new_fi->length = n + length;
2873 break;
2874
2875 case FT_BOOLEAN:
2876 /*
2877 * Map all non-zero values to little-endian for
2878 * backwards compatibility.
2879 */
2880 if (encoding)
2881 encoding = ENC_LITTLE_ENDIAN0x80000000;
2882 proto_tree_set_boolean(new_fi,
2883 get_uint64_value(tree, tvb, start, length, encoding));
2884 break;
2885
2886 case FT_CHAR:
2887 /* XXX - make these just FT_UINT? */
2888 case FT_UINT8:
2889 case FT_UINT16:
2890 case FT_UINT24:
2891 case FT_UINT32:
2892 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2893 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2894 value = (uint32_t)value64;
2895 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2896 new_fi->flags |= FI_VARINT0x00040000;
2897 }
2898 }
2899 else {
2900 /*
2901 * Map all non-zero values to little-endian for
2902 * backwards compatibility.
2903 */
2904 if (encoding)
2905 encoding = ENC_LITTLE_ENDIAN0x80000000;
2906
2907 value = get_uint_value(tree, tvb, start, length, encoding);
2908 }
2909 proto_tree_set_uint(new_fi, value);
2910 break;
2911
2912 case FT_UINT40:
2913 case FT_UINT48:
2914 case FT_UINT56:
2915 case FT_UINT64:
2916 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2917 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2918 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2919 new_fi->flags |= FI_VARINT0x00040000;
2920 }
2921 }
2922 else {
2923 /*
2924 * Map all other non-zero values to little-endian for
2925 * backwards compatibility.
2926 */
2927 if (encoding)
2928 encoding = ENC_LITTLE_ENDIAN0x80000000;
2929
2930 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2931 }
2932 proto_tree_set_uint64(new_fi, value64);
2933 break;
2934
2935 /* XXX - make these just FT_INT? */
2936 case FT_INT8:
2937 case FT_INT16:
2938 case FT_INT24:
2939 case FT_INT32:
2940 /*
2941 * Map all non-zero values to little-endian for
2942 * backwards compatibility.
2943 */
2944 if (encoding)
2945 encoding = ENC_LITTLE_ENDIAN0x80000000;
2946 proto_tree_set_int(new_fi,
2947 get_int_value(tree, tvb, start, length, encoding));
2948 break;
2949
2950 case FT_INT40:
2951 case FT_INT48:
2952 case FT_INT56:
2953 case FT_INT64:
2954 /*
2955 * Map all non-zero values to little-endian for
2956 * backwards compatibility.
2957 */
2958 if (encoding)
2959 encoding = ENC_LITTLE_ENDIAN0x80000000;
2960 proto_tree_set_int64(new_fi,
2961 get_int64_value(tree, tvb, start, length, encoding));
2962 break;
2963
2964 case FT_IPv4:
2965 /*
2966 * Map all non-zero values to little-endian for
2967 * backwards compatibility.
2968 */
2969 if (encoding)
2970 encoding = ENC_LITTLE_ENDIAN0x80000000;
2971 if (length != FT_IPv4_LEN4) {
2972 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2973 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2974 }
2975 ipv4_value = tvb_get_ipv4(tvb, start);
2976 /*
2977 * NOTE: to support code written when
2978 * proto_tree_add_item() took a bool as its
2979 * last argument, with false meaning "big-endian"
2980 * and true meaning "little-endian", we treat any
2981 * non-zero value of "encoding" as meaning
2982 * "little-endian".
2983 */
2984 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value)(((guint32) ( (((guint32) (ipv4_value) & (guint32) 0x000000ffU
) << 24) | (((guint32) (ipv4_value) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (ipv4_value) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (ipv4_value) & (guint32) 0xff000000U
) >> 24))))
: ipv4_value);
2985 break;
2986
2987 case FT_IPXNET:
2988 if (length != FT_IPXNET_LEN4) {
2989 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2990 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2991 }
2992 proto_tree_set_ipxnet(new_fi,
2993 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2994 break;
2995
2996 case FT_IPv6:
2997 if (length != FT_IPv6_LEN16) {
2998 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2999 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3000 }
3001 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3002 break;
3003
3004 case FT_FCWWN:
3005 if (length != FT_FCWWN_LEN8) {
3006 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3007 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3008 }
3009 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3010 break;
3011
3012 case FT_AX25:
3013 if (length != 7) {
3014 length_error = length < 7 ? true1 : false0;
3015 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3016 }
3017 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3018 break;
3019
3020 case FT_VINES:
3021 if (length != VINES_ADDR_LEN6) {
3022 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3023 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3024 }
3025 proto_tree_set_vines_tvb(new_fi, tvb, start);
3026 break;
3027
3028 case FT_ETHER:
3029 if (length != FT_ETHER_LEN6) {
3030 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3031 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3032 }
3033 proto_tree_set_ether_tvb(new_fi, tvb, start);
3034 break;
3035
3036 case FT_EUI64:
3037 /*
3038 * Map all non-zero values to little-endian for
3039 * backwards compatibility.
3040 */
3041 if (encoding)
3042 encoding = ENC_LITTLE_ENDIAN0x80000000;
3043 if (length != FT_EUI64_LEN8) {
3044 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3045 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3046 }
3047 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3048 break;
3049 case FT_GUID:
3050 /*
3051 * Map all non-zero values to little-endian for
3052 * backwards compatibility.
3053 */
3054 if (encoding)
3055 encoding = ENC_LITTLE_ENDIAN0x80000000;
3056 if (length != FT_GUID_LEN16) {
3057 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3058 report_type_length_mismatch(tree, "a GUID", length, length_error);
3059 }
3060 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3061 break;
3062
3063 case FT_OID:
3064 case FT_REL_OID:
3065 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3066 break;
3067
3068 case FT_SYSTEM_ID:
3069 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3070 break;
3071
3072 case FT_FLOAT:
3073 /*
3074 * NOTE: to support code written when
3075 * proto_tree_add_item() took a bool as its
3076 * last argument, with false meaning "big-endian"
3077 * and true meaning "little-endian", we treat any
3078 * non-zero value of "encoding" as meaning
3079 * "little-endian".
3080 *
3081 * At some point in the future, we might
3082 * support non-IEEE-binary floating-point
3083 * formats in the encoding as well
3084 * (IEEE decimal, System/3x0, VAX).
3085 */
3086 if (encoding)
3087 encoding = ENC_LITTLE_ENDIAN0x80000000;
3088 if (length != 4) {
3089 length_error = length < 4 ? true1 : false0;
3090 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3091 }
3092 if (encoding)
3093 floatval = tvb_get_letohieee_float(tvb, start);
3094 else
3095 floatval = tvb_get_ntohieee_float(tvb, start);
3096 proto_tree_set_float(new_fi, floatval);
3097 break;
3098
3099 case FT_DOUBLE:
3100 /*
3101 * NOTE: to support code written when
3102 * proto_tree_add_item() took a bool as its
3103 * last argument, with false meaning "big-endian"
3104 * and true meaning "little-endian", we treat any
3105 * non-zero value of "encoding" as meaning
3106 * "little-endian".
3107 *
3108 * At some point in the future, we might
3109 * support non-IEEE-binary floating-point
3110 * formats in the encoding as well
3111 * (IEEE decimal, System/3x0, VAX).
3112 */
3113 if (encoding == true1)
3114 encoding = ENC_LITTLE_ENDIAN0x80000000;
3115 if (length != 8) {
3116 length_error = length < 8 ? true1 : false0;
3117 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3118 }
3119 if (encoding)
3120 doubleval = tvb_get_letohieee_double(tvb, start);
3121 else
3122 doubleval = tvb_get_ntohieee_double(tvb, start);
3123 proto_tree_set_double(new_fi, doubleval);
3124 break;
3125
3126 case FT_STRING:
3127 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3128 tvb, start, length, &item_length, encoding);
3129 proto_tree_set_string(new_fi, stringval);
3130
3131 /* Instead of calling proto_item_set_len(), since we
3132 * don't yet have a proto_item, we set the
3133 * field_info's length ourselves.
3134 *
3135 * XXX - our caller can't use that length to
3136 * advance an offset unless they arrange that
3137 * there always be a protocol tree into which
3138 * we're putting this item.
3139 */
3140 new_fi->length = item_length;
3141 break;
3142
3143 case FT_STRINGZ:
3144 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3145 tree, tvb, start, length, &item_length, encoding);
3146 proto_tree_set_string(new_fi, stringval);
3147
3148 /* Instead of calling proto_item_set_len(),
3149 * since we don't yet have a proto_item, we
3150 * set the field_info's length ourselves.
3151 *
3152 * XXX - our caller can't use that length to
3153 * advance an offset unless they arrange that
3154 * there always be a protocol tree into which
3155 * we're putting this item.
3156 */
3157 new_fi->length = item_length;
3158 break;
3159
3160 case FT_UINT_STRING:
3161 /*
3162 * NOTE: to support code written when
3163 * proto_tree_add_item() took a bool as its
3164 * last argument, with false meaning "big-endian"
3165 * and true meaning "little-endian", if the
3166 * encoding value is true, treat that as
3167 * ASCII with a little-endian length.
3168 *
3169 * This won't work for code that passes
3170 * arbitrary non-zero values; that code
3171 * will need to be fixed.
3172 */
3173 if (encoding == true1)
3174 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3175 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3176 tree, tvb, start, length, &item_length, encoding);
3177 proto_tree_set_string(new_fi, stringval);
3178
3179 /* Instead of calling proto_item_set_len(), since we
3180 * don't yet have a proto_item, we set the
3181 * field_info's length ourselves.
3182 *
3183 * XXX - our caller can't use that length to
3184 * advance an offset unless they arrange that
3185 * there always be a protocol tree into which
3186 * we're putting this item.
3187 */
3188 new_fi->length = item_length;
3189 break;
3190
3191 case FT_STRINGZPAD:
3192 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3193 tvb, start, length, &item_length, encoding);
3194 proto_tree_set_string(new_fi, stringval);
3195
3196 /* Instead of calling proto_item_set_len(), since we
3197 * don't yet have a proto_item, we set the
3198 * field_info's length ourselves.
3199 *
3200 * XXX - our caller can't use that length to
3201 * advance an offset unless they arrange that
3202 * there always be a protocol tree into which
3203 * we're putting this item.
3204 */
3205 new_fi->length = item_length;
3206 break;
3207
3208 case FT_STRINGZTRUNC:
3209 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3210 tvb, start, length, &item_length, encoding);
3211 proto_tree_set_string(new_fi, stringval);
3212
3213 /* Instead of calling proto_item_set_len(), since we
3214 * don't yet have a proto_item, we set the
3215 * field_info's length ourselves.
3216 *
3217 * XXX - our caller can't use that length to
3218 * advance an offset unless they arrange that
3219 * there always be a protocol tree into which
3220 * we're putting this item.
3221 */
3222 new_fi->length = item_length;
3223 break;
3224
3225 case FT_ABSOLUTE_TIME:
3226 /*
3227 * Absolute times can be in any of a number of
3228 * formats, and they can be big-endian or
3229 * little-endian.
3230 *
3231 * Historically FT_TIMEs were only timespecs;
3232 * the only question was whether they were stored
3233 * in big- or little-endian format.
3234 *
3235 * For backwards compatibility, we interpret an
3236 * encoding of 1 as meaning "little-endian timespec",
3237 * so that passing true is interpreted as that.
3238 */
3239 if (encoding == true1)
3240 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3241
3242 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3243
3244 proto_tree_set_time(new_fi, &time_stamp);
3245 break;
3246
3247 case FT_RELATIVE_TIME:
3248 /*
3249 * Relative times can be in any of a number of
3250 * formats, and they can be big-endian or
3251 * little-endian.
3252 *
3253 * Historically FT_TIMEs were only timespecs;
3254 * the only question was whether they were stored
3255 * in big- or little-endian format.
3256 *
3257 * For backwards compatibility, we interpret an
3258 * encoding of 1 as meaning "little-endian timespec",
3259 * so that passing true is interpreted as that.
3260 */
3261 if (encoding == true1)
3262 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3263
3264 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3265
3266 proto_tree_set_time(new_fi, &time_stamp);
3267 break;
3268 case FT_IEEE_11073_SFLOAT:
3269 if (encoding)
3270 encoding = ENC_LITTLE_ENDIAN0x80000000;
3271 if (length != 2) {
3272 length_error = length < 2 ? true1 : false0;
3273 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3274 }
3275
3276 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3277
3278 break;
3279 case FT_IEEE_11073_FLOAT:
3280 if (encoding)
3281 encoding = ENC_LITTLE_ENDIAN0x80000000;
3282 if (length != 4) {
3283 length_error = length < 4 ? true1 : false0;
3284 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3285 }
3286 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3287
3288 break;
3289 default:
3290 REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3291 new_fi->hfinfo->abbrev,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3292 new_fi->hfinfo->type,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3293 ftype_name(new_fi->hfinfo->type))proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
;
3294 break;
3295 }
3296 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
3297
3298 /* Don't add new node to proto_tree until now so that any exceptions
3299 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3300 /* XXX. wouldn't be better to add this item to tree, with some special
3301 * flag (FI_EXCEPTION?) to know which item caused exception? For
3302 * strings and bytes, we would have to set new_fi->value to something
3303 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3304 * could handle NULL values. */
3305 pi = proto_tree_add_node(tree, new_fi);
3306
3307 switch (new_fi->hfinfo->type) {
3308
3309 case FT_STRING:
3310 /* XXX: trailing stray character detection should be done
3311 * _before_ conversion to UTF-8, because conversion can change
3312 * the length, or else get_string_length should return a value
3313 * for the "length in bytes of the string after conversion
3314 * including internal nulls." (Noting that we do, for other
3315 * reasons, still need the "length in bytes in the field",
3316 * especially for FT_STRINGZ.)
3317 *
3318 * This is true even for ASCII and UTF-8, because
3319 * substituting REPLACEMENT CHARACTERS for illegal characters
3320 * can also do so (and for UTF-8 possibly even make the
3321 * string _shorter_).
3322 */
3323 detect_trailing_stray_characters(encoding, stringval, item_length, pi);
3324 break;
3325
3326 default:
3327 break;
3328 }
3329
3330 return pi;
3331}
3332
3333proto_item *
3334proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3335 const unsigned start, unsigned length,
3336 const unsigned encoding, int32_t *retval)
3337{
3338 header_field_info *hfinfo;
3339 field_info *new_fi;
3340 int32_t value;
3341
3342 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", 3342, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3342,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3342, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3343
3344 switch (hfinfo->type) {
3345 case FT_INT8:
3346 case FT_INT16:
3347 case FT_INT24:
3348 case FT_INT32:
3349 break;
3350 case FT_INT64:
3351 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)
3352 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3353 default:
3354 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)
3355 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3356 }
3357
3358 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3359 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3360 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3361 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3362 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3363 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3364 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3365
3366 if (encoding & ENC_STRING0x07000000) {
3367 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3368 }
3369 /* I believe it's ok if this is called with a NULL tree */
3370 value = get_int_value(tree, tvb, start, length, encoding);
3371
3372 if (retval) {
3373 int no_of_bits;
3374 *retval = value;
3375 if (hfinfo->bitmask) {
3376 /* Mask out irrelevant portions */
3377 *retval &= (uint32_t)(hfinfo->bitmask);
3378 /* Shift bits */
3379 *retval >>= hfinfo_bitshift(hfinfo);
3380 }
3381 no_of_bits = ws_count_ones(hfinfo->bitmask);
3382 *retval = ws_sign_ext32(*retval, no_of_bits);
3383 }
3384
3385 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3386
3387 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", 3387
, __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", 3387, "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", 3387, "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", 3387, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3388
3389 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3390
3391 proto_tree_set_int(new_fi, value);
3392
3393 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3394
3395 return proto_tree_add_node(tree, new_fi);
3396}
3397
3398proto_item *
3399proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3400 const unsigned start, unsigned length,
3401 const unsigned encoding, uint32_t *retval)
3402{
3403 header_field_info *hfinfo;
3404 field_info *new_fi;
3405 uint32_t value;
3406
3407 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", 3407, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3407,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3407, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3408
3409 switch (hfinfo->type) {
3410 case FT_CHAR:
3411 case FT_UINT8:
3412 case FT_UINT16:
3413 case FT_UINT24:
3414 case FT_UINT32:
3415 break;
3416 default:
3417 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)
3418 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)
;
3419 }
3420
3421 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3422 {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3423 if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3424 *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3425 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3426 return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3427 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3428 )if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
;
3429
3430 if (encoding & ENC_STRING0x07000000) {
3431 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3432 }
3433 /* I believe it's ok if this is called with a NULL tree */
3434 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3435 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3436 uint64_t temp64;
3437 tvb_get_varint(tvb, start, length, &temp64, encoding);
3438 value = (uint32_t)temp64;
3439 } else {
3440 value = get_uint_value(tree, tvb, start, length, encoding);
3441 }
3442
3443 if (retval) {
3444 *retval = value;
3445 if (hfinfo->bitmask) {
3446 /* Mask out irrelevant portions */
3447 *retval &= (uint32_t)(hfinfo->bitmask);
3448 /* Shift bits */
3449 *retval >>= hfinfo_bitshift(hfinfo);
3450 }
3451 }
3452
3453 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3454
3455 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", 3455
, __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", 3455, "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", 3455, "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", 3455, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3456
3457 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3458
3459 proto_tree_set_uint(new_fi, value);
3460
3461 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3462 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3463 new_fi->flags |= FI_VARINT0x00040000;
3464 }
3465 return proto_tree_add_node(tree, new_fi);
3466}
3467
3468proto_item *
3469proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3470 const unsigned start, unsigned length,
3471 const unsigned encoding, uint32_t *retval)
3472{
3473 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3474}
3475
3476proto_item *
3477proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3478 const unsigned start, unsigned length,
3479 const unsigned encoding, uint8_t *retval)
3480{
3481 /* TODO: further restrict by hfinfo->type ? */
3482 uint32_t val32;
3483 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3484 *retval = (uint8_t)val32;
3485 return item;
3486}
3487
3488proto_item *
3489proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3490 const unsigned start, unsigned length,
3491 const unsigned encoding, uint16_t *retval)
3492{
3493 /* TODO: further restrict by hfinfo->type ? */
3494 uint32_t val32;
3495 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3496 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3497 return item;
3498}
3499
3500
3501/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3502 * and returns proto_item* and uint value retrieved*/
3503proto_item *
3504ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3505 const unsigned encoding, uint32_t *retval)
3506{
3507 field_info *new_fi;
3508 header_field_info *hfinfo;
3509 unsigned item_length;
3510 unsigned offset;
3511 uint32_t value;
3512
3513 offset = ptvc->offset;
3514 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", 3514, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3514,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3514, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3515
3516 switch (hfinfo->type) {
3517 case FT_CHAR:
3518 case FT_UINT8:
3519 case FT_UINT16:
3520 case FT_UINT24:
3521 case FT_UINT32:
3522 break;
3523 default:
3524 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)
3525 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)
;
3526 }
3527
3528 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3529 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3530
3531 /* I believe it's ok if this is called with a NULL tree */
3532 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3533 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3534
3535 if (retval) {
3536 *retval = value;
3537 if (hfinfo->bitmask) {
3538 /* Mask out irrelevant portions */
3539 *retval &= (uint32_t)(hfinfo->bitmask);
3540 /* Shift bits */
3541 *retval >>= hfinfo_bitshift(hfinfo);
3542 }
3543 }
3544
3545 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3546
3547 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3548
3549 /* Coast clear. Try and fake it */
3550 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", 3550
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3550, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3550, "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", 3550, __func__, "Adding %s would put more than %d 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); } } }
;
3551
3552 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3553
3554 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3555 offset, length, encoding);
3556}
3557
3558/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3559 * and returns proto_item* and int value retrieved*/
3560proto_item *
3561ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3562 const unsigned encoding, int32_t *retval)
3563{
3564 field_info *new_fi;
3565 header_field_info *hfinfo;
3566 unsigned item_length;
3567 unsigned offset;
3568 uint32_t value;
3569
3570 offset = ptvc->offset;
3571 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", 3571, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3571,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3571, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3572
3573 switch (hfinfo->type) {
3574 case FT_INT8:
3575 case FT_INT16:
3576 case FT_INT24:
3577 case FT_INT32:
3578 break;
3579 default:
3580 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)
3581 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3582 }
3583
3584 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3585 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3586
3587 /* I believe it's ok if this is called with a NULL tree */
3588 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3589 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3590
3591 if (retval) {
3592 int no_of_bits;
3593 *retval = value;
3594 if (hfinfo->bitmask) {
3595 /* Mask out irrelevant portions */
3596 *retval &= (uint32_t)(hfinfo->bitmask);
3597 /* Shift bits */
3598 *retval >>= hfinfo_bitshift(hfinfo);
3599 }
3600 no_of_bits = ws_count_ones(hfinfo->bitmask);
3601 *retval = ws_sign_ext32(*retval, no_of_bits);
3602 }
3603
3604 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3605
3606 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3607
3608 /* Coast clear. Try and fake it */
3609 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", 3609
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3609, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3609, "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", 3609, __func__, "Adding %s would put more than %d 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); } } }
;
3610
3611 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3612
3613 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3614 offset, length, encoding);
3615}
3616
3617/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3618 * and returns proto_item* and string value retrieved */
3619proto_item*
3620ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3621{
3622 header_field_info *hfinfo;
3623 field_info *new_fi;
3624 const uint8_t *value;
3625 unsigned item_length;
3626 unsigned offset;
3627
3628 offset = ptvc->offset;
3629
3630 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", 3630
, __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", 3630, "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", 3630, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3631
3632 switch (hfinfo->type) {
3633 case FT_STRING:
3634 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3635 break;
3636 case FT_STRINGZ:
3637 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3638 break;
3639 case FT_UINT_STRING:
3640 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3641 break;
3642 case FT_STRINGZPAD:
3643 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3644 break;
3645 case FT_STRINGZTRUNC:
3646 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3647 break;
3648 default:
3649 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)
3650 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)
;
3651 }
3652
3653 if (retval)
3654 *retval = value;
3655
3656 ptvcursor_advance(ptvc, item_length);
3657
3658 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3659
3660 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", 3660, __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", 3660,
"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", 3660, "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", 3660
, __func__, "Adding %s would put more than %d 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); } } }
;
3661
3662 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3663
3664 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3665 offset, length, encoding);
3666}
3667
3668/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3669 * and returns proto_item* and boolean value retrieved */
3670proto_item*
3671ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3672{
3673 header_field_info *hfinfo;
3674 field_info *new_fi;
3675 unsigned item_length;
3676 unsigned offset;
3677 uint64_t value, bitval;
3678
3679 offset = ptvc->offset;
3680 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", 3680, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3680,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3680, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3681
3682 if (hfinfo->type != FT_BOOLEAN) {
3683 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)
3684 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3685 }
3686
3687 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3688 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3689 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3690 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3691 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3692 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3693 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3694
3695 if (encoding & ENC_STRING0x07000000) {
3696 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3697 }
3698
3699 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3700 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3701
3702 /* I believe it's ok if this is called with a NULL tree */
3703 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3704
3705 if (retval) {
3706 bitval = value;
3707 if (hfinfo->bitmask) {
3708 /* Mask out irrelevant portions */
3709 bitval &= hfinfo->bitmask;
3710 }
3711 *retval = (bitval != 0);
3712 }
3713
3714 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3715
3716 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3717
3718 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", 3718, __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", 3718,
"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", 3718, "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", 3718
, __func__, "Adding %s would put more than %d 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); } } }
;
3719
3720 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3721
3722 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3723 offset, length, encoding);
3724}
3725
3726proto_item *
3727proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3728 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3729{
3730 header_field_info *hfinfo;
3731 field_info *new_fi;
3732 uint64_t value;
3733
3734 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", 3734, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3734,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3735
3736 switch (hfinfo->type) {
3737 case FT_UINT40:
3738 case FT_UINT48:
3739 case FT_UINT56:
3740 case FT_UINT64:
3741 break;
3742 default:
3743 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)
3744 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3745 }
3746
3747 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3748 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3749 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3750 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3751 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3752 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3753 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3754
3755 if (encoding & ENC_STRING0x07000000) {
3756 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3757 }
3758 /* I believe it's ok if this is called with a NULL tree */
3759 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3760 tvb_get_varint(tvb, start, length, &value, encoding);
3761 } else {
3762 value = get_uint64_value(tree, tvb, start, length, encoding);
3763 }
3764
3765 if (retval) {
3766 *retval = value;
3767 if (hfinfo->bitmask) {
3768 /* Mask out irrelevant portions */
3769 *retval &= hfinfo->bitmask;
3770 /* Shift bits */
3771 *retval >>= hfinfo_bitshift(hfinfo);
3772 }
3773 }
3774
3775 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3776
3777 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", 3777
, __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", 3777, "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", 3777, "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", 3777, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3778
3779 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3780
3781 proto_tree_set_uint64(new_fi, value);
3782
3783 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3784 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3785 new_fi->flags |= FI_VARINT0x00040000;
3786 }
3787
3788 return proto_tree_add_node(tree, new_fi);
3789}
3790
3791proto_item *
3792proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3793 const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3794{
3795 header_field_info *hfinfo;
3796 field_info *new_fi;
3797 int64_t value;
3798
3799 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", 3799, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3799,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3799, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3800
3801 switch (hfinfo->type) {
3802 case FT_INT40:
3803 case FT_INT48:
3804 case FT_INT56:
3805 case FT_INT64:
3806 break;
3807 default:
3808 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)
3809 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3810 }
3811
3812 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3813 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3814 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3815 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3816 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3817 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3818 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3819
3820 if (encoding & ENC_STRING0x07000000) {
3821 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3822 }
3823 /* I believe it's ok if this is called with a NULL tree */
3824 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3825 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3826 }
3827 else {
3828 value = get_int64_value(tree, tvb, start, length, encoding);
3829 }
3830
3831 if (retval) {
3832 *retval = value;
3833 }
3834
3835 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3836
3837 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", 3837
, __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", 3837, "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", 3837, "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", 3837, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3838
3839 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3840
3841 proto_tree_set_int64(new_fi, value);
3842
3843 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3844 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3845 new_fi->flags |= FI_VARINT0x00040000;
3846 }
3847
3848 return proto_tree_add_node(tree, new_fi);
3849}
3850
3851proto_item *
3852proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3853 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3854{
3855 header_field_info *hfinfo;
3856 field_info *new_fi;
3857 uint64_t value;
3858
3859 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", 3859, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3859,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3859, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3860
3861 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
))
)) {
3862 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)
3863 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3864 }
3865
3866 if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3867 REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3868 }
3869
3870 if (encoding & ENC_STRING0x07000000) {
3871 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3872 }
3873
3874 /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3875 * It also handles length 0, setting both return values to 0.
3876 * XXX - Should the max length be affected by the field type and/or
3877 * encoding, e.g. 5 for FT_[U]INT32?
3878 * XXX - Should there be separate _varint and _varuint versions to
3879 * avoid the changing the sign when casting the return value?
3880 * XXX - Do we even need the length parameter? Every user of this
3881 * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3882 * separate function, but unlike some field types, variable length
3883 * is the typical case here, not the exception, and the typical
3884 * case should have the shorter, more convenient function name.
3885 * Having the length makes the signature more similar to other
3886 * functions, though. */
3887 length = tvb_get_varint(tvb, start, length, &value, encoding);
3888
3889 if (retval) {
3890 *retval = value;
3891 if (hfinfo->bitmask) {
3892 /* Mask out irrelevant portions */
3893 *retval &= hfinfo->bitmask;
3894 /* Shift bits */
3895 *retval >>= hfinfo_bitshift(hfinfo);
3896 }
3897 }
3898
3899 if (lenretval) {
3900 *lenretval = length;
3901 }
3902
3903 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3904
3905 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", 3905
, __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", 3905, "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", 3905, "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", 3905, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3906
3907 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3908
3909 proto_tree_set_uint64(new_fi, value);
3910
3911 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3912 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3913 new_fi->flags |= FI_VARINT0x00040000;
3914 }
3915
3916 return proto_tree_add_node(tree, new_fi);
3917
3918}
3919
3920proto_item *
3921proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3922 const unsigned start, unsigned length,
3923 const unsigned encoding, bool_Bool *retval)
3924{
3925 header_field_info *hfinfo;
3926 field_info *new_fi;
3927 uint64_t value, bitval;
3928
3929 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", 3929, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3929,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3929, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3930
3931 if (hfinfo->type != FT_BOOLEAN) {
3932 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)
3933 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3934 }
3935
3936 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3937 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3938 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3939 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3940 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3941 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3942 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3943
3944 if (encoding & ENC_STRING0x07000000) {
3945 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3946 }
3947 /* I believe it's ok if this is called with a NULL tree */
3948 value = get_uint64_value(tree, tvb, start, length, encoding);
3949
3950 if (retval) {
3951 bitval = value;
3952 if (hfinfo->bitmask) {
3953 /* Mask out irrelevant portions */
3954 bitval &= hfinfo->bitmask;
3955 }
3956 *retval = (bitval != 0);
3957 }
3958
3959 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3960
3961 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", 3961
, __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", 3961, "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", 3961, "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", 3961, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3962
3963 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3964
3965 proto_tree_set_boolean(new_fi, value);
3966
3967 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3968
3969 return proto_tree_add_node(tree, new_fi);
3970}
3971
3972proto_item *
3973proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3974 const unsigned start, unsigned length,
3975 const unsigned encoding, float *retval)
3976{
3977 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3978 field_info *new_fi;
3979 float value;
3980
3981 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", 3981,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3982
3983 if (hfinfo->type != FT_FLOAT) {
3984 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)
;
3985 }
3986
3987 if (length != 4) {
3988 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3989 }
3990
3991 /* treat any nonzero encoding as little endian for backwards compatibility */
3992 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3993 if (retval) {
3994 *retval = value;
3995 }
3996
3997 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3998
3999 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", 3999
, __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", 3999, "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", 3999, "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", 3999, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4000
4001 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4002 if (encoding) {
4003 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4004 }
4005
4006 proto_tree_set_float(new_fi, value);
4007
4008 return proto_tree_add_node(tree, new_fi);
4009}
4010
4011proto_item *
4012proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4013 const unsigned start, unsigned length,
4014 const unsigned encoding, double *retval)
4015{
4016 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4017 field_info *new_fi;
4018 double value;
4019
4020 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", 4020,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4021
4022 if (hfinfo->type != FT_DOUBLE) {
4023 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)
;
4024 }
4025
4026 if (length != 8) {
4027 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4028 }
4029
4030 /* treat any nonzero encoding as little endian for backwards compatibility */
4031 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4032 if (retval) {
4033 *retval = value;
4034 }
4035
4036 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4037
4038 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", 4038
, __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", 4038, "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", 4038, "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", 4038, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4039
4040 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4041 if (encoding) {
4042 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4043 }
4044
4045 proto_tree_set_double(new_fi, value);
4046
4047 return proto_tree_add_node(tree, new_fi);
4048}
4049
4050proto_item *
4051proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4052 const unsigned start, unsigned length,
4053 const unsigned encoding, ws_in4_addr *retval)
4054{
4055 header_field_info *hfinfo;
4056 field_info *new_fi;
4057 ws_in4_addr value;
4058
4059 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", 4059, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4059,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4059, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4060
4061 switch (hfinfo->type) {
4062 case FT_IPv4:
4063 break;
4064 default:
4065 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)
4066 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4067 }
4068
4069 if (length != FT_IPv4_LEN4)
4070 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)
4071 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4072
4073 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4074 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4075 }
4076
4077 /*
4078 * NOTE: to support code written when proto_tree_add_item() took
4079 * a bool as its last argument, with false meaning "big-endian"
4080 * and true meaning "little-endian", we treat any non-zero value
4081 * of "encoding" as meaning "little-endian".
4082 */
4083 value = tvb_get_ipv4(tvb, start);
4084 if (encoding)
4085 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))))
;
4086
4087 if (retval) {
4088 *retval = value;
4089 }
4090
4091 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4092
4093 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", 4093
, __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", 4093, "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", 4093, "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", 4093, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4094
4095 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4096
4097 proto_tree_set_ipv4(new_fi, value);
4098
4099 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4100 return proto_tree_add_node(tree, new_fi);
4101}
4102
4103proto_item *
4104proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4105 const unsigned start, unsigned length,
4106 const unsigned encoding, ws_in6_addr *addr)
4107{
4108 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4109 field_info *new_fi;
4110
4111 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", 4111,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4112
4113 switch (hfinfo->type) {
4114 case FT_IPv6:
4115 break;
4116 default:
4117 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)
4118 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4119 }
4120
4121 if (length != FT_IPv6_LEN16)
4122 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)
4123 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4124
4125 if (encoding) {
4126 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"
)
;
4127 }
4128
4129 tvb_get_ipv6(tvb, start, addr);
4130
4131 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4132
4133 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", 4133
, __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", 4133, "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", 4133, "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", 4133, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4134
4135 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4136
4137 proto_tree_set_ipv6(new_fi, addr);
4138
4139 return proto_tree_add_node(tree, new_fi);
4140}
4141
4142proto_item *
4143proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4144 const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4145
4146 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4147 field_info *new_fi;
4148
4149 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", 4149,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4150
4151 switch (hfinfo->type) {
4152 case FT_ETHER:
4153 break;
4154 default:
4155 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)
4156 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4157 }
4158
4159 if (length != FT_ETHER_LEN6)
4160 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)
4161 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4162
4163 if (encoding) {
4164 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"
)
;
4165 }
4166
4167 tvb_memcpy(tvb, retval, start, length);
4168
4169 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4170
4171 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", 4171
, __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", 4171, "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", 4171, "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", 4171, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4172
4173 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4174
4175 proto_tree_set_ether(new_fi, retval);
4176
4177 return proto_tree_add_node(tree, new_fi);
4178}
4179
4180
4181proto_item *
4182proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4183 tvbuff_t *tvb,
4184 const unsigned start, int length,
4185 const unsigned encoding,
4186 wmem_allocator_t *scope,
4187 const uint8_t **retval,
4188 unsigned *lenretval)
4189{
4190 proto_item *pi;
4191 header_field_info *hfinfo;
4192 field_info *new_fi;
4193 const uint8_t *value;
4194
4195 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", 4195, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4195,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4195, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4196
4197 switch (hfinfo->type) {
4198 case FT_STRING:
4199 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4200 break;
4201 case FT_STRINGZ:
4202 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4203 break;
4204 case FT_UINT_STRING:
4205 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4206 break;
4207 case FT_STRINGZPAD:
4208 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4209 break;
4210 case FT_STRINGZTRUNC:
4211 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4212 break;
4213 default:
4214 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)
4215 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)
;
4216 }
4217
4218 if (retval)
4219 *retval = value;
4220
4221 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4222
4223 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", 4223
, __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", 4223, "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", 4223, "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", 4223, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4224
4225 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4226
4227 proto_tree_set_string(new_fi, (const char*)value);
4228
4229 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4230
4231 pi = proto_tree_add_node(tree, new_fi);
4232
4233 switch (hfinfo->type) {
4234
4235 case FT_STRINGZ:
4236 case FT_STRINGZPAD:
4237 case FT_STRINGZTRUNC:
4238 case FT_UINT_STRING:
4239 break;
4240
4241 case FT_STRING:
4242 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4243 break;
4244
4245 default:
4246 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4246
, __func__, "assertion \"not reached\" failed")
;
4247 }
4248
4249 return pi;
4250}
4251
4252proto_item *
4253proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4254 const unsigned start, int length,
4255 const unsigned encoding, wmem_allocator_t *scope,
4256 const uint8_t **retval)
4257{
4258 unsigned item_length; // Param cannot be NULL in function below
4259 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4260 tvb, start, length, encoding, scope, retval, &item_length);
4261}
4262
4263proto_item *
4264proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4265 tvbuff_t *tvb,
4266 const unsigned start, int length,
4267 const unsigned encoding,
4268 wmem_allocator_t *scope,
4269 char **retval,
4270 unsigned *lenretval)
4271{
4272 proto_item *pi;
4273 header_field_info *hfinfo;
4274 field_info *new_fi;
4275 const uint8_t *value;
4276 uint32_t n = 0;
4277
4278 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", 4278, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4278,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4278, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4279
4280 switch (hfinfo->type) {
4281 case FT_STRING:
4282 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4283 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4284 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4285 break;
4286 case FT_STRINGZ:
4287 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4288 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4289 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4290 break;
4291 case FT_UINT_STRING:
4292 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4293 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4294 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4295 break;
4296 case FT_STRINGZPAD:
4297 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4298 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4299 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4300 break;
4301 case FT_STRINGZTRUNC:
4302 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4303 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4304 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4305 break;
4306 case FT_BYTES:
4307 tvb_ensure_bytes_exist(tvb, start, length);
4308 value = tvb_get_ptr(tvb, start, length);
4309 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4310 *lenretval = length;
4311 break;
4312 case FT_UINT_BYTES:
4313 n = get_uint_value(tree, tvb, start, length, encoding);
4314 tvb_ensure_bytes_exist(tvb, start + length, n);
4315 value = tvb_get_ptr(tvb, start + length, n);
4316 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4317 *lenretval = length + n;
4318 break;
4319 default:
4320 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)
4321 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)
;
4322 }
4323
4324 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4325
4326 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", 4326
, __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", 4326, "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", 4326, "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", 4326, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4327
4328 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4329
4330 switch (hfinfo->type) {
4331
4332 case FT_STRING:
4333 case FT_STRINGZ:
4334 case FT_UINT_STRING:
4335 case FT_STRINGZPAD:
4336 case FT_STRINGZTRUNC:
4337 proto_tree_set_string(new_fi, (const char*)value);
4338 break;
4339
4340 case FT_BYTES:
4341 proto_tree_set_bytes(new_fi, value, length);
4342 break;
4343
4344 case FT_UINT_BYTES:
4345 proto_tree_set_bytes(new_fi, value, n);
4346 break;
4347
4348 default:
4349 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4349
, __func__, "assertion \"not reached\" failed")
;
4350 }
4351
4352 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4353
4354 pi = proto_tree_add_node(tree, new_fi);
4355
4356 switch (hfinfo->type) {
4357
4358 case FT_STRINGZ:
4359 case FT_STRINGZPAD:
4360 case FT_STRINGZTRUNC:
4361 case FT_UINT_STRING:
4362 break;
4363
4364 case FT_STRING:
4365 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4366 break;
4367
4368 case FT_BYTES:
4369 case FT_UINT_BYTES:
4370 break;
4371
4372 default:
4373 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4373
, __func__, "assertion \"not reached\" failed")
;
4374 }
4375
4376 return pi;
4377}
4378
4379proto_item *
4380proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4381 tvbuff_t *tvb,
4382 const unsigned start, int length,
4383 const unsigned encoding,
4384 wmem_allocator_t *scope,
4385 char **retval)
4386{
4387 unsigned item_length; // Param cannot be NULL in function below
4388 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4389 tvb, start, length, encoding, scope, retval, &item_length);
4390}
4391
4392proto_item *
4393proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4394 tvbuff_t *tvb,
4395 const unsigned start, int length, const unsigned encoding,
4396 wmem_allocator_t *scope, char **retval)
4397{
4398 header_field_info *hfinfo;
4399 field_info *new_fi;
4400 nstime_t time_stamp;
4401 int flags;
4402
4403 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", 4403, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4403,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4403, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4404
4405 switch (hfinfo->type) {
4406 case FT_ABSOLUTE_TIME:
4407 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4408 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4409 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4410 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4411 }
4412 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4413 break;
4414 case FT_RELATIVE_TIME:
4415 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4416 *retval = rel_time_to_secs_str(scope, &time_stamp);
4417 break;
4418 default:
4419 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)
4420 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4421 }
4422
4423 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4424
4425 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", 4425
, __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", 4425, "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", 4425, "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", 4425, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4426
4427 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4428
4429 switch (hfinfo->type) {
4430
4431 case FT_ABSOLUTE_TIME:
4432 case FT_RELATIVE_TIME:
4433 proto_tree_set_time(new_fi, &time_stamp);
4434 break;
4435 default:
4436 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4436
, __func__, "assertion \"not reached\" failed")
;
4437 }
4438
4439 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4440
4441 return proto_tree_add_node(tree, new_fi);
4442}
4443
4444/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4445 and returns proto_item* */
4446proto_item *
4447ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4448 const unsigned encoding)
4449{
4450 field_info *new_fi;
4451 header_field_info *hfinfo;
4452 int item_length;
4453 unsigned offset;
4454
4455 offset = ptvc->offset;
4456 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", 4456, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4456,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4457 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4458 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4459
4460 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4461
4462 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4463
4464 /* Coast clear. Try and fake it */
4465 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", 4465
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4465, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4465, "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", 4465, __func__, "Adding %s would put more than %d 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); } } }
;
4466
4467 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4468
4469 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4470 offset, length, encoding);
4471}
4472
4473/* Add an item to a proto_tree, using the text label registered to that item;
4474 the item is extracted from the tvbuff handed to it. */
4475proto_item *
4476proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4477 const unsigned start, int length, const unsigned encoding)
4478{
4479 field_info *new_fi;
4480 int item_length;
4481
4482 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", 4482,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4483
4484 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4485 test_length(hfinfo, tvb, start, item_length, encoding);
4486
4487 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4488
4489 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", 4489
, __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", 4489, "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", 4489, "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", 4489, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4490
4491 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4492
4493 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4494}
4495
4496proto_item *
4497proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4498 const unsigned start, int length, const unsigned encoding)
4499{
4500 register header_field_info *hfinfo;
4501
4502 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", 4502, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4502,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4502, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4503 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4504}
4505
4506/* Add an item to a proto_tree, using the text label registered to that item;
4507 the item is extracted from the tvbuff handed to it.
4508
4509 Return the length of the item through the pointer. */
4510proto_item *
4511proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4512 tvbuff_t *tvb, const unsigned start,
4513 int length, const unsigned encoding,
4514 unsigned *lenretval)
4515{
4516 field_info *new_fi;
4517 int item_length;
4518 proto_item *item;
4519
4520 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", 4520,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4521
4522 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4523 test_length(hfinfo, tvb, start, item_length, encoding);
4524
4525 if (!tree) {
4526 /*
4527 * We need to get the correct item length here.
4528 * That's normally done by proto_tree_new_item(),
4529 * but we won't be calling it.
4530 */
4531 *lenretval = get_full_length(hfinfo, tvb, start, length,
4532 item_length, encoding);
4533 return NULL((void*)0);
4534 }
4535
4536 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", 4543
, __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", 4543, "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", 4543, "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", 4543
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4537 /*((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", 4543
, __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", 4543, "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", 4543, "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", 4543
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4538 * 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", 4543
, __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", 4543, "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", 4543, "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", 4543
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4539 * 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", 4543
, __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", 4543, "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", 4543, "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", 4543
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4540 */((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", 4543
, __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", 4543, "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", 4543, "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", 4543
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4541 *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", 4543
, __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", 4543, "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", 4543, "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", 4543
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4542 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", 4543
, __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", 4543, "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", 4543, "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", 4543
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4543 })((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", 4543
, __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", 4543, "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", 4543, "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", 4543
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4544
4545 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4546
4547 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4548 *lenretval = new_fi->length;
4549 return item;
4550}
4551
4552proto_item *
4553proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4554 const unsigned start, int length,
4555 const unsigned encoding, unsigned *lenretval)
4556{
4557 register header_field_info *hfinfo;
4558
4559 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", 4559, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4559,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4559, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4560 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4561}
4562
4563/* which FT_ types can use proto_tree_add_bytes_item() */
4564static inline bool_Bool
4565validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4566{
4567 return (type == FT_BYTES ||
4568 type == FT_UINT_BYTES ||
4569 type == FT_OID ||
4570 type == FT_REL_OID ||
4571 type == FT_SYSTEM_ID );
4572}
4573
4574/* Note: this does no validation that the byte array of an FT_OID or
4575 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4576 so I think it's ok to continue not validating it?
4577 */
4578proto_item *
4579proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4580 const unsigned start, unsigned length,
4581 const unsigned encoding,
4582 GByteArray *retval, unsigned *endoff, int *err)
4583{
4584 field_info *new_fi;
4585 GByteArray *bytes = retval;
4586 GByteArray *created_bytes = NULL((void*)0);
4587 bool_Bool failed = false0;
4588 uint32_t n = 0;
4589 header_field_info *hfinfo;
4590 bool_Bool generate = (bytes || tree) ? true1 : false0;
4591
4592 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", 4592, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4592,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4592, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4593
4594 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", 4594,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4595
4596 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", 4597, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4597 "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", 4597, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4598
4599 if (length == 0) {
4600 return NULL((void*)0);
4601 }
4602
4603 if (encoding & ENC_STR_NUM0x01000000) {
4604 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"
)
;
4605 }
4606
4607 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4608 if (hfinfo->type == FT_UINT_BYTES) {
4609 /* can't decode FT_UINT_BYTES from strings */
4610 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")
4611 "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")
;
4612 }
4613
4614 unsigned hex_encoding = encoding;
4615 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4616 /* If none of the separator values are used,
4617 * assume no separator (the common case). */
4618 hex_encoding |= ENC_SEP_NONE0x00010000;
4619#if 0
4620 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")
4621 "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")
;
4622#endif
4623 }
4624
4625 if (!bytes) {
4626 /* caller doesn't care about return value, but we need it to
4627 call tvb_get_string_bytes() and set the tree later */
4628 bytes = created_bytes = g_byte_array_new();
4629 }
4630
4631 /*
4632 * bytes might be NULL after this, but can't add expert
4633 * error until later; if it's NULL, just note that
4634 * it failed.
4635 */
4636 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4637 if (bytes == NULL((void*)0))
4638 failed = true1;
4639 }
4640 else if (generate) {
4641 tvb_ensure_bytes_exist(tvb, start, length);
4642
4643 if (hfinfo->type == FT_UINT_BYTES) {
4644 n = length; /* n is now the "header" length */
4645 length = get_uint_value(tree, tvb, start, n, encoding);
4646 /* length is now the value's length; only store the value in the array */
4647 tvb_ensure_bytes_exist(tvb, start + n, length);
4648 if (!bytes) {
4649 /* caller doesn't care about return value, but
4650 * we may need it to set the tree later */
4651 bytes = created_bytes = g_byte_array_new();
4652 }
4653 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4654 }
4655 else if (length > 0) {
4656 if (!bytes) {
4657 /* caller doesn't care about return value, but
4658 * we may need it to set the tree later */
4659 bytes = created_bytes = g_byte_array_new();
4660 }
4661 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4662 }
4663
4664 if (endoff)
4665 *endoff = start + n + length;
4666 }
4667
4668 if (err)
4669 *err = failed ? EINVAL22 : 0;
4670
4671 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); }
4672 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4673 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); }
4674 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); }
4675 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); }
4676 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4677 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4678
4679 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", 4685
, __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", 4685, "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", 4685, "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", 4685
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4680 {((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", 4685
, __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", 4685, "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", 4685, "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", 4685
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4681 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", 4685
, __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", 4685, "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", 4685, "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", 4685
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4682 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", 4685
, __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", 4685, "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", 4685, "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", 4685
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4683 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", 4685
, __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", 4685, "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", 4685, "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", 4685
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4684 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", 4685
, __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", 4685, "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", 4685, "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", 4685
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4685 } )((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", 4685
, __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", 4685, "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", 4685, "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", 4685
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4686
4687 /* n will be zero except when it's a FT_UINT_BYTES */
4688 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4689
4690 if (encoding & ENC_STRING0x07000000) {
4691 if (failed)
4692 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4693
4694 if (bytes)
4695 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4696 else
4697 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4698
4699 if (created_bytes)
4700 g_byte_array_free(created_bytes, true1);
4701 }
4702 else {
4703 /* n will be zero except when it's a FT_UINT_BYTES */
4704 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4705
4706 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4707 * use the byte array created above in this case.
4708 */
4709 if (created_bytes)
4710 g_byte_array_free(created_bytes, true1);
4711
4712 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4713 (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)
;
4714 }
4715
4716 return proto_tree_add_node(tree, new_fi);
4717}
4718
4719
4720proto_item *
4721proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4722 const unsigned start, const unsigned length,
4723 const unsigned encoding,
4724 nstime_t *retval, unsigned *endoff, int *err)
4725{
4726 field_info *new_fi;
4727 nstime_t time_stamp;
4728 int saved_err = 0;
4729 header_field_info *hfinfo;
4730
4731 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", 4731, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4731,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4731, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4732
4733 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", 4733,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4734
4735 if (length == 0) {
4736 if(retval) {
4737 nstime_set_zero(retval);
4738 }
4739 return NULL((void*)0);
4740 }
4741
4742 nstime_set_zero(&time_stamp);
4743
4744 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4745 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", 4745, ((hfinfo))->abbrev))))
;
4746 /* The only string format that could be a relative time is
4747 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4748 * relative to "now" currently.
4749 */
4750 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4751 saved_err = EINVAL22;
4752 }
4753 else {
4754 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", 4754, ((hfinfo))->abbrev))))
;
4755 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4756
4757 tvb_ensure_bytes_exist(tvb, start, length);
4758 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4759 if (endoff) *endoff = start + length;
4760 }
4761
4762 if (err) *err = saved_err;
4763
4764 if (retval) {
4765 retval->secs = time_stamp.secs;
4766 retval->nsecs = time_stamp.nsecs;
4767 }
4768
4769 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4770
4771 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", 4771
, __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", 4771, "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", 4771, "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", 4771, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4772
4773 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4774
4775 proto_tree_set_time(new_fi, &time_stamp);
4776
4777 if (encoding & ENC_STRING0x07000000) {
4778 if (saved_err)
4779 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4780 }
4781 else {
4782 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4783 (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)
;
4784 }
4785
4786 return proto_tree_add_node(tree, new_fi);
4787}
4788
4789/* Add a FT_NONE to a proto_tree */
4790proto_item *
4791proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4792 const unsigned start, int length, const char *format,
4793 ...)
4794{
4795 proto_item *pi;
4796 va_list ap;
4797 header_field_info *hfinfo;
4798
4799 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4800
4801 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", 4801
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4801, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4801, "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", 4801, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4802
4803 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", 4803
, ((hfinfo))->abbrev))))
;
4804
4805 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4806
4807 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4807, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4808
4809 va_start(ap, format)__builtin_va_start(ap, format);
4810 proto_tree_set_representation(pi, format, ap);
4811 va_end(ap)__builtin_va_end(ap);
4812
4813 /* no value to set for FT_NONE */
4814 return pi;
4815}
4816
4817/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4818 * offset, and returns proto_item* */
4819proto_item *
4820ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4821 const unsigned encoding)
4822{
4823 proto_item *item;
4824
4825 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4826 length, encoding);
4827
4828 return item;
4829}
4830
4831/* Advance the ptvcursor's offset within its tvbuff without
4832 * adding anything to the proto_tree. */
4833void
4834ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4835{
4836 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4837 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4838 }
4839}
4840
4841
4842static void
4843proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4844{
4845 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4845, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4846 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4847}
4848
4849/* Add a FT_PROTOCOL to a proto_tree */
4850proto_item *
4851proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4852 unsigned start, int length, const char *format, ...)
4853{
4854 proto_item *pi;
4855 field_info *new_fi;
4856 tvbuff_t *protocol_tvb;
4857 va_list ap;
4858 header_field_info *hfinfo;
4859 char* protocol_rep;
4860
4861 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4862
4863 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", 4863
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4863, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4863, "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", 4863, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4864
4865 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"
, 4865, ((hfinfo))->abbrev))))
;
4866
4867 /*
4868 * This can throw an exception when it calls get_hfi_length before
4869 * it allocates anything, if length is nonzero and start is past
4870 * the end of the tvb. Afterwards it can't throw an exception,
4871 * as length is clamped to the captured length remaining.
4872 */
4873 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4874 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4875 /* Start the protocol_tvb at the correct start offset, but allow it
4876 * to be lengthened later via finfo_set_len. */
4877 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4878
4879 va_start(ap, format)__builtin_va_start(ap, format);
4880 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4881 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4882 g_free(protocol_rep)(__builtin_object_size ((protocol_rep), 0) != ((size_t) - 1))
? g_free_sized (protocol_rep, __builtin_object_size ((protocol_rep
), 0)) : (g_free) (protocol_rep)
;
4883 va_end(ap)__builtin_va_end(ap);
4884
4885 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4885, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4886
4887 va_start(ap, format)__builtin_va_start(ap, format);
4888 proto_tree_set_representation(pi, format, ap);
4889 va_end(ap)__builtin_va_end(ap);
4890
4891 return pi;
4892}
4893
4894/* Add a FT_BYTES to a proto_tree */
4895proto_item *
4896proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4897 int length, const uint8_t *start_ptr)
4898{
4899 proto_item *pi;
4900 header_field_info *hfinfo;
4901 int item_length;
4902
4903 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", 4903, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4903,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4903, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4904 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4905 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4906
4907 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4908
4909 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", 4909
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4909, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4909, "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", 4909, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4910
4911 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",
4911, ((hfinfo))->abbrev))))
;
4912
4913 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4914 start_ptr = tvb_get_ptr(tvb, start, length);
4915
4916 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4917 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4918
4919 return pi;
4920}
4921
4922/* Add a FT_BYTES to a proto_tree */
4923proto_item *
4924proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4925 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4926{
4927 proto_item *pi;
4928 header_field_info *hfinfo;
4929 int item_length;
4930
4931 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", 4931, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4931,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4931, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4932 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4933 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4934
4935 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4936
4937 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", 4937
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4937, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4937, "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", 4937, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4938
4939 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",
4939, ((hfinfo))->abbrev))))
;
4940
4941 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4942 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4943
4944 return pi;
4945}
4946
4947proto_item *
4948proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4949 unsigned start, int length,
4950 const uint8_t *start_ptr,
4951 const char *format, ...)
4952{
4953 proto_item *pi;
4954 va_list ap;
4955
4956 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4957
4958 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; }
;
4959
4960 va_start(ap, format)__builtin_va_start(ap, format);
4961 proto_tree_set_representation_value(pi, format, ap);
4962 va_end(ap)__builtin_va_end(ap);
4963
4964 return pi;
4965}
4966
4967proto_item *
4968proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4969 unsigned start, int length, const uint8_t *start_ptr,
4970 const char *format, ...)
4971{
4972 proto_item *pi;
4973 va_list ap;
4974
4975 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4976
4977 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; }
;
4978
4979 va_start(ap, format)__builtin_va_start(ap, format);
4980 proto_tree_set_representation(pi, format, ap);
4981 va_end(ap)__builtin_va_end(ap);
4982
4983 return pi;
4984}
4985
4986static void
4987proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4988{
4989 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4989, "length >= 0"
))))
;
4990 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", 4990, "start_ptr != ((void*)0) || length == 0"
))))
;
4991
4992 fvalue_set_bytes_data(fi->value, start_ptr, length);
4993}
4994
4995
4996static void
4997proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
4998{
4999 tvb_ensure_bytes_exist(tvb, offset, length);
5000 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5001}
5002
5003static void
5004proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5005{
5006 GByteArray *bytes;
5007
5008 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5008, "value != ((void*)0)"
))))
;
5009
5010 bytes = byte_array_dup(value);
5011
5012 fvalue_set_byte_array(fi->value, bytes);
5013}
5014
5015/* Add a FT_*TIME to a proto_tree */
5016proto_item *
5017proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5018 unsigned length, const nstime_t *value_ptr)
5019{
5020 proto_item *pi;
5021 header_field_info *hfinfo;
5022
5023 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5024
5025 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", 5025
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5025, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5025, "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", 5025, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5026
5027 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", 5027, ((hfinfo))->abbrev))))
;
5028
5029 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5030 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5031
5032 return pi;
5033}
5034
5035proto_item *
5036proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5037 unsigned start, unsigned length, nstime_t *value_ptr,
5038 const char *format, ...)
5039{
5040 proto_item *pi;
5041 va_list ap;
5042
5043 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5044 if (pi != tree) {
5045 va_start(ap, format)__builtin_va_start(ap, format);
5046 proto_tree_set_representation_value(pi, format, ap);
5047 va_end(ap)__builtin_va_end(ap);
5048 }
5049
5050 return pi;
5051}
5052
5053proto_item *
5054proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5055 unsigned start, unsigned length, nstime_t *value_ptr,
5056 const char *format, ...)
5057{
5058 proto_item *pi;
5059 va_list ap;
5060
5061 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5062 if (pi != tree) {
5063 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5063, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5064
5065 va_start(ap, format)__builtin_va_start(ap, format);
5066 proto_tree_set_representation(pi, format, ap);
5067 va_end(ap)__builtin_va_end(ap);
5068 }
5069
5070 return pi;
5071}
5072
5073/* Set the FT_*TIME value */
5074static void
5075proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5076{
5077 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5077, "value_ptr != ((void*)0)"
))))
;
5078
5079 fvalue_set_time(fi->value, value_ptr);
5080}
5081
5082/* Add a FT_IPXNET to a proto_tree */
5083proto_item *
5084proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5085 unsigned length, uint32_t value)
5086{
5087 proto_item *pi;
5088 header_field_info *hfinfo;
5089
5090 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5091
5092 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", 5092
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5092, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5092, "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", 5092, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5093
5094 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"
, 5094, ((hfinfo))->abbrev))))
;
5095
5096 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5097 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5098
5099 return pi;
5100}
5101
5102proto_item *
5103proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5104 unsigned start, unsigned length, uint32_t value,
5105 const char *format, ...)
5106{
5107 proto_item *pi;
5108 va_list ap;
5109
5110 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5111 if (pi != tree) {
5112 va_start(ap, format)__builtin_va_start(ap, format);
5113 proto_tree_set_representation_value(pi, format, ap);
5114 va_end(ap)__builtin_va_end(ap);
5115 }
5116
5117 return pi;
5118}
5119
5120proto_item *
5121proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5122 unsigned start, unsigned length, uint32_t value,
5123 const char *format, ...)
5124{
5125 proto_item *pi;
5126 va_list ap;
5127
5128 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5129 if (pi != tree) {
5130 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5130, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5131
5132 va_start(ap, format)__builtin_va_start(ap, format);
5133 proto_tree_set_representation(pi, format, ap);
5134 va_end(ap)__builtin_va_end(ap);
5135 }
5136
5137 return pi;
5138}
5139
5140/* Set the FT_IPXNET value */
5141static void
5142proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5143{
5144 fvalue_set_uinteger(fi->value, value);
5145}
5146
5147/* Add a FT_IPv4 to a proto_tree */
5148proto_item *
5149proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5150 unsigned length, ws_in4_addr value)
5151{
5152 proto_item *pi;
5153 header_field_info *hfinfo;
5154
5155 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5156
5157 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", 5157
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5157, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5157, "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", 5157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5158
5159 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", 5159
, ((hfinfo))->abbrev))))
;
5160
5161 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5162 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5163
5164 return pi;
5165}
5166
5167proto_item *
5168proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5169 unsigned start, unsigned length, ws_in4_addr value,
5170 const char *format, ...)
5171{
5172 proto_item *pi;
5173 va_list ap;
5174
5175 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5176 if (pi != tree) {
5177 va_start(ap, format)__builtin_va_start(ap, format);
5178 proto_tree_set_representation_value(pi, format, ap);
5179 va_end(ap)__builtin_va_end(ap);
5180 }
5181
5182 return pi;
5183}
5184
5185proto_item *
5186proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5187 unsigned start, unsigned length, ws_in4_addr value,
5188 const char *format, ...)
5189{
5190 proto_item *pi;
5191 va_list ap;
5192
5193 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5194 if (pi != tree) {
5195 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5195, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5196
5197 va_start(ap, format)__builtin_va_start(ap, format);
5198 proto_tree_set_representation(pi, format, ap);
5199 va_end(ap)__builtin_va_end(ap);
5200 }
5201
5202 return pi;
5203}
5204
5205/* Set the FT_IPv4 value */
5206static void
5207proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5208{
5209 ipv4_addr_and_mask ipv4;
5210 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5211 fvalue_set_ipv4(fi->value, &ipv4);
5212}
5213
5214/* Add a FT_IPv6 to a proto_tree */
5215proto_item *
5216proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5217 unsigned length, const ws_in6_addr *value)
5218{
5219 proto_item *pi;
5220 header_field_info *hfinfo;
5221
5222 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5223
5224 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", 5224
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5224, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5224, "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", 5224, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5225
5226 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", 5226
, ((hfinfo))->abbrev))))
;
5227
5228 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5229 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5230
5231 return pi;
5232}
5233
5234proto_item *
5235proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5236 unsigned start, unsigned length,
5237 const ws_in6_addr *value_ptr,
5238 const char *format, ...)
5239{
5240 proto_item *pi;
5241 va_list ap;
5242
5243 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5244 if (pi != tree) {
5245 va_start(ap, format)__builtin_va_start(ap, format);
5246 proto_tree_set_representation_value(pi, format, ap);
5247 va_end(ap)__builtin_va_end(ap);
5248 }
5249
5250 return pi;
5251}
5252
5253proto_item *
5254proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5255 unsigned start, unsigned length,
5256 const ws_in6_addr *value_ptr,
5257 const char *format, ...)
5258{
5259 proto_item *pi;
5260 va_list ap;
5261
5262 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5263 if (pi != tree) {
5264 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5264, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5265
5266 va_start(ap, format)__builtin_va_start(ap, format);
5267 proto_tree_set_representation(pi, format, ap);
5268 va_end(ap)__builtin_va_end(ap);
5269 }
5270
5271 return pi;
5272}
5273
5274/* Set the FT_IPv6 value */
5275static void
5276proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5277{
5278 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5278, "value != ((void*)0)"
))))
;
5279 ipv6_addr_and_prefix ipv6;
5280 ipv6.addr = *value;
5281 ipv6.prefix = 128;
5282 fvalue_set_ipv6(fi->value, &ipv6);
5283}
5284
5285static void
5286proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5287{
5288 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5289}
5290
5291/* Set the FT_FCWWN value */
5292static void
5293proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5294{
5295 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5295, "value_ptr != ((void*)0)"
))))
;
5296 fvalue_set_fcwwn(fi->value, value_ptr);
5297}
5298
5299static void
5300proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5301{
5302 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5303}
5304
5305/* Add a FT_GUID to a proto_tree */
5306proto_item *
5307proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5308 unsigned length, const e_guid_t *value_ptr)
5309{
5310 proto_item *pi;
5311 header_field_info *hfinfo;
5312
5313 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5314
5315 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", 5315
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5315, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5315, "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", 5315, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5316
5317 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", 5317
, ((hfinfo))->abbrev))))
;
5318
5319 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5320 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5321
5322 return pi;
5323}
5324
5325proto_item *
5326proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5327 unsigned start, unsigned length,
5328 const e_guid_t *value_ptr,
5329 const char *format, ...)
5330{
5331 proto_item *pi;
5332 va_list ap;
5333
5334 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5335 if (pi != tree) {
5336 va_start(ap, format)__builtin_va_start(ap, format);
5337 proto_tree_set_representation_value(pi, format, ap);
5338 va_end(ap)__builtin_va_end(ap);
5339 }
5340
5341 return pi;
5342}
5343
5344proto_item *
5345proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5346 unsigned start, unsigned length, const e_guid_t *value_ptr,
5347 const char *format, ...)
5348{
5349 proto_item *pi;
5350 va_list ap;
5351
5352 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5353 if (pi != tree) {
5354 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5354, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5355
5356 va_start(ap, format)__builtin_va_start(ap, format);
5357 proto_tree_set_representation(pi, format, ap);
5358 va_end(ap)__builtin_va_end(ap);
5359 }
5360
5361 return pi;
5362}
5363
5364/* Set the FT_GUID value */
5365static void
5366proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5367{
5368 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5368, "value_ptr != ((void*)0)"
))))
;
5369 fvalue_set_guid(fi->value, value_ptr);
5370}
5371
5372static void
5373proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5374 const unsigned encoding)
5375{
5376 e_guid_t guid;
5377
5378 tvb_get_guid(tvb, start, &guid, encoding);
5379 proto_tree_set_guid(fi, &guid);
5380}
5381
5382/* Add a FT_OID to a proto_tree */
5383proto_item *
5384proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5385 unsigned length, const uint8_t* value_ptr)
5386{
5387 proto_item *pi;
5388 header_field_info *hfinfo;
5389
5390 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5391
5392 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", 5392
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5392, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5392, "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", 5392, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5393
5394 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", 5394
, ((hfinfo))->abbrev))))
;
5395
5396 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5397 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5398
5399 return pi;
5400}
5401
5402proto_item *
5403proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5404 unsigned start, unsigned length,
5405 const uint8_t* value_ptr,
5406 const char *format, ...)
5407{
5408 proto_item *pi;
5409 va_list ap;
5410
5411 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5412 if (pi != tree) {
5413 va_start(ap, format)__builtin_va_start(ap, format);
5414 proto_tree_set_representation_value(pi, format, ap);
5415 va_end(ap)__builtin_va_end(ap);
5416 }
5417
5418 return pi;
5419}
5420
5421proto_item *
5422proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5423 unsigned start, unsigned length, const uint8_t* value_ptr,
5424 const char *format, ...)
5425{
5426 proto_item *pi;
5427 va_list ap;
5428
5429 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5430 if (pi != tree) {
5431 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5431, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5432
5433 va_start(ap, format)__builtin_va_start(ap, format);
5434 proto_tree_set_representation(pi, format, ap);
5435 va_end(ap)__builtin_va_end(ap);
5436 }
5437
5438 return pi;
5439}
5440
5441/* Set the FT_OID value */
5442static void
5443proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5444{
5445 GByteArray *bytes;
5446
5447 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", 5447, "value_ptr != ((void*)0) || length == 0"
))))
;
5448
5449 bytes = g_byte_array_new();
5450 if (length > 0) {
5451 g_byte_array_append(bytes, value_ptr, length);
5452 }
5453 fvalue_set_byte_array(fi->value, bytes);
5454}
5455
5456static void
5457proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5458{
5459 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5460}
5461
5462/* Set the FT_SYSTEM_ID value */
5463static void
5464proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5465{
5466 GByteArray *bytes;
5467
5468 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", 5468, "value_ptr != ((void*)0) || length == 0"
))))
;
5469
5470 bytes = g_byte_array_new();
5471 if (length > 0) {
5472 g_byte_array_append(bytes, value_ptr, length);
5473 }
5474 fvalue_set_byte_array(fi->value, bytes);
5475}
5476
5477static void
5478proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5479{
5480 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5481}
5482
5483/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5484 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5485 * is destroyed. */
5486proto_item *
5487proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5488 int length, const char* value)
5489{
5490 proto_item *pi;
5491 header_field_info *hfinfo;
5492 int item_length;
5493
5494 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", 5494, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5494,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5494, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5495 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5496 /*
5497 * Special case - if the length is 0, skip the test, so that
5498 * we can have an empty string right after the end of the
5499 * packet. (This handles URL-encoded forms where the last field
5500 * has no value so the form ends right after the =.)
5501 *
5502 * XXX - length zero makes sense for FT_STRING, and more or less
5503 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5504 * for FT_STRINGZ (except that a number of fields that should be
5505 * one of the others are actually registered as FT_STRINGZ.)
5506 */
5507 if (item_length != 0)
5508 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5509
5510 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5511
5512 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", 5512
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5512, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5512, "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", 5512, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5513
5514 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", 5514, ((hfinfo))->abbrev))))
;
5515
5516 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5517 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5517, "length >= 0"
))))
;
5518
5519 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", 5519, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5520 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5521
5522 return pi;
5523}
5524
5525proto_item *
5526proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5527 unsigned start, int length, const char* value,
5528 const char *format,
5529 ...)
5530{
5531 proto_item *pi;
5532 va_list ap;
5533
5534 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5535 if (pi != tree) {
5536 va_start(ap, format)__builtin_va_start(ap, format);
5537 proto_tree_set_representation_value(pi, format, ap);
5538 va_end(ap)__builtin_va_end(ap);
5539 }
5540
5541 return pi;
5542}
5543
5544proto_item *
5545proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5546 unsigned start, int length, const char* value,
5547 const char *format, ...)
5548{
5549 proto_item *pi;
5550 va_list ap;
5551
5552 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5553 if (pi != tree) {
5554 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5554, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5555
5556 va_start(ap, format)__builtin_va_start(ap, format);
5557 proto_tree_set_representation(pi, format, ap);
5558 va_end(ap)__builtin_va_end(ap);
5559 }
5560
5561 return pi;
5562}
5563
5564/* Set the FT_STRING value */
5565static void
5566proto_tree_set_string(field_info *fi, const char* value)
5567{
5568 if (value) {
5569 fvalue_set_string(fi->value, value);
5570 } else {
5571 /*
5572 * XXX - why is a null value for a string field
5573 * considered valid?
5574 */
5575 fvalue_set_string(fi->value, "[ Null ]");
5576 }
5577}
5578
5579/* Set the FT_AX25 value */
5580static void
5581proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5582{
5583 fvalue_set_ax25(fi->value, value);
5584}
5585
5586static void
5587proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5588{
5589 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5590}
5591
5592/* Set the FT_VINES value */
5593static void
5594proto_tree_set_vines(field_info *fi, const uint8_t* value)
5595{
5596 fvalue_set_vines(fi->value, value);
5597}
5598
5599static void
5600proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5601{
5602 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5603}
5604
5605/* Add a FT_ETHER to a proto_tree */
5606proto_item *
5607proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5608 unsigned length, const uint8_t* value)
5609{
5610 proto_item *pi;
5611 header_field_info *hfinfo;
5612
5613 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5614
5615 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", 5615
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5615, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5615, "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", 5615, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5616
5617 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",
5617, ((hfinfo))->abbrev))))
;
5618
5619 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5620 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5621
5622 return pi;
5623}
5624
5625proto_item *
5626proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5627 unsigned start, unsigned length, const uint8_t* value,
5628 const char *format, ...)
5629{
5630 proto_item *pi;
5631 va_list ap;
5632
5633 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5634 if (pi != tree) {
5635 va_start(ap, format)__builtin_va_start(ap, format);
5636 proto_tree_set_representation_value(pi, format, ap);
5637 va_end(ap)__builtin_va_end(ap);
5638 }
5639
5640 return pi;
5641}
5642
5643proto_item *
5644proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5645 unsigned start, unsigned length, const uint8_t* value,
5646 const char *format, ...)
5647{
5648 proto_item *pi;
5649 va_list ap;
5650
5651 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5652 if (pi != tree) {
5653 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5653, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5654
5655 va_start(ap, format)__builtin_va_start(ap, format);
5656 proto_tree_set_representation(pi, format, ap);
5657 va_end(ap)__builtin_va_end(ap);
5658 }
5659
5660 return pi;
5661}
5662
5663/* Set the FT_ETHER value */
5664static void
5665proto_tree_set_ether(field_info *fi, const uint8_t* value)
5666{
5667 fvalue_set_ether(fi->value, value);
5668}
5669
5670static void
5671proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5672{
5673 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5674}
5675
5676/* Add a FT_BOOLEAN to a proto_tree */
5677proto_item *
5678proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5679 unsigned length, uint64_t value)
5680{
5681 proto_item *pi;
5682 header_field_info *hfinfo;
5683
5684 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5685
5686 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", 5686
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5686, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5686, "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", 5686, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5687
5688 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"
, 5688, ((hfinfo))->abbrev))))
;
5689
5690 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5691 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5692
5693 return pi;
5694}
5695
5696proto_item *
5697proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5698 tvbuff_t *tvb, unsigned start, unsigned length,
5699 uint64_t value, const char *format, ...)
5700{
5701 proto_item *pi;
5702 va_list ap;
5703
5704 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5705 if (pi != tree) {
5706 va_start(ap, format)__builtin_va_start(ap, format);
5707 proto_tree_set_representation_value(pi, format, ap);
5708 va_end(ap)__builtin_va_end(ap);
5709 }
5710
5711 return pi;
5712}
5713
5714proto_item *
5715proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5716 unsigned start, unsigned length, uint64_t value,
5717 const char *format, ...)
5718{
5719 proto_item *pi;
5720 va_list ap;
5721
5722 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5723 if (pi != tree) {
5724 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5724, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5725
5726 va_start(ap, format)__builtin_va_start(ap, format);
5727 proto_tree_set_representation(pi, format, ap);
5728 va_end(ap)__builtin_va_end(ap);
5729 }
5730
5731 return pi;
5732}
5733
5734/* Set the FT_BOOLEAN value */
5735static void
5736proto_tree_set_boolean(field_info *fi, uint64_t value)
5737{
5738 proto_tree_set_uint64(fi, value);
5739}
5740
5741/* Generate, into "buf", a string showing the bits of a bitfield.
5742 Return a pointer to the character after that string. */
5743static char *
5744other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5745{
5746 int i = 0;
5747 uint64_t bit;
5748 char *p;
5749
5750 p = buf;
5751
5752 /* This is a devel error. It is safer to stop here. */
5753 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5753, "width >= 1"
))))
;
5754
5755 bit = UINT64_C(1)1UL << (width - 1);
5756 for (;;) {
5757 if (mask & bit) {
5758 /* This bit is part of the field. Show its value. */
5759 if (val & bit)
5760 *p++ = '1';
5761 else
5762 *p++ = '0';
5763 } else {
5764 /* This bit is not part of the field. */
5765 *p++ = '.';
5766 }
5767 bit >>= 1;
5768 i++;
5769 if (i >= width)
5770 break;
5771 if (i % 4 == 0)
5772 *p++ = ' ';
5773 }
5774 *p = '\0';
5775 return p;
5776}
5777
5778static char *
5779decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5780{
5781 char *p;
5782
5783 p = other_decode_bitfield_value(buf, val, mask, width);
5784 p = g_stpcpy(p, " = ");
5785
5786 return p;
5787}
5788
5789static char *
5790other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5791{
5792 int i = 0;
5793 uint64_t bit;
5794 char *p;
5795
5796 p = buf;
5797
5798 /* This is a devel error. It is safer to stop here. */
5799 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5799, "width >= 1"
))))
;
5800
5801 bit = UINT64_C(1)1UL << (width - 1);
5802 for (;;) {
5803 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5804 (mask & bit)) {
5805 /* This bit is part of the field. Show its value. */
5806 if (val & bit)
5807 *p++ = '1';
5808 else
5809 *p++ = '0';
5810 } else {
5811 /* This bit is not part of the field. */
5812 *p++ = '.';
5813 }
5814 bit >>= 1;
5815 i++;
5816 if (i >= width)
5817 break;
5818 if (i % 4 == 0)
5819 *p++ = ' ';
5820 }
5821
5822 *p = '\0';
5823 return p;
5824}
5825
5826static char *
5827decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5828{
5829 char *p;
5830
5831 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5832 p = g_stpcpy(p, " = ");
5833
5834 return p;
5835}
5836
5837/* Add a FT_FLOAT to a proto_tree */
5838proto_item *
5839proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5840 unsigned length, float value)
5841{
5842 proto_item *pi;
5843 header_field_info *hfinfo;
5844
5845 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5846
5847 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", 5847
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5847, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5847, "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", 5847, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5848
5849 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",
5849, ((hfinfo))->abbrev))))
;
5850
5851 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5852 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5853
5854 return pi;
5855}
5856
5857proto_item *
5858proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5859 unsigned start, unsigned length, float value,
5860 const char *format, ...)
5861{
5862 proto_item *pi;
5863 va_list ap;
5864
5865 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5866 if (pi != tree) {
5867 va_start(ap, format)__builtin_va_start(ap, format);
5868 proto_tree_set_representation_value(pi, format, ap);
5869 va_end(ap)__builtin_va_end(ap);
5870 }
5871
5872 return pi;
5873}
5874
5875proto_item *
5876proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5877 unsigned start, unsigned length, float value,
5878 const char *format, ...)
5879{
5880 proto_item *pi;
5881 va_list ap;
5882
5883 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5884 if (pi != tree) {
5885 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5885, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5886
5887 va_start(ap, format)__builtin_va_start(ap, format);
5888 proto_tree_set_representation(pi, format, ap);
5889 va_end(ap)__builtin_va_end(ap);
5890 }
5891
5892 return pi;
5893}
5894
5895/* Set the FT_FLOAT value */
5896static void
5897proto_tree_set_float(field_info *fi, float value)
5898{
5899 fvalue_set_floating(fi->value, value);
5900}
5901
5902/* Add a FT_DOUBLE to a proto_tree */
5903proto_item *
5904proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5905 unsigned length, double value)
5906{
5907 proto_item *pi;
5908 header_field_info *hfinfo;
5909
5910 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5911
5912 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", 5912
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5912, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5912, "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", 5912, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5913
5914 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"
, 5914, ((hfinfo))->abbrev))))
;
5915
5916 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5917 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5918
5919 return pi;
5920}
5921
5922proto_item *
5923proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5924 unsigned start, unsigned length, double value,
5925 const char *format, ...)
5926{
5927 proto_item *pi;
5928 va_list ap;
5929
5930 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5931 if (pi != tree) {
5932 va_start(ap, format)__builtin_va_start(ap, format);
5933 proto_tree_set_representation_value(pi, format, ap);
5934 va_end(ap)__builtin_va_end(ap);
5935 }
5936
5937 return pi;
5938}
5939
5940proto_item *
5941proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5942 unsigned start, unsigned length, double value,
5943 const char *format, ...)
5944{
5945 proto_item *pi;
5946 va_list ap;
5947
5948 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5949 if (pi != tree) {
5950 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5950, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5951
5952 va_start(ap, format)__builtin_va_start(ap, format);
5953 proto_tree_set_representation(pi, format, ap);
5954 va_end(ap)__builtin_va_end(ap);
5955 }
5956
5957 return pi;
5958}
5959
5960/* Set the FT_DOUBLE value */
5961static void
5962proto_tree_set_double(field_info *fi, double value)
5963{
5964 fvalue_set_floating(fi->value, value);
5965}
5966
5967/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5968proto_item *
5969proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5970 unsigned length, uint32_t value)
5971{
5972 proto_item *pi = NULL((void*)0);
5973 header_field_info *hfinfo;
5974
5975 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5976
5977 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", 5977
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5977, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5977, "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", 5977, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5978
5979 switch (hfinfo->type) {
5980 case FT_CHAR:
5981 case FT_UINT8:
5982 case FT_UINT16:
5983 case FT_UINT24:
5984 case FT_UINT32:
5985 case FT_FRAMENUM:
5986 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5987 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5988 break;
5989
5990 default:
5991 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)
5992 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)
;
5993 }
5994
5995 return pi;
5996}
5997
5998proto_item *
5999proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6000 unsigned start, unsigned length, uint32_t value,
6001 const char *format, ...)
6002{
6003 proto_item *pi;
6004 va_list ap;
6005
6006 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6007 if (pi != tree) {
6008 va_start(ap, format)__builtin_va_start(ap, format);
6009 proto_tree_set_representation_value(pi, format, ap);
6010 va_end(ap)__builtin_va_end(ap);
6011 }
6012
6013 return pi;
6014}
6015
6016proto_item *
6017proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6018 unsigned start, unsigned length, uint32_t value,
6019 const char *format, ...)
6020{
6021 proto_item *pi;
6022 va_list ap;
6023
6024 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6025 if (pi != tree) {
6026 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6026, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6027
6028 va_start(ap, format)__builtin_va_start(ap, format);
6029 proto_tree_set_representation(pi, format, ap);
6030 va_end(ap)__builtin_va_end(ap);
6031 }
6032
6033 return pi;
6034}
6035
6036/* Set the FT_UINT{8,16,24,32} value */
6037static void
6038proto_tree_set_uint(field_info *fi, uint32_t value)
6039{
6040 const header_field_info *hfinfo;
6041 uint32_t integer;
6042
6043 hfinfo = fi->hfinfo;
6044 integer = value;
6045
6046 if (hfinfo->bitmask) {
6047 /* Mask out irrelevant portions */
6048 integer &= (uint32_t)(hfinfo->bitmask);
6049
6050 /* Shift bits */
6051 integer >>= hfinfo_bitshift(hfinfo);
6052
6053 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6054 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)
;
6055 }
6056
6057 fvalue_set_uinteger(fi->value, integer);
6058}
6059
6060/* Add FT_UINT{40,48,56,64} to a proto_tree */
6061proto_item *
6062proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6063 unsigned length, uint64_t value)
6064{
6065 proto_item *pi = NULL((void*)0);
6066 header_field_info *hfinfo;
6067
6068 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6069
6070 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", 6070
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6070, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6070, "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", 6070, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6071
6072 switch (hfinfo->type) {
6073 case FT_UINT40:
6074 case FT_UINT48:
6075 case FT_UINT56:
6076 case FT_UINT64:
6077 case FT_FRAMENUM:
6078 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6079 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6080 break;
6081
6082 default:
6083 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)
6084 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)
;
6085 }
6086
6087 return pi;
6088}
6089
6090proto_item *
6091proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6092 unsigned start, unsigned length, uint64_t value,
6093 const char *format, ...)
6094{
6095 proto_item *pi;
6096 va_list ap;
6097
6098 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6099 if (pi != tree) {
6100 va_start(ap, format)__builtin_va_start(ap, format);
6101 proto_tree_set_representation_value(pi, format, ap);
6102 va_end(ap)__builtin_va_end(ap);
6103 }
6104
6105 return pi;
6106}
6107
6108proto_item *
6109proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6110 unsigned start, unsigned length, uint64_t value,
6111 const char *format, ...)
6112{
6113 proto_item *pi;
6114 va_list ap;
6115
6116 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6117 if (pi != tree) {
6118 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6118, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6119
6120 va_start(ap, format)__builtin_va_start(ap, format);
6121 proto_tree_set_representation(pi, format, ap);
6122 va_end(ap)__builtin_va_end(ap);
6123 }
6124
6125 return pi;
6126}
6127
6128/* Set the FT_UINT{40,48,56,64} value */
6129static void
6130proto_tree_set_uint64(field_info *fi, uint64_t value)
6131{
6132 const header_field_info *hfinfo;
6133 uint64_t integer;
6134
6135 hfinfo = fi->hfinfo;
6136 integer = value;
6137
6138 if (hfinfo->bitmask) {
6139 /* Mask out irrelevant portions */
6140 integer &= hfinfo->bitmask;
6141
6142 /* Shift bits */
6143 integer >>= hfinfo_bitshift(hfinfo);
6144
6145 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6146 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)
;
6147 }
6148
6149 fvalue_set_uinteger64(fi->value, integer);
6150}
6151
6152/* Add FT_INT{8,16,24,32} to a proto_tree */
6153proto_item *
6154proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6155 unsigned length, int32_t value)
6156{
6157 proto_item *pi = NULL((void*)0);
6158 header_field_info *hfinfo;
6159
6160 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6161
6162 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", 6162
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6162, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6162, "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", 6162, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6163
6164 switch (hfinfo->type) {
6165 case FT_INT8:
6166 case FT_INT16:
6167 case FT_INT24:
6168 case FT_INT32:
6169 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6170 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6171 break;
6172
6173 default:
6174 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)
6175 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6176 }
6177
6178 return pi;
6179}
6180
6181proto_item *
6182proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6183 unsigned start, unsigned length, int32_t value,
6184 const char *format, ...)
6185{
6186 proto_item *pi;
6187 va_list ap;
6188
6189 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6190 if (pi != tree) {
6191 va_start(ap, format)__builtin_va_start(ap, format);
6192 proto_tree_set_representation_value(pi, format, ap);
6193 va_end(ap)__builtin_va_end(ap);
6194 }
6195
6196 return pi;
6197}
6198
6199proto_item *
6200proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6201 unsigned start, unsigned length, int32_t value,
6202 const char *format, ...)
6203{
6204 proto_item *pi;
6205 va_list ap;
6206
6207 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6208 if (pi != tree) {
6209 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6209, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6210
6211 va_start(ap, format)__builtin_va_start(ap, format);
6212 proto_tree_set_representation(pi, format, ap);
6213 va_end(ap)__builtin_va_end(ap);
6214 }
6215
6216 return pi;
6217}
6218
6219/* Set the FT_INT{8,16,24,32} value */
6220static void
6221proto_tree_set_int(field_info *fi, int32_t value)
6222{
6223 const header_field_info *hfinfo;
6224 uint32_t integer;
6225 int no_of_bits;
6226
6227 hfinfo = fi->hfinfo;
6228 integer = (uint32_t) value;
6229
6230 if (hfinfo->bitmask) {
6231 /* Mask out irrelevant portions */
6232 integer &= (uint32_t)(hfinfo->bitmask);
6233
6234 /* Shift bits */
6235 integer >>= hfinfo_bitshift(hfinfo);
6236
6237 no_of_bits = ws_count_ones(hfinfo->bitmask);
6238 integer = ws_sign_ext32(integer, no_of_bits);
6239
6240 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6241 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)
;
6242 }
6243
6244 fvalue_set_sinteger(fi->value, integer);
6245}
6246
6247/* Add FT_INT{40,48,56,64} to a proto_tree */
6248proto_item *
6249proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6250 unsigned length, int64_t value)
6251{
6252 proto_item *pi = NULL((void*)0);
6253 header_field_info *hfinfo;
6254
6255 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6256
6257 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", 6257
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6257, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6257, "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", 6257, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6258
6259 switch (hfinfo->type) {
6260 case FT_INT40:
6261 case FT_INT48:
6262 case FT_INT56:
6263 case FT_INT64:
6264 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6265 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6266 break;
6267
6268 default:
6269 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)
6270 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6271 }
6272
6273 return pi;
6274}
6275
6276proto_item *
6277proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6278 unsigned start, unsigned length, int64_t value,
6279 const char *format, ...)
6280{
6281 proto_item *pi;
6282 va_list ap;
6283
6284 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6285 if (pi != tree) {
6286 va_start(ap, format)__builtin_va_start(ap, format);
6287 proto_tree_set_representation_value(pi, format, ap);
6288 va_end(ap)__builtin_va_end(ap);
6289 }
6290
6291 return pi;
6292}
6293
6294/* Set the FT_INT{40,48,56,64} value */
6295static void
6296proto_tree_set_int64(field_info *fi, int64_t value)
6297{
6298 const header_field_info *hfinfo;
6299 uint64_t integer;
6300 int no_of_bits;
6301
6302 hfinfo = fi->hfinfo;
6303 integer = value;
6304
6305 if (hfinfo->bitmask) {
6306 /* Mask out irrelevant portions */
6307 integer &= hfinfo->bitmask;
6308
6309 /* Shift bits */
6310 integer >>= hfinfo_bitshift(hfinfo);
6311
6312 no_of_bits = ws_count_ones(hfinfo->bitmask);
6313 integer = ws_sign_ext64(integer, no_of_bits);
6314
6315 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6316 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)
;
6317 }
6318
6319 fvalue_set_sinteger64(fi->value, integer);
6320}
6321
6322proto_item *
6323proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6324 unsigned start, unsigned length, int64_t value,
6325 const char *format, ...)
6326{
6327 proto_item *pi;
6328 va_list ap;
6329
6330 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6331 if (pi != tree) {
6332 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6332, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6333
6334 va_start(ap, format)__builtin_va_start(ap, format);
6335 proto_tree_set_representation(pi, format, ap);
6336 va_end(ap)__builtin_va_end(ap);
6337 }
6338
6339 return pi;
6340}
6341
6342/* Add a FT_EUI64 to a proto_tree */
6343proto_item *
6344proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6345 unsigned length, const uint64_t value)
6346{
6347 proto_item *pi;
6348 header_field_info *hfinfo;
6349
6350 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6351
6352 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", 6352
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6352, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6352, "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", 6352, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6353
6354 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",
6354, ((hfinfo))->abbrev))))
;
6355
6356 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6357 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6358
6359 return pi;
6360}
6361
6362proto_item *
6363proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6364 unsigned start, unsigned length, const uint64_t value,
6365 const char *format, ...)
6366{
6367 proto_item *pi;
6368 va_list ap;
6369
6370 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6371 if (pi != tree) {
6372 va_start(ap, format)__builtin_va_start(ap, format);
6373 proto_tree_set_representation_value(pi, format, ap);
6374 va_end(ap)__builtin_va_end(ap);
6375 }
6376
6377 return pi;
6378}
6379
6380proto_item *
6381proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6382 unsigned start, unsigned length, const uint64_t value,
6383 const char *format, ...)
6384{
6385 proto_item *pi;
6386 va_list ap;
6387
6388 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6389 if (pi != tree) {
6390 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6390, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6391
6392 va_start(ap, format)__builtin_va_start(ap, format);
6393 proto_tree_set_representation(pi, format, ap);
6394 va_end(ap)__builtin_va_end(ap);
6395 }
6396
6397 return pi;
6398}
6399
6400/* Set the FT_EUI64 value */
6401static void
6402proto_tree_set_eui64(field_info *fi, const uint64_t value)
6403{
6404 uint8_t v[FT_EUI64_LEN8];
6405 phtonu64(v, value);
6406 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6407}
6408
6409static void
6410proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6411{
6412 if (encoding)
6413 {
6414 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6415 } else {
6416 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6417 }
6418}
6419
6420proto_item *
6421proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6422 const mac_hf_list_t *list_generic,
6423 int idx, tvbuff_t *tvb,
6424 proto_tree *tree, unsigned offset)
6425{
6426 uint8_t addr[6];
6427 const char *addr_name = NULL((void*)0);
6428 const char *oui_name = NULL((void*)0);
6429 proto_item *addr_item = NULL((void*)0);
6430 proto_tree *addr_tree = NULL((void*)0);
6431 proto_item *ret_val = NULL((void*)0);
6432
6433 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6434 return NULL((void*)0);
6435 }
6436
6437 /* Resolve what we can of the address */
6438 tvb_memcpy(tvb, addr, offset, sizeof addr);
6439 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6440 addr_name = get_ether_name(addr);
6441 }
6442 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6443 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6444 }
6445
6446 /* Add the item for the specific address type */
6447 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6448 if (idx >= 0) {
6449 addr_tree = proto_item_add_subtree(ret_val, idx);
6450 }
6451 else {
6452 addr_tree = tree;
6453 }
6454
6455 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6456 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6457 tvb, offset, 6, addr_name);
6458 proto_item_set_generated(addr_item);
6459 proto_item_set_hidden(addr_item);
6460 }
6461
6462 if (list_specific->hf_oui != NULL((void*)0)) {
6463 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6464 proto_item_set_generated(addr_item);
6465 proto_item_set_hidden(addr_item);
6466
6467 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6468 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6469 proto_item_set_generated(addr_item);
6470 proto_item_set_hidden(addr_item);
6471 }
6472 }
6473
6474 if (list_specific->hf_lg != NULL((void*)0)) {
6475 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6476 }
6477 if (list_specific->hf_ig != NULL((void*)0)) {
6478 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6479 }
6480
6481 /* Were we given a list for generic address fields? If not, stop here */
6482 if (list_generic == NULL((void*)0)) {
6483 return ret_val;
6484 }
6485
6486 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6487 proto_item_set_hidden(addr_item);
6488
6489 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6490 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6491 tvb, offset, 6, addr_name);
6492 proto_item_set_generated(addr_item);
6493 proto_item_set_hidden(addr_item);
6494 }
6495
6496 if (list_generic->hf_oui != NULL((void*)0)) {
6497 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6498 proto_item_set_generated(addr_item);
6499 proto_item_set_hidden(addr_item);
6500
6501 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6502 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6503 proto_item_set_generated(addr_item);
6504 proto_item_set_hidden(addr_item);
6505 }
6506 }
6507
6508 if (list_generic->hf_lg != NULL((void*)0)) {
6509 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6510 proto_item_set_hidden(addr_item);
6511 }
6512 if (list_generic->hf_ig != NULL((void*)0)) {
6513 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6514 proto_item_set_hidden(addr_item);
6515 }
6516 return ret_val;
6517}
6518
6519static proto_item *
6520proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6521{
6522 proto_node *pnode, *tnode, *sibling;
6523 field_info *tfi;
6524 unsigned depth = 1;
6525
6526 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6526, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6527
6528 /*
6529 * Restrict our depth. proto_tree_traverse_pre_order and
6530 * proto_tree_traverse_post_order (and possibly others) are recursive
6531 * so we need to be mindful of our stack size.
6532 */
6533 if (tree->first_child == NULL((void*)0)) {
6534 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6535 depth++;
6536 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6537 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__)), 6540)))
6538 "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__)), 6540)))
6539 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__)), 6540)))
6540 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__)), 6540)))
;
6541 }
6542 }
6543 }
6544
6545 /*
6546 * Make sure "tree" is ready to have subtrees under it, by
6547 * checking whether it's been given an ett_ value.
6548 *
6549 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6550 * node of the protocol tree. That node is not displayed,
6551 * so it doesn't need an ett_ value to remember whether it
6552 * was expanded.
6553 */
6554 tnode = tree;
6555 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6556 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6557 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"
, 6558)
6558 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"
, 6558)
;
6559 /* XXX - is it safe to continue here? */
6560 }
6561
6562 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6563 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6564 pnode->parent = tnode;
6565 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6566 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6567 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6568
6569 if (tnode->last_child != NULL((void*)0)) {
6570 sibling = tnode->last_child;
6571 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6571, "sibling->next == ((void*)0)"
))))
;
6572 sibling->next = pnode;
6573 } else
6574 tnode->first_child = pnode;
6575 tnode->last_child = pnode;
6576
6577 /* We should not be adding a fake node for an interesting field */
6578 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", 6578, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6579
6580 /* XXX - Should the proto_item have a header_field_info member, at least
6581 * for faked items, to know what hfi was faked? (Some dissectors look at
6582 * the tree items directly.)
6583 */
6584 return (proto_item *)pnode;
6585}
6586
6587/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6588static proto_item *
6589proto_tree_add_node(proto_tree *tree, field_info *fi)
6590{
6591 proto_node *pnode, *tnode, *sibling;
6592 field_info *tfi;
6593 unsigned depth = 1;
6594
6595 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6595, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6596
6597 /*
6598 * Restrict our depth. proto_tree_traverse_pre_order and
6599 * proto_tree_traverse_post_order (and possibly others) are recursive
6600 * so we need to be mindful of our stack size.
6601 */
6602 if (tree->first_child == NULL((void*)0)) {
6603 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6604 depth++;
6605 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6606 /* The fvalue_t is pool-allocated; just release the
6607 * type-specific data it owns (see new_field_info()). */
6608 fvalue_cleanup(fi->value);
6609 fi->value = NULL((void*)0);
6610 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__)), 6613)))
6611 "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__)), 6613)))
6612 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__)), 6613)))
6613 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__)), 6613)))
;
6614 }
6615 }
6616 }
6617
6618 /*
6619 * Make sure "tree" is ready to have subtrees under it, by
6620 * checking whether it's been given an ett_ value.
6621 *
6622 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6623 * node of the protocol tree. That node is not displayed,
6624 * so it doesn't need an ett_ value to remember whether it
6625 * was expanded.
6626 */
6627 tnode = tree;
6628 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6629 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6630 /* Since we are not adding fi to a node, its fvalue won't get
6631 * cleaned up by proto_tree_free_node(), so release the
6632 * type-specific data it owns now. The fvalue_t structure itself
6633 * is pool-allocated (see new_field_info()).
6634 */
6635 fvalue_cleanup(fi->value);
6636 fi->value = NULL((void*)0);
6637 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", 6638)
6638 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", 6638)
;
6639 /* XXX - is it safe to continue here? */
6640 }
6641
6642 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6643 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6644 pnode->parent = tnode;
6645 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6646 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6647 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6648
6649 if (tnode->last_child != NULL((void*)0)) {
6650 sibling = tnode->last_child;
6651 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6651, "sibling->next == ((void*)0)"
))))
;
6652 sibling->next = pnode;
6653 } else
6654 tnode->first_child = pnode;
6655 tnode->last_child = pnode;
6656
6657 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6658
6659 return (proto_item *)pnode;
6660}
6661
6662
6663/* Generic way to allocate field_info and add to proto_tree.
6664 * Sets *pfi to address of newly-allocated field_info struct */
6665static proto_item *
6666proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6667 int *length)
6668{
6669 proto_item *pi;
6670 field_info *fi;
6671 int item_length;
6672
6673 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6674 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6675 pi = proto_tree_add_node(tree, fi);
6676
6677 return pi;
6678}
6679
6680/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6681 * Eventually this should replace the other function.
6682 * Sets *pfi to address of newly-allocated field_info struct */
6683static proto_item *
6684proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6685 unsigned *length)
6686{
6687 proto_item *pi;
6688 field_info *fi;
6689 unsigned item_length;
6690
6691 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6692 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6693 pi = proto_tree_add_node(tree, fi);
6694
6695 return pi;
6696}
6697
6698static void
6699get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6700 int *item_length, const unsigned encoding)
6701{
6702 int length_remaining;
6703
6704 /*
6705 * We only allow a null tvbuff if the item has a zero length,
6706 * i.e. if there's no data backing it.
6707 */
6708 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", 6708, "tvb != ((void*)0) || *length == 0"
))))
;
6709
6710 /*
6711 * XXX - in some protocols, there are 32-bit unsigned length
6712 * fields, so lengths in protocol tree and tvbuff routines
6713 * should really be unsigned. We should have, for those
6714 * field types for which "to the end of the tvbuff" makes sense,
6715 * additional routines that take no length argument and
6716 * add fields that run to the end of the tvbuff.
6717 */
6718 if (*length == -1) {
6719 /*
6720 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6721 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6722 * of -1 means "set the length to what remains in the
6723 * tvbuff".
6724 *
6725 * The assumption is either that
6726 *
6727 * 1) the length of the item can only be determined
6728 * by dissection (typically true of items with
6729 * subitems, which are probably FT_NONE or
6730 * FT_PROTOCOL)
6731 *
6732 * or
6733 *
6734 * 2) if the tvbuff is "short" (either due to a short
6735 * snapshot length or due to lack of reassembly of
6736 * fragments/segments/whatever), we want to display
6737 * what's available in the field (probably FT_BYTES
6738 * or FT_STRING) and then throw an exception later
6739 *
6740 * or
6741 *
6742 * 3) the field is defined to be "what's left in the
6743 * packet"
6744 *
6745 * so we set the length to what remains in the tvbuff so
6746 * that, if we throw an exception while dissecting, it
6747 * has what is probably the right value.
6748 *
6749 * For FT_STRINGZ, it means "the string is null-terminated,
6750 * not null-padded; set the length to the actual length
6751 * of the string", and if the tvbuff if short, we just
6752 * throw an exception.
6753 *
6754 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6755 * it means "find the end of the string",
6756 * and if the tvbuff if short, we just throw an exception.
6757 *
6758 * It's not valid for any other type of field. For those
6759 * fields, we treat -1 the same way we treat other
6760 * negative values - we assume the length is a Really
6761 * Big Positive Number, and throw a ReportedBoundsError
6762 * exception, under the assumption that the Really Big
6763 * Length would run past the end of the packet.
6764 */
6765 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
))
)) {
6766 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6767 /*
6768 * Leave the length as -1, so our caller knows
6769 * it was -1.
6770 */
6771 *item_length = *length;
6772 return;
6773 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6774 switch (tvb_get_uint8(tvb, start) >> 6)
6775 {
6776 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6777 *item_length = 1;
6778 break;
6779 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6780 *item_length = 2;
6781 break;
6782 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6783 *item_length = 4;
6784 break;
6785 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6786 *item_length = 8;
6787 break;
6788 }
6789 }
6790 }
6791
6792 switch (hfinfo->type) {
6793
6794 case FT_PROTOCOL:
6795 case FT_NONE:
6796 case FT_BYTES:
6797 case FT_STRING:
6798 case FT_STRINGZPAD:
6799 case FT_STRINGZTRUNC:
6800 /*
6801 * We allow FT_PROTOCOLs to be zero-length -
6802 * for example, an ONC RPC NULL procedure has
6803 * neither arguments nor reply, so the
6804 * payload for that protocol is empty.
6805 *
6806 * We also allow the others to be zero-length -
6807 * because that's the way the code has been for a
6808 * long, long time.
6809 *
6810 * However, we want to ensure that the start
6811 * offset is not *past* the byte past the end
6812 * of the tvbuff: we throw an exception in that
6813 * case.
6814 */
6815 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6816 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6816, "*length >= 0"
))))
;
6817 break;
6818
6819 case FT_STRINGZ:
6820 /*
6821 * Leave the length as -1, so our caller knows
6822 * it was -1.
6823 */
6824 break;
6825
6826 default:
6827 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6828 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6828))
;
6829 }
6830 *item_length = *length;
6831 } else {
6832 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6833 /*
6834 * These types are for interior nodes of the
6835 * tree, and don't have data associated with
6836 * them; if the length is negative (XXX - see
6837 * above) or goes past the end of the tvbuff,
6838 * cut it short at the end of the tvbuff.
6839 * That way, if this field is selected in
6840 * Wireshark, we don't highlight stuff past
6841 * the end of the data.
6842 *
6843 * If we don't have a tvb, then length must be zero,
6844 * per the DISSECTOR_ASSERT() above.
6845 *
6846 * If we do have a tvb, and the length requested is
6847 * nonzero, we want to ensure that the start offset
6848 * is not *past* the byte past the end of the tvbuff
6849 * data: we throw an exception in that case as above.
6850 */
6851 if (tvb && *length) {
6852 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6853 if (*length < 0 ||
6854 (*length > 0 &&
6855 (length_remaining < *length)))
6856 *length = length_remaining;
6857 }
6858 }
6859 *item_length = *length;
6860 if (*item_length < 0) {
6861 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6862 }
6863 }
6864}
6865
6866static void
6867get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6868 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6869{
6870 unsigned length_remaining;
6871
6872 /*
6873 * We only allow a null tvbuff if the item has a zero length,
6874 * i.e. if there's no data backing it.
6875 */
6876 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", 6876, "tvb != ((void*)0) || *length == 0"
))))
;
6877
6878
6879 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6880 /*
6881 * These types are for interior nodes of the
6882 * tree, and don't have data associated with
6883 * them; if the length is negative (XXX - see
6884 * above) or goes past the end of the tvbuff,
6885 * cut it short at the end of the tvbuff.
6886 * That way, if this field is selected in
6887 * Wireshark, we don't highlight stuff past
6888 * the end of the data.
6889 *
6890 * If we don't have a tvb, then length must be zero,
6891 * per the DISSECTOR_ASSERT() above.
6892 *
6893 * If we do have a tvb, and the length requested is
6894 * nonzero, we want to ensure that the start offset
6895 * is not *past* the byte past the end of the tvbuff
6896 * data: we throw an exception in that case as above.
6897 * (If the length requested is zero, then it's quite
6898 * likely that the start offset is the byte past the
6899 * end, but that's ok.)
6900 */
6901 if (tvb && *length) {
6902 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6903 if (length_remaining < *length) {
6904 *length = length_remaining;
6905 }
6906 }
6907 }
6908 *item_length = *length;
6909}
6910
6911static int
6912get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6913 int length, unsigned item_length, const int encoding)
6914{
6915 uint32_t n;
6916
6917 /*
6918 * We need to get the correct item length here.
6919 * That's normally done by proto_tree_new_item(),
6920 * but we won't be calling it.
6921 */
6922 switch (hfinfo->type) {
6923
6924 case FT_NONE:
6925 case FT_PROTOCOL:
6926 case FT_BYTES:
6927 /*
6928 * The length is the specified length.
6929 */
6930 break;
6931
6932 case FT_UINT_BYTES:
6933 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6934 item_length += n;
6935 if ((int)item_length < length) {
6936 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6937 }
6938 break;
6939
6940 /* XXX - make these just FT_UINT? */
6941 case FT_UINT8:
6942 case FT_UINT16:
6943 case FT_UINT24:
6944 case FT_UINT32:
6945 case FT_UINT40:
6946 case FT_UINT48:
6947 case FT_UINT56:
6948 case FT_UINT64:
6949 /* XXX - make these just FT_INT? */
6950 case FT_INT8:
6951 case FT_INT16:
6952 case FT_INT24:
6953 case FT_INT32:
6954 case FT_INT40:
6955 case FT_INT48:
6956 case FT_INT56:
6957 case FT_INT64:
6958 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6959 if (length < -1) {
6960 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6961 }
6962 if (length == -1) {
6963 uint64_t dummy;
6964 /* This can throw an exception */
6965 /* XXX - do this without fetching the varint? */
6966 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6967 if (length == 0) {
6968 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6969 }
6970 }
6971 item_length = length;
6972 break;
6973 }
6974
6975 /*
6976 * The length is the specified length.
6977 */
6978 break;
6979
6980 case FT_BOOLEAN:
6981 case FT_CHAR:
6982 case FT_IPv4:
6983 case FT_IPXNET:
6984 case FT_IPv6:
6985 case FT_FCWWN:
6986 case FT_AX25:
6987 case FT_VINES:
6988 case FT_ETHER:
6989 case FT_EUI64:
6990 case FT_GUID:
6991 case FT_OID:
6992 case FT_REL_OID:
6993 case FT_SYSTEM_ID:
6994 case FT_FLOAT:
6995 case FT_DOUBLE:
6996 case FT_STRING:
6997 /*
6998 * The length is the specified length.
6999 */
7000 break;
7001
7002 case FT_STRINGZ:
7003 if (length < -1) {
7004 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7005 }
7006 if (length == -1) {
7007 /* This can throw an exception */
7008 item_length = tvb_strsize_enc(tvb, start, encoding);
7009 }
7010 break;
7011
7012 case FT_UINT_STRING:
7013 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7014 item_length += n;
7015 if ((int)item_length < length) {
7016 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7017 }
7018 break;
7019
7020 case FT_STRINGZPAD:
7021 case FT_STRINGZTRUNC:
7022 case FT_ABSOLUTE_TIME:
7023 case FT_RELATIVE_TIME:
7024 case FT_IEEE_11073_SFLOAT:
7025 case FT_IEEE_11073_FLOAT:
7026 /*
7027 * The length is the specified length.
7028 */
7029 break;
7030
7031 default:
7032 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
))
7033 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
))
7034 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
))
7035 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
))
;
7036 break;
7037 }
7038 return item_length;
7039}
7040
7041// This was arbitrarily chosen, but if you're adding 50K items to the tree
7042// without advancing the offset you should probably take a long, hard look
7043// at what you're doing.
7044// We *could* make this a configurable option, but I (Gerald) would like to
7045// avoid adding yet another nerd knob.
7046# define PROTO_TREE_MAX_IDLE50000 50000
7047static field_info *
7048new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7049 const unsigned start, const int item_length)
7050{
7051 field_info *fi;
7052
7053 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7054
7055 fi->hfinfo = hfinfo;
7056 fi->start = start;
7057 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7058 /* add the data source tvbuff */
7059 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7060
7061 // If our start offset hasn't advanced after adding many items it probably
7062 // means we're in a large or infinite loop.
7063 if (fi->start > 0) {
7064 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7065 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7066 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7067 if (wireshark_abort_on_too_many_items) {
7068 ws_error("Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7069
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7069 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7069
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7070 }
7071 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7072 * but if not, we should hit the max item error earlier,
7073 * so we shouldn't need to reset the tree count to
7074 * ensure that the exception handler can add the item. */
7075 THROW_MESSAGE(DissectorError,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7076 wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7077 "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7078 hfinfo->abbrev, PROTO_TREE_MAX_IDLE))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
;
7079 }
7080 } else {
7081 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7082 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7083 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7084 }
7085 }
7086 fi->length = item_length;
7087 fi->tree_type = -1;
7088 fi->flags = 0;
7089 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7090 /* If the tree is not visible, set the item hidden, unless we
7091 * need the representation or length and can't fake them.
7092 */
7093 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7094 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7095 }
7096 }
7097 fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7098 fi->rep = NULL((void*)0);
7099
7100 fi->appendix_start = 0;
7101 fi->appendix_length = 0;
7102
7103 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7104 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7105
7106 return fi;
7107}
7108
7109static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7110{
7111 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7112 return 0;
7113 }
7114
7115 /* Search for field name */
7116 char *ptr = strstr(representation, hfinfo->name);
7117 if (!ptr) {
7118 return 0;
7119 }
7120
7121 /* Check if field name ends with the ": " delimiter */
7122 ptr += strlen(hfinfo->name);
7123 if (strncmp(ptr, ": ", 2) == 0) {
7124 ptr += 2;
7125 }
7126
7127 /* Return offset to after field name */
7128 return ptr - representation;
7129}
7130
7131static size_t label_find_name_pos(const item_label_t *rep)
7132{
7133 size_t name_pos = 0;
7134
7135 /* If the value_pos is too small or too large, we can't find the expected format */
7136 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7137 return 0;
7138 }
7139
7140 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7141 if (rep->representation[rep->value_pos-2] == ':') {
7142 name_pos = rep->value_pos - 2;
7143 }
7144
7145 return name_pos;
7146}
7147
7148/* If the protocol tree is to be visible, set the representation of a
7149 proto_tree entry with the name of the field for the item and with
7150 the value formatted with the supplied printf-style format and
7151 argument list. */
7152static void
7153proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7154{
7155 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7155, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7156
7157 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7158 * items string representation */
7159 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7160 size_t name_pos, ret = 0;
7161 char *str;
7162 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7163 const header_field_info *hf;
7164
7165 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7165, "fi"))))
;
7166
7167 hf = fi->hfinfo;
7168
7169 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;
;
7170 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))
)) {
7171 uint64_t val;
7172 char *p;
7173
7174 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)
)
7175 val = fvalue_get_uinteger(fi->value);
7176 else
7177 val = fvalue_get_uinteger64(fi->value);
7178
7179 val <<= hfinfo_bitshift(hf);
7180
7181 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7182 ret = (p - fi->rep->representation);
7183 }
7184
7185 /* put in the hf name */
7186 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)
;
7187
7188 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7189 /* If possible, Put in the value of the string */
7190 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7191 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"
, 7191, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7192 fi->rep->value_pos = ret;
7193 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7194 if (ret >= ITEM_LABEL_LENGTH240) {
7195 /* Uh oh, we don't have enough room. Tell the user
7196 * that the field is truncated.
7197 */
7198 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7199 }
7200 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7201 }
7202}
7203
7204/* If the protocol tree is to be visible, set the representation of a
7205 proto_tree entry with the representation formatted with the supplied
7206 printf-style format and argument list. */
7207static void
7208proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7209{
7210 size_t ret; /*tmp return value */
7211 char *str;
7212 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7213
7214 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7214, "fi"))))
;
7215
7216 if (!proto_item_is_hidden(pi)) {
7217 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;
;
7218
7219 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7220 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"
, 7220, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7221 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7222 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7223 if (ret >= ITEM_LABEL_LENGTH240) {
7224 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7225 size_t name_pos = label_find_name_pos(fi->rep);
7226 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7227 }
7228 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7229 }
7230}
7231
7232static int
7233proto_strlcpy(char *dest, const char *src, size_t dest_size)
7234{
7235 if (dest_size == 0) return 0;
7236
7237 size_t res = g_strlcpy(dest, src, dest_size);
7238
7239 /* At most dest_size - 1 characters will be copied
7240 * (unless dest_size is 0). */
7241 if (res >= dest_size)
7242 res = dest_size - 1;
7243 return (int) res;
7244}
7245
7246static header_field_info *
7247hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7248{
7249 header_field_info *dup_hfinfo;
7250
7251 if (hfinfo->same_name_prev_id == -1)
7252 return NULL((void*)0);
7253 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", 7253
, __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", 7253, "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", 7253,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7254 return dup_hfinfo;
7255}
7256
7257static void
7258hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7259{
7260 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
7261 last_field_name = NULL((void*)0);
7262
7263 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7264 /* No hfinfo with the same name */
7265 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7266 return;
7267 }
7268
7269 if (hfinfo->same_name_next) {
7270 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7271 }
7272
7273 if (hfinfo->same_name_prev_id != -1) {
7274 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7275 same_name_prev->same_name_next = hfinfo->same_name_next;
7276 if (!hfinfo->same_name_next) {
7277 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7278 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7279 }
7280 }
7281}
7282
7283int
7284proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7285{
7286 const header_field_info *hfinfo = finfo->hfinfo;
7287 int label_len = 0;
7288 char *tmp_str;
7289 const char *str;
7290 const uint8_t *bytes;
7291 uint32_t number;
7292 uint64_t number64;
7293 const char *hf_str_val;
7294 char number_buf[NUMBER_LABEL_LENGTH80];
7295 const char *number_out;
7296 address addr;
7297 const ipv4_addr_and_mask *ipv4;
7298 const ipv6_addr_and_prefix *ipv6;
7299
7300 switch (hfinfo->type) {
7301
7302 case FT_NONE:
7303 case FT_PROTOCOL:
7304 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7305
7306 case FT_UINT_BYTES:
7307 case FT_BYTES:
7308 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7309 hfinfo,
7310 fvalue_get_bytes_data(finfo->value),
7311 (unsigned)fvalue_length2(finfo->value),
7312 label_str_size);
7313 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7314 wmem_free(NULL((void*)0), tmp_str);
7315 break;
7316
7317 case FT_ABSOLUTE_TIME:
7318 {
7319 const nstime_t *value = fvalue_get_time(finfo->value);
7320 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7321 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7322 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7323 }
7324 if (hfinfo->strings) {
7325 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7326 if (time_string != NULL((void*)0)) {
7327 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7328 break;
7329 }
7330 }
7331 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7332 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7333 wmem_free(NULL((void*)0), tmp_str);
7334 break;
7335 }
7336
7337 case FT_RELATIVE_TIME:
7338 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7339 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7340 wmem_free(NULL((void*)0), tmp_str);
7341 break;
7342
7343 case FT_BOOLEAN:
7344 number64 = fvalue_get_uinteger64(finfo->value);
7345 label_len = proto_strlcpy(display_label_str,
7346 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7347 break;
7348
7349 case FT_CHAR:
7350 number = fvalue_get_uinteger(finfo->value);
7351
7352 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7353 char tmp[ITEM_LABEL_LENGTH240];
7354 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7355
7356 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7356, "fmtfunc"))))
;
7357 fmtfunc(tmp, number);
7358
7359 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7360
7361 } else if (hfinfo->strings) {
7362 number_out = hf_try_val_to_str(number, hfinfo);
7363
7364 if (!number_out) {
7365 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7366 }
7367
7368 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7369
7370 } else {
7371 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7372
7373 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7374 }
7375
7376 break;
7377
7378 /* XXX - make these just FT_NUMBER? */
7379 case FT_INT8:
7380 case FT_INT16:
7381 case FT_INT24:
7382 case FT_INT32:
7383 case FT_UINT8:
7384 case FT_UINT16:
7385 case FT_UINT24:
7386 case FT_UINT32:
7387 case FT_FRAMENUM:
7388 hf_str_val = NULL((void*)0);
7389 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
))
?
7390 (uint32_t) fvalue_get_sinteger(finfo->value) :
7391 fvalue_get_uinteger(finfo->value);
7392
7393 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7394 char tmp[ITEM_LABEL_LENGTH240];
7395 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7396
7397 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7397, "fmtfunc"))))
;
7398 fmtfunc(tmp, number);
7399
7400 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7401
7402 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7403 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7404 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7405 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7406 hf_str_val = hf_try_val_to_str(number, hfinfo);
7407 if (hf_str_val)
7408 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7409 } else {
7410 number_out = hf_try_val_to_str(number, hfinfo);
7411
7412 if (!number_out) {
7413 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7414 }
7415
7416 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7417 }
7418 } else {
7419 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7420
7421 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7422 }
7423
7424 break;
7425
7426 case FT_INT40:
7427 case FT_INT48:
7428 case FT_INT56:
7429 case FT_INT64:
7430 case FT_UINT40:
7431 case FT_UINT48:
7432 case FT_UINT56:
7433 case FT_UINT64:
7434 hf_str_val = NULL((void*)0);
7435 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
))
?
7436 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7437 fvalue_get_uinteger64(finfo->value);
7438
7439 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7440 char tmp[ITEM_LABEL_LENGTH240];
7441 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7442
7443 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7443, "fmtfunc64"
))))
;
7444 fmtfunc64(tmp, number64);
7445
7446 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7447 } else if (hfinfo->strings) {
7448 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7449 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7450 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7451 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7452 if (hf_str_val)
7453 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7454 } else {
7455 number_out = hf_try_val64_to_str(number64, hfinfo);
7456
7457 if (!number_out)
7458 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7459
7460 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7461 }
7462 } else {
7463 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7464
7465 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7466 }
7467
7468 break;
7469
7470 case FT_EUI64:
7471 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7472 tmp_str = address_to_display(NULL((void*)0), &addr);
7473 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7474 wmem_free(NULL((void*)0), tmp_str);
7475 break;
7476
7477 case FT_IPv4:
7478 ipv4 = fvalue_get_ipv4(finfo->value);
7479 //XXX: Should we ignore the mask?
7480 set_address_ipv4(&addr, ipv4);
7481 tmp_str = address_to_display(NULL((void*)0), &addr);
7482 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7483 wmem_free(NULL((void*)0), tmp_str);
7484 free_address(&addr);
7485 break;
7486
7487 case FT_IPv6:
7488 ipv6 = fvalue_get_ipv6(finfo->value);
7489 set_address_ipv6(&addr, ipv6);
7490 tmp_str = address_to_display(NULL((void*)0), &addr);
7491 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7492 wmem_free(NULL((void*)0), tmp_str);
7493 free_address(&addr);
7494 break;
7495
7496 case FT_FCWWN:
7497 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7498 tmp_str = address_to_display(NULL((void*)0), &addr);
7499 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7500 wmem_free(NULL((void*)0), tmp_str);
7501 break;
7502
7503 case FT_ETHER:
7504 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7505 tmp_str = address_to_display(NULL((void*)0), &addr);
7506 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7507 wmem_free(NULL((void*)0), tmp_str);
7508 break;
7509
7510 case FT_GUID:
7511 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7512 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7513 wmem_free(NULL((void*)0), tmp_str);
7514 break;
7515
7516 case FT_REL_OID:
7517 bytes = fvalue_get_bytes_data(finfo->value);
7518 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7519 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7520 wmem_free(NULL((void*)0), tmp_str);
7521 break;
7522
7523 case FT_OID:
7524 bytes = fvalue_get_bytes_data(finfo->value);
7525 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7526 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7527 wmem_free(NULL((void*)0), tmp_str);
7528 break;
7529
7530 case FT_SYSTEM_ID:
7531 bytes = fvalue_get_bytes_data(finfo->value);
7532 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7533 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7534 wmem_free(NULL((void*)0), tmp_str);
7535 break;
7536
7537 case FT_FLOAT:
7538 case FT_DOUBLE:
7539 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7540 break;
7541
7542 case FT_IEEE_11073_SFLOAT:
7543 case FT_IEEE_11073_FLOAT:
7544 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7545 break;
7546
7547 case FT_STRING:
7548 case FT_STRINGZ:
7549 case FT_UINT_STRING:
7550 case FT_STRINGZPAD:
7551 case FT_STRINGZTRUNC:
7552 str = fvalue_get_string(finfo->value);
7553 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7554 if (label_len >= label_str_size) {
7555 /* Truncation occurred. Get the real length
7556 * copied (not including '\0') */
7557 label_len = label_str_size ? label_str_size - 1 : 0;
7558 }
7559 break;
7560
7561 default:
7562 /* First try ftype string representation */
7563 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7564 if (!tmp_str) {
7565 /* Default to show as bytes */
7566 bytes = fvalue_get_bytes_data(finfo->value);
7567 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7568 }
7569 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7570 wmem_free(NULL((void*)0), tmp_str);
7571 break;
7572 }
7573 return label_len;
7574}
7575
7576const char *
7577proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7578 char *result, char *expr, const int size)
7579{
7580 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7581 GPtrArray *finfos;
7582 field_info *finfo = NULL((void*)0);
7583 header_field_info* hfinfo;
7584 const char *abbrev = NULL((void*)0);
7585
7586 char *str;
7587 col_custom_t *field_idx;
7588 int field_id;
7589 int ii = 0;
7590
7591 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7591, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7592 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7593 field_id = field_idx->field_id;
7594 if (field_id == 0) {
7595 GPtrArray *fvals = NULL((void*)0);
7596 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7597 if (fvals != NULL((void*)0)) {
7598
7599 // XXX - Handling occurrences is unusual when more
7600 // than one field is involved, e.g. there's four
7601 // results for tcp.port + tcp.port. We may really
7602 // want to apply it to the operands, not the output.
7603 // Note that occurrences are not quite the same as
7604 // the layer operator (should the grammar support
7605 // both?)
7606 /* Calculate single index or set outer boundaries */
7607 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7608 if (occurrence < 0) {
7609 i = occurrence + len;
7610 last = i;
7611 } else if (occurrence > 0) {
7612 i = occurrence - 1;
7613 last = i;
7614 } else {
7615 i = 0;
7616 last = len - 1;
7617 }
7618 if (i < 0 || i >= len) {
7619 g_ptr_array_unref(fvals);
7620 continue;
7621 }
7622 for (; i <= last; i++) {
7623 /* XXX - We could have a "resolved" result
7624 * for types where the value depends only
7625 * on the type, e.g. FT_IPv4, and not on
7626 * hfinfo->strings. Supporting the latter
7627 * requires knowing which hfinfo matched
7628 * if there are multiple with the same
7629 * abbreviation. In any case, we need to
7630 * know the expected return type of the
7631 * field expression.
7632 */
7633 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7634 if (offset_r && (offset_r < (size - 1)))
7635 result[offset_r++] = ',';
7636 if (offset_e && (offset_e < (size - 1)))
7637 expr[offset_e++] = ',';
7638 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7639 // col_{add,append,set}_* calls ws_label_strcpy
7640 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7641
7642 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7643 }
7644 g_ptr_array_unref(fvals);
7645 } else if (passed) {
7646 // XXX - Occurrence doesn't make sense for a test
7647 // output, it should be applied to the operands.
7648 if (offset_r && (offset_r < (size - 1)))
7649 result[offset_r++] = ',';
7650 if (offset_e && (offset_e < (size - 1)))
7651 expr[offset_e++] = ',';
7652 /* Prevent multiple check marks */
7653 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7654 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7655 } else {
7656 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7657 }
7658 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7659 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7660 } else {
7661 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7662 }
7663 }
7664 continue;
7665 }
7666 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", 7666
, __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", 7666,
"(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", 7666,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7667
7668 /* do we need to rewind ? */
7669 if (!hfinfo)
7670 return "";
7671
7672 if (occurrence < 0) {
7673 /* Search other direction */
7674 while (hfinfo->same_name_prev_id != -1) {
7675 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", 7675
, __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", 7675, "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", 7675,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7676 }
7677 }
7678
7679 prev_len = 0; /* Reset handled occurrences */
7680
7681 while (hfinfo) {
7682 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7683
7684 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7685 if (occurrence < 0) {
7686 hfinfo = hfinfo->same_name_next;
7687 } else {
7688 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7689 }
7690 continue;
7691 }
7692
7693 /* Are there enough occurrences of the field? */
7694 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7695 if (occurrence < 0) {
7696 hfinfo = hfinfo->same_name_next;
7697 } else {
7698 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7699 }
7700 prev_len += len;
7701 continue;
7702 }
7703
7704 /* Calculate single index or set outer boundaries */
7705 if (occurrence < 0) {
7706 i = occurrence + len + prev_len;
7707 last = i;
7708 } else if (occurrence > 0) {
7709 i = occurrence - 1 - prev_len;
7710 last = i;
7711 } else {
7712 i = 0;
7713 last = len - 1;
7714 }
7715
7716 prev_len += len; /* Count handled occurrences */
7717
7718 while (i <= last) {
7719 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7720
7721 if (offset_r && (offset_r < (size - 1)))
7722 result[offset_r++] = ',';
7723
7724 if (display_details) {
7725 char representation[ITEM_LABEL_LENGTH240];
7726 size_t offset = 0;
7727
7728 if (finfo->rep && finfo->rep->value_len) {
7729 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7730 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7731 } else {
7732 proto_item_fill_label(finfo, representation, &offset);
7733 }
7734 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7735 } else {
7736 switch (hfinfo->type) {
7737
7738 case FT_NONE:
7739 case FT_PROTOCOL:
7740 /* Prevent multiple check marks */
7741 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7742 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7743 } else {
7744 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7745 }
7746 break;
7747
7748 default:
7749 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7750 break;
7751 }
7752 }
7753
7754 if (offset_e && (offset_e < (size - 1)))
7755 expr[offset_e++] = ',';
7756
7757 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
))
)) {
7758 const char *hf_str_val;
7759 /* Integer types with BASE_NONE never get the numeric value. */
7760 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7761 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7762 } 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
)
) {
7763 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7764 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7765 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7766 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7767 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7768 }
7769 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7770 offset_e = (int)strlen(expr);
7771 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7772 /* Prevent multiple check marks */
7773 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7774 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7775 } else {
7776 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7777 }
7778 } else {
7779 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7780 // col_{add,append,set}_* calls ws_label_strcpy
7781 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7782 wmem_free(NULL((void*)0), str);
7783 }
7784 i++;
7785 }
7786
7787 /* XXX: Why is only the first abbreviation returned for a multifield
7788 * custom column? */
7789 if (!abbrev) {
7790 /* Store abbrev for return value */
7791 abbrev = hfinfo->abbrev;
7792 }
7793
7794 if (occurrence == 0) {
7795 /* Fetch next hfinfo with same name (abbrev) */
7796 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7797 } else {
7798 hfinfo = NULL((void*)0);
7799 }
7800 }
7801 }
7802
7803 if (offset_r >= (size - 1)) {
7804 mark_truncated(result, 0, size, NULL((void*)0));
7805 }
7806 if (offset_e >= (size - 1)) {
7807 mark_truncated(expr, 0, size, NULL((void*)0));
7808 }
7809 return abbrev ? abbrev : "";
7810}
7811
7812char *
7813proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7814{
7815 int len, prev_len, last, i;
7816 GPtrArray *finfos;
7817 field_info *finfo = NULL((void*)0);
7818 header_field_info* hfinfo;
7819
7820 char *filter = NULL((void*)0);
7821 GPtrArray *filter_array;
7822
7823 col_custom_t *col_custom;
7824 int field_id;
7825
7826 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7826, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7827 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7828 for (GSList *iter = field_ids; iter; iter = iter->next) {
7829 col_custom = (col_custom_t*)iter->data;
7830 field_id = col_custom->field_id;
7831 if (field_id == 0) {
7832 GPtrArray *fvals = NULL((void*)0);
7833 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7834 if (fvals != NULL((void*)0)) {
7835 // XXX - Handling occurrences is unusual when more
7836 // than one field is involved, e.g. there's four
7837 // results for tcp.port + tcp.port. We really
7838 // want to apply it to the operands, not the output.
7839 /* Calculate single index or set outer boundaries */
7840 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7841 if (occurrence < 0) {
7842 i = occurrence + len;
7843 last = i;
7844 } else if (occurrence > 0) {
7845 i = occurrence - 1;
7846 last = i;
7847 } else {
7848 i = 0;
7849 last = len - 1;
7850 }
7851 if (i < 0 || i >= len) {
7852 g_ptr_array_unref(fvals);
7853 continue;
7854 }
7855 for (; i <= last; i++) {
7856 /* XXX - Should multiple values for one
7857 * field use set membership to reduce
7858 * verbosity, here and below? */
7859 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7860 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7861 wmem_free(NULL((void*)0), str);
7862 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7863 g_ptr_array_add(filter_array, filter);
7864 }
7865 }
7866 g_ptr_array_unref(fvals);
7867 } else if (passed) {
7868 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7869 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7870 g_ptr_array_add(filter_array, filter);
7871 }
7872 } else {
7873 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7874 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7875 g_ptr_array_add(filter_array, filter);
7876 }
7877 }
7878 continue;
7879 }
7880
7881 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", 7881
, __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", 7881,
"(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", 7881,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7882
7883 /* do we need to rewind ? */
7884 if (!hfinfo)
7885 return NULL((void*)0);
7886
7887 if (occurrence < 0) {
7888 /* Search other direction */
7889 while (hfinfo->same_name_prev_id != -1) {
7890 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", 7890
, __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", 7890, "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", 7890,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7891 }
7892 }
7893
7894 prev_len = 0; /* Reset handled occurrences */
7895
7896 while (hfinfo) {
7897 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7898
7899 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7900 if (occurrence < 0) {
7901 hfinfo = hfinfo->same_name_next;
7902 } else {
7903 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7904 }
7905 continue;
7906 }
7907
7908 /* Are there enough occurrences of the field? */
7909 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7910 if (occurrence < 0) {
7911 hfinfo = hfinfo->same_name_next;
7912 } else {
7913 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7914 }
7915 prev_len += len;
7916 continue;
7917 }
7918
7919 /* Calculate single index or set outer boundaries */
7920 if (occurrence < 0) {
7921 i = occurrence + len + prev_len;
7922 last = i;
7923 } else if (occurrence > 0) {
7924 i = occurrence - 1 - prev_len;
7925 last = i;
7926 } else {
7927 i = 0;
7928 last = len - 1;
7929 }
7930
7931 prev_len += len; /* Count handled occurrences */
7932
7933 while (i <= last) {
7934 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7935
7936 filter = proto_construct_match_selected_string(finfo, edt);
7937 if (filter) {
7938 /* Only add the same expression once (especially for FT_PROTOCOL).
7939 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7940 */
7941 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7942 g_ptr_array_add(filter_array, filter);
7943 }
7944 }
7945 i++;
7946 }
7947
7948 if (occurrence == 0) {
7949 /* Fetch next hfinfo with same name (abbrev) */
7950 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7951 } else {
7952 hfinfo = NULL((void*)0);
7953 }
7954 }
7955 }
7956
7957 g_ptr_array_add(filter_array, NULL((void*)0));
7958
7959 /* XXX: Should this be || or && ? */
7960 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7961
7962 g_ptr_array_free(filter_array, true1);
7963
7964 return output;
7965}
7966
7967/* Set text of proto_item after having already been created. */
7968void
7969proto_item_set_text(proto_item *pi, const char *format, ...)
7970{
7971 field_info *fi = NULL((void*)0);
7972 va_list ap;
7973
7974 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7975
7976 fi = PITEM_FINFO(pi)((pi)->finfo);
7977 if (fi == NULL((void*)0))
7978 return;
7979
7980 if (fi->rep) {
7981 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7982 fi->rep = NULL((void*)0);
7983 }
7984
7985 va_start(ap, format)__builtin_va_start(ap, format);
7986 proto_tree_set_representation(pi, format, ap);
7987 va_end(ap)__builtin_va_end(ap);
7988}
7989
7990/* Append to text of proto_item after having already been created. */
7991void
7992proto_item_append_text(proto_item *pi, const char *format, ...)
7993{
7994 field_info *fi = NULL((void*)0);
7995 size_t curlen;
7996 char *str;
7997 va_list ap;
7998
7999 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8000
8001 fi = PITEM_FINFO(pi)((pi)->finfo);
8002 if (fi == NULL((void*)0)) {
8003 return;
8004 }
8005
8006 if (!proto_item_is_hidden(pi)) {
8007 /*
8008 * If we don't already have a representation,
8009 * generate the default representation.
8010 */
8011 if (fi->rep == NULL((void*)0)) {
8012 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;
;
8013 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8014 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8015 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8016 (strncmp(format, ": ", 2) == 0)) {
8017 fi->rep->value_pos += 2;
8018 }
8019 }
8020 if (fi->rep) {
8021 curlen = strlen(fi->rep->representation);
8022 /* curlen doesn't include the \0 byte.
8023 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8024 * the representation has already been truncated (of an up
8025 * to 4 byte UTF-8 character) or is just at the maximum length
8026 * unless we search for " [truncated]" (which may not be
8027 * at the start.)
8028 * It's safer to do nothing.
8029 */
8030 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8031 va_start(ap, format)__builtin_va_start(ap, format);
8032 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8033 va_end(ap)__builtin_va_end(ap);
8034 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"
, 8034, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8035 /* Keep fi->rep->value_pos */
8036 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8037 if (curlen >= ITEM_LABEL_LENGTH240) {
8038 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8039 size_t name_pos = label_find_name_pos(fi->rep);
8040 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8041 }
8042 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8043 }
8044 }
8045 }
8046}
8047
8048/* Prepend to text of proto_item after having already been created. */
8049void
8050proto_item_prepend_text(proto_item *pi, const char *format, ...)
8051{
8052 field_info *fi = NULL((void*)0);
8053 size_t pos;
8054 char representation[ITEM_LABEL_LENGTH240];
8055 char *str;
8056 va_list ap;
8057
8058 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8059
8060 fi = PITEM_FINFO(pi)((pi)->finfo);
8061 if (fi == NULL((void*)0)) {
8062 return;
8063 }
8064
8065 if (!proto_item_is_hidden(pi)) {
8066 /*
8067 * If we don't already have a representation,
8068 * generate the default representation.
8069 */
8070 if (fi->rep == NULL((void*)0)) {
8071 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;
;
8072 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8073 } else
8074 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8075
8076 va_start(ap, format)__builtin_va_start(ap, format);
8077 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8078 va_end(ap)__builtin_va_end(ap);
8079 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"
, 8079, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8080 fi->rep->value_pos += strlen(str);
8081 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8082 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8083 /* XXX: As above, if the old representation is close to the label
8084 * length, it might already be marked as truncated. */
8085 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8086 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8087 size_t name_pos = label_find_name_pos(fi->rep);
8088 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8089 }
8090 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8091 }
8092}
8093
8094static void
8095finfo_set_len(field_info *fi, const unsigned length)
8096{
8097 unsigned length_remaining;
8098
8099 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8100 if (length > length_remaining)
8101 fi->length = length_remaining;
8102 else
8103 fi->length = length;
8104
8105 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8106 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8107 fvalue_set_protocol_length(fi->value, fi->length);
8108 }
8109
8110 /*
8111 * You cannot just make the "len" field of a GByteArray
8112 * larger, if there's no data to back that length;
8113 * you can only make it smaller.
8114 */
8115 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8116 GBytes *bytes = fvalue_get_bytes(fi->value);
8117 size_t size;
8118 const void *data = g_bytes_get_data(bytes, &size);
8119 if ((size_t)fi->length <= size) {
8120 fvalue_set_bytes_data(fi->value, data, fi->length);
8121 }
8122 g_bytes_unref(bytes);
8123 }
8124}
8125
8126void
8127proto_item_set_len(proto_item *pi, const unsigned length)
8128{
8129 field_info *fi;
8130
8131 if (pi == NULL((void*)0))
8132 return;
8133
8134 fi = PITEM_FINFO(pi)((pi)->finfo);
8135 if (fi == NULL((void*)0))
8136 return;
8137
8138 finfo_set_len(fi, length);
8139}
8140
8141/*
8142 * Sets the length of the item based on its start and on the specified
8143 * offset, which is the offset past the end of the item; as the start
8144 * in the item is relative to the beginning of the data source tvbuff,
8145 * we need to pass in a tvbuff - the end offset is relative to the beginning
8146 * of that tvbuff.
8147 */
8148void
8149proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8150{
8151 field_info *fi;
8152 unsigned length;
8153
8154 if (pi == NULL((void*)0))
8155 return;
8156
8157 fi = PITEM_FINFO(pi)((pi)->finfo);
8158 if (fi == NULL((void*)0))
8159 return;
8160
8161 if (G_LIKELY(tvb)(tvb)) {
8162 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8162, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8163 end += tvb_raw_offset(tvb);
8164 } else {
8165 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8165, "((void*)0) == fi->ds_tvb"
))))
;
8166 }
8167 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8167, "end >= fi->start"
))))
;
8168 length = end - fi->start;
8169
8170 finfo_set_len(fi, length);
8171}
8172
8173unsigned
8174proto_item_get_len(const proto_item *pi)
8175{
8176 /* XXX - The only use case where this is really guaranteed to work is
8177 * increasing the length of an item (which has no effect if the item
8178 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8179 *
8180 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8181 *
8182 * Should there be a macro or function to do that, and possibly this
8183 * be deprecated? As a bonus, we could handle overflow.
8184 */
8185 field_info *fi;
8186
8187 if (!pi)
8188 return 0;
8189 fi = PITEM_FINFO(pi)((pi)->finfo);
8190 if (fi) {
8191 return fi->length;
8192 }
8193 return 0;
8194}
8195
8196void
8197proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8198 if (!ti) {
8199 return;
8200 }
8201 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)
;
8202 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)
;
8203}
8204
8205char *
8206proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8207{
8208 field_info *fi;
8209
8210 if (!pi)
8211 return wmem_strdup(scope, "");
8212 fi = PITEM_FINFO(pi)((pi)->finfo);
8213 if (!fi)
8214 return wmem_strdup(scope, "");
8215 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8215, "fi->hfinfo != ((void*)0)"
))))
;
8216 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8217}
8218
8219proto_tree *
8220proto_tree_create_root(packet_info *pinfo)
8221{
8222 proto_node *pnode;
8223
8224 /* Initialize the proto_node */
8225 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8226 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8227 pnode->parent = NULL((void*)0);
8228 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8229 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc ((sizeof (tree_data_t) > 0 ?
sizeof (tree_data_t) : 1)))
;
8230
8231 /* Make sure we can access pinfo everywhere */
8232 pnode->tree_data->pinfo = pinfo;
8233
8234 /* Don't initialize the tree_data_t. Wait until we know we need it */
8235 pnode->tree_data->interesting_hfids = NULL((void*)0);
8236
8237 /* Set the default to false so it's easier to
8238 * find errors; if we expect to see the protocol tree
8239 * but for some reason the default 'visible' is not
8240 * changed, then we'll find out very quickly. */
8241 pnode->tree_data->visible = false0;
8242
8243 /* Make sure that we fake protocols (if possible) */
8244 pnode->tree_data->fake_protocols = true1;
8245
8246 /* Keep track of the number of children */
8247 pnode->tree_data->count = 0;
8248
8249 /* Initialize our loop checks */
8250 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8251 pnode->tree_data->max_start = 0;
8252 pnode->tree_data->start_idle_count = 0;
8253
8254 return (proto_tree *)pnode;
8255}
8256
8257
8258/* "prime" a proto_tree with a single hfid that a dfilter
8259 * is interested in. */
8260void
8261proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8262{
8263 header_field_info *hfinfo;
8264
8265 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", 8265, __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", 8265, "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", 8265, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8266 /* this field is referenced by a filter so increase the refcount.
8267 also increase the refcount for the parent, i.e the protocol.
8268 Don't increase the refcount if we're already printing the
8269 type, as that is a superset of direct reference.
8270 */
8271 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8272 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8273 }
8274 /* only increase the refcount if there is a parent.
8275 if this is a protocol and not a field then parent will be -1
8276 and there is no parent to add any refcounting for.
8277 */
8278 if (hfinfo->parent != -1) {
8279 header_field_info *parent_hfinfo;
8280 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", 8280
, __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", 8280,
"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", 8280,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8281
8282 /* Mark parent as indirectly referenced unless it is already directly
8283 * referenced, i.e. the user has specified the parent in a filter.
8284 */
8285 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8286 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8287 }
8288}
8289
8290/* "prime" a proto_tree with a single hfid that a dfilter
8291 * is interested in. */
8292void
8293proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8294{
8295 header_field_info *hfinfo;
8296
8297 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", 8297, __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", 8297, "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", 8297, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8298 /* this field is referenced by an (output) filter so increase the refcount.
8299 also increase the refcount for the parent, i.e the protocol.
8300 */
8301 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8302 /* only increase the refcount if there is a parent.
8303 if this is a protocol and not a field then parent will be -1
8304 and there is no parent to add any refcounting for.
8305 */
8306 if (hfinfo->parent != -1) {
8307 header_field_info *parent_hfinfo;
8308 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", 8308
, __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", 8308,
"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", 8308,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8309
8310 /* Mark parent as indirectly referenced unless it is already directly
8311 * referenced, i.e. the user has specified the parent in a filter.
8312 */
8313 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8314 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8315 }
8316}
8317
8318proto_tree *
8319proto_item_add_subtree(proto_item *pi, const int idx) {
8320 field_info *fi;
8321
8322 if (!pi)
8323 return NULL((void*)0);
8324
8325 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", 8325, "idx >= 0 && idx < num_tree_types"
))))
;
8326
8327 fi = PITEM_FINFO(pi)((pi)->finfo);
8328 if (!fi)
8329 return (proto_tree *)pi;
8330
8331 fi->tree_type = idx;
8332
8333 return (proto_tree *)pi;
8334}
8335
8336proto_tree *
8337proto_item_get_subtree(proto_item *pi) {
8338 field_info *fi;
8339
8340 if (!pi)
8341 return NULL((void*)0);
8342 fi = PITEM_FINFO(pi)((pi)->finfo);
8343 if ( (fi) && (fi->tree_type == -1) )
8344 return NULL((void*)0);
8345 return (proto_tree *)pi;
8346}
8347
8348proto_item *
8349proto_item_get_parent(const proto_item *ti) {
8350 if (!ti)
8351 return NULL((void*)0);
8352 return ti->parent;
8353}
8354
8355proto_item *
8356proto_item_get_parent_nth(proto_item *ti, int gen) {
8357 if (!ti)
8358 return NULL((void*)0);
8359 while (gen--) {
8360 ti = ti->parent;
8361 if (!ti)
8362 return NULL((void*)0);
8363 }
8364 return ti;
8365}
8366
8367
8368proto_item *
8369proto_tree_get_parent(proto_tree *tree) {
8370 if (!tree)
8371 return NULL((void*)0);
8372 return (proto_item *)tree;
8373}
8374
8375proto_tree *
8376proto_tree_get_parent_tree(proto_tree *tree) {
8377 if (!tree)
8378 return NULL((void*)0);
8379
8380 /* we're the root tree, there's no parent
8381 return ourselves so the caller has at least a tree to attach to */
8382 if (!tree->parent)
8383 return tree;
8384
8385 return (proto_tree *)tree->parent;
8386}
8387
8388proto_tree *
8389proto_tree_get_root(proto_tree *tree) {
8390 if (!tree)
8391 return NULL((void*)0);
8392 while (tree->parent) {
8393 tree = tree->parent;
8394 }
8395 return tree;
8396}
8397
8398void
8399proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8400 proto_item *item_to_move)
8401{
8402 /* This function doesn't generate any values. It only reorganizes the protocol tree
8403 * so we can bail out immediately if it isn't visible. */
8404 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8405 return;
8406
8407 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", 8407, "item_to_move->parent == tree"
))))
;
8408 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", 8408, "fixed_item->parent == tree"
))))
;
8409
8410 /*** cut item_to_move out ***/
8411
8412 /* is item_to_move the first? */
8413 if (tree->first_child == item_to_move) {
8414 /* simply change first child to next */
8415 tree->first_child = item_to_move->next;
8416
8417 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", 8417, "tree->last_child != item_to_move"
))))
;
8418 } else {
8419 proto_item *curr_item;
8420 /* find previous and change it's next */
8421 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8422 if (curr_item->next == item_to_move) {
8423 break;
8424 }
8425 }
8426
8427 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8427, "curr_item"
))))
;
8428
8429 curr_item->next = item_to_move->next;
8430
8431 /* fix last_child if required */
8432 if (tree->last_child == item_to_move) {
8433 tree->last_child = curr_item;
8434 }
8435 }
8436
8437 /*** insert to_move after fixed ***/
8438 item_to_move->next = fixed_item->next;
8439 fixed_item->next = item_to_move;
8440 if (tree->last_child == fixed_item) {
8441 tree->last_child = item_to_move;
8442 }
8443}
8444
8445void
8446proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8447 const unsigned length)
8448{
8449 field_info *fi;
8450
8451 if (tree == NULL((void*)0))
8452 return;
8453
8454 fi = PTREE_FINFO(tree)((tree)->finfo);
8455 if (fi == NULL((void*)0))
8456 return;
8457
8458 /* We don't store a separate data source tvb for the appendix, so
8459 * it must be from the same data source. (XXX - Are there any
8460 * situations where it makes sense to have an appendix from a
8461 * different data source?) */
8462 if (G_LIKELY(tvb)(tvb)) {
8463 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8463, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8464 start += tvb_raw_offset(tvb);
8465 } else {
8466 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8466, "((void*)0) == fi->ds_tvb"
))))
;
8467 }
8468
8469 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8470 * main body? */
8471
8472 fi->appendix_start = start;
8473 fi->appendix_length = length;
8474}
8475
8476static void
8477check_protocol_filter_name_or_fail(const char *filter_name)
8478{
8479 /* Require at least two characters. */
8480 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8481 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)
;
8482 }
8483
8484 if (proto_check_field_name(filter_name) != '\0') {
8485 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)
8486 " 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)
8487 " 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)
;
8488 }
8489
8490 /* Check that it doesn't match some very common numeric forms. */
8491 if (filter_name[0] == '0' &&
8492 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8493 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8494 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])
8495 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])
;
8496 }
8497
8498 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8499
8500 /* Check that it contains at least one letter. */
8501 bool_Bool have_letter = false0;
8502 for (const char *s = filter_name; *s != '\0'; s++) {
8503 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8504 have_letter = true1;
8505 break;
8506 }
8507 }
8508 if (!have_letter) {
8509 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)
8510 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8511 }
8512
8513 /* Check for reserved keywords. */
8514 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8515 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)
8516 " 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)
;
8517 }
8518}
8519
8520int
8521proto_register_protocol(const char *name, const char *short_name,
8522 const char *filter_name)
8523{
8524 protocol_t *protocol;
8525 header_field_info *hfinfo;
8526
8527 check_protocol_filter_name_or_fail(filter_name);
8528
8529 /*
8530 * Add this protocol to the list of known protocols;
8531 * the list is sorted by protocol short name.
8532 */
8533 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8534 protocol->name = name;
8535 protocol->short_name = short_name;
8536 protocol->filter_name = filter_name;
8537 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8538 protocol->is_enabled = true1; /* protocol is enabled by default */
8539 protocol->enabled_by_default = true1; /* see previous comment */
8540 protocol->can_toggle = true1;
8541 protocol->parent_proto_id = -1;
8542 protocol->heur_list = NULL((void*)0);
8543
8544 /* List will be sorted later by name, when all protocols completed registering */
8545 protocols = g_list_prepend(protocols, protocol);
8546 /*
8547 * Make sure there's not already a protocol with any of those
8548 * names. Crash if there is, as that's an error in the code
8549 * or an inappropriate plugin.
8550 * This situation has to be fixed to not register more than one
8551 * protocol with the same name.
8552 */
8553 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8554 /* ws_error will terminate the program */
8555 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)
8556 " 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)
;
8557 }
8558 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8559 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)
8560 " 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)
;
8561 }
8562 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8563 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)
8564 " 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)
;
8565 }
8566
8567 /* Here we allocate a new header_field_info struct */
8568 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8569 hfinfo->name = name;
8570 hfinfo->abbrev = filter_name;
8571 hfinfo->type = FT_PROTOCOL;
8572 hfinfo->display = BASE_NONE;
8573 hfinfo->strings = protocol;
8574 hfinfo->bitmask = 0;
8575 hfinfo->ref_type = HF_REF_TYPE_NONE;
8576 hfinfo->blurb = NULL((void*)0);
8577 hfinfo->parent = -1; /* This field differentiates protos and fields */
8578
8579 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8580 return protocol->proto_id;
8581}
8582
8583int
8584proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8585{
8586 protocol_t *protocol;
8587 header_field_info *hfinfo;
8588
8589 /*
8590 * Helper protocols don't need the strict rules as a "regular" protocol
8591 * Just register it in a list and make a hf_ field from it
8592 */
8593 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8594 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)
;
8595 }
8596
8597 if (parent_proto <= 0) {
8598 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)
8599 " 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)
;
8600 }
8601
8602 check_protocol_filter_name_or_fail(filter_name);
8603
8604 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8605 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8606 protocol->name = name;
8607 protocol->short_name = short_name;
8608 protocol->filter_name = filter_name;
8609 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8610
8611 /* Enabling and toggling is really determined by parent protocol,
8612 but provide default values here */
8613 protocol->is_enabled = true1;
8614 protocol->enabled_by_default = true1;
8615 protocol->can_toggle = true1;
8616
8617 protocol->parent_proto_id = parent_proto;
8618 protocol->heur_list = NULL((void*)0);
8619
8620 /* List will be sorted later by name, when all protocols completed registering */
8621 protocols = g_list_prepend(protocols, protocol);
8622
8623 /* Here we allocate a new header_field_info struct */
8624 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8625 hfinfo->name = name;
8626 hfinfo->abbrev = filter_name;
8627 hfinfo->type = field_type;
8628 hfinfo->display = BASE_NONE;
8629 if (field_type == FT_BYTES) {
8630 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8631 }
8632 hfinfo->strings = protocol;
8633 hfinfo->bitmask = 0;
8634 hfinfo->ref_type = HF_REF_TYPE_NONE;
8635 hfinfo->blurb = NULL((void*)0);
8636 hfinfo->parent = -1; /* This field differentiates protos and fields */
8637
8638 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8639 return protocol->proto_id;
8640}
8641
8642bool_Bool
8643proto_deregister_protocol(const char *short_name)
8644{
8645 protocol_t *protocol;
8646 header_field_info *hfinfo;
8647 int proto_id;
8648 unsigned i;
8649
8650 proto_id = proto_get_id_by_short_name(short_name);
8651 protocol = find_protocol_by_id(proto_id);
8652 if (protocol == NULL((void*)0))
8653 return false0;
8654
8655 g_hash_table_remove(proto_names, protocol->name);
8656 g_hash_table_remove(proto_short_names, (void *)short_name);
8657 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8658
8659 if (protocol->fields) {
8660 for (i = 0; i < protocol->fields->len; i++) {
8661 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8662 hfinfo_remove_from_gpa_name_map(hfinfo);
8663 expert_deregister_expertinfo(hfinfo->abbrev);
8664 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8665 }
8666 g_ptr_array_free(protocol->fields, true1);
8667 protocol->fields = NULL((void*)0);
8668 }
8669
8670 g_list_free(protocol->heur_list);
8671
8672 /* Remove this protocol from the list of known protocols */
8673 protocols = g_list_remove(protocols, protocol);
8674
8675 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8676 wmem_map_remove(gpa_name_map, protocol->filter_name);
8677
8678 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
8679 last_field_name = NULL((void*)0);
8680
8681 return true1;
8682}
8683
8684void
8685proto_register_alias(const int proto_id, const char *alias_name)
8686{
8687 protocol_t *protocol;
8688
8689 protocol = find_protocol_by_id(proto_id);
8690 if (alias_name && protocol) {
8691 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8692 }
8693}
8694
8695/*
8696 * Routines to use to iterate over the protocols.
8697 * The argument passed to the iterator routines is an opaque cookie to
8698 * their callers; it's the GList pointer for the current element in
8699 * the list.
8700 * The ID of the protocol is returned, or -1 if there is no protocol.
8701 */
8702int
8703proto_get_first_protocol(void **cookie)
8704{
8705 protocol_t *protocol;
8706
8707 if (protocols == NULL((void*)0))
8708 return -1;
8709 *cookie = protocols;
8710 protocol = (protocol_t *)protocols->data;
8711 return protocol->proto_id;
8712}
8713
8714int
8715proto_get_data_protocol(void *cookie)
8716{
8717 GList *list_item = (GList *)cookie;
8718
8719 protocol_t *protocol = (protocol_t *)list_item->data;
8720 return protocol->proto_id;
8721}
8722
8723int
8724proto_get_next_protocol(void **cookie)
8725{
8726 GList *list_item = (GList *)*cookie;
8727 protocol_t *protocol;
8728
8729 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8730 if (list_item == NULL((void*)0))
8731 return -1;
8732 *cookie = list_item;
8733 protocol = (protocol_t *)list_item->data;
8734 return protocol->proto_id;
8735}
8736
8737header_field_info *
8738proto_get_first_protocol_field(const int proto_id, void **cookie)
8739{
8740 protocol_t *protocol = find_protocol_by_id(proto_id);
8741
8742 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8743 return NULL((void*)0);
8744
8745 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8746 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8747}
8748
8749header_field_info *
8750proto_get_next_protocol_field(const int proto_id, void **cookie)
8751{
8752 protocol_t *protocol = find_protocol_by_id(proto_id);
8753 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8754
8755 i++;
8756
8757 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8758 return NULL((void*)0);
8759
8760 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8761 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8762}
8763
8764protocol_t *
8765find_protocol_by_id(const int proto_id)
8766{
8767 header_field_info *hfinfo;
8768
8769 if (proto_id <= 0)
8770 return NULL((void*)0);
8771
8772 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", 8772, __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", 8772,
"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", 8772, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8773 if (hfinfo->type != FT_PROTOCOL) {
8774 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", 8774, "hfinfo->display & 0x00004000"
))))
;
8775 }
8776 return (protocol_t *)hfinfo->strings;
8777}
8778
8779int
8780proto_get_id(const protocol_t *protocol)
8781{
8782 return protocol->proto_id;
8783}
8784
8785bool_Bool
8786proto_name_already_registered(const char *name)
8787{
8788 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8788, "name", "No name present"))))
;
8789
8790 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8791 return true1;
8792 return false0;
8793}
8794
8795int
8796proto_get_id_by_filter_name(const char *filter_name)
8797{
8798 const protocol_t *protocol = NULL((void*)0);
8799
8800 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", 8800,
"filter_name", "No filter name present"))))
;
8801
8802 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8803
8804 if (protocol == NULL((void*)0))
8805 return -1;
8806 return protocol->proto_id;
8807}
8808
8809int
8810proto_get_id_by_short_name(const char *short_name)
8811{
8812 const protocol_t *protocol = NULL((void*)0);
8813
8814 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", 8814,
"short_name", "No short name present"))))
;
8815
8816 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8817
8818 if (protocol == NULL((void*)0))
8819 return -1;
8820 return protocol->proto_id;
8821}
8822
8823const char *
8824proto_get_protocol_name(const int proto_id)
8825{
8826 protocol_t *protocol;
8827
8828 protocol = find_protocol_by_id(proto_id);
8829
8830 if (protocol == NULL((void*)0))
8831 return NULL((void*)0);
8832 return protocol->name;
8833}
8834
8835const char *
8836proto_get_protocol_short_name(const protocol_t *protocol)
8837{
8838 if (protocol == NULL((void*)0))
8839 return "(none)";
8840 return protocol->short_name;
8841}
8842
8843const char *
8844proto_get_protocol_long_name(const protocol_t *protocol)
8845{
8846 if (protocol == NULL((void*)0))
8847 return "(none)";
8848 return protocol->name;
8849}
8850
8851const char *
8852proto_get_protocol_filter_name(const int proto_id)
8853{
8854 protocol_t *protocol;
8855
8856 protocol = find_protocol_by_id(proto_id);
8857 if (protocol == NULL((void*)0))
8858 return "(none)";
8859 return protocol->filter_name;
8860}
8861
8862void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8863{
8864 heur_dtbl_entry_t* heuristic_dissector;
8865
8866 if (protocol == NULL((void*)0))
8867 return;
8868
8869 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8870 if (heuristic_dissector != NULL((void*)0))
8871 {
8872 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8873 }
8874}
8875
8876void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8877{
8878 if (protocol == NULL((void*)0))
8879 return;
8880
8881 g_list_foreach(protocol->heur_list, func, user_data);
8882}
8883
8884void
8885proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8886 bool_Bool *is_tcp, bool_Bool *is_udp,
8887 bool_Bool *is_sctp, bool_Bool *is_tls,
8888 bool_Bool *is_rtp,
8889 bool_Bool *is_lte_rlc)
8890{
8891 wmem_list_frame_t *protos = wmem_list_head(layers);
8892 int proto_id;
8893 const char *proto_name;
8894
8895 /* Walk the list of a available protocols in the packet and
8896 attempt to find "major" ones. */
8897 /* It might make more sense to assemble and return a bitfield. */
8898 while (protos != NULL((void*)0))
8899 {
8900 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8901 proto_name = proto_get_protocol_filter_name(proto_id);
8902
8903 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8904 (!strcmp(proto_name, "ipv6")))) {
8905 *is_ip = true1;
8906 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8907 *is_tcp = true1;
8908 } else if (is_udp && !strcmp(proto_name, "udp")) {
8909 *is_udp = true1;
8910 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8911 *is_sctp = true1;
8912 } else if (is_tls && !strcmp(proto_name, "tls")) {
8913 *is_tls = true1;
8914 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8915 *is_rtp = true1;
8916 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8917 *is_lte_rlc = true1;
8918 }
8919
8920 protos = wmem_list_frame_next(protos);
8921 }
8922}
8923
8924bool_Bool
8925proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8926{
8927 wmem_list_frame_t *protos = wmem_list_head(layers);
8928 int proto_id;
8929 const char *name;
8930
8931 /* Walk the list of a available protocols in the packet and
8932 attempt to find the specified protocol. */
8933 while (protos != NULL((void*)0))
8934 {
8935 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8936 name = proto_get_protocol_filter_name(proto_id);
8937
8938 if (!strcmp(name, proto_name))
8939 {
8940 return true1;
8941 }
8942
8943 protos = wmem_list_frame_next(protos);
8944 }
8945
8946 return false0;
8947}
8948
8949char *
8950proto_list_layers(const packet_info *pinfo)
8951{
8952 wmem_strbuf_t *buf;
8953 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8954
8955 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8956
8957 /* Walk the list of layers in the packet and
8958 return a string of all entries. */
8959 while (layers != NULL((void*)0))
8960 {
8961 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8962
8963 layers = wmem_list_frame_next(layers);
8964 if (layers != NULL((void*)0)) {
8965 wmem_strbuf_append_c(buf, ':');
8966 }
8967 }
8968
8969 return wmem_strbuf_finalize(buf);
8970}
8971
8972uint8_t
8973proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8974{
8975 int *proto_layer_num_ptr;
8976
8977 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8978 if (proto_layer_num_ptr == NULL((void*)0)) {
8979 return 0;
8980 }
8981
8982 return (uint8_t)*proto_layer_num_ptr;
8983}
8984
8985bool_Bool
8986proto_is_pino(const protocol_t *protocol)
8987{
8988 return (protocol->parent_proto_id != -1);
8989}
8990
8991bool_Bool
8992// NOLINTNEXTLINE(misc-no-recursion)
8993proto_is_protocol_enabled(const protocol_t *protocol)
8994{
8995 if (protocol == NULL((void*)0))
8996 return false0;
8997
8998 //parent protocol determines enable/disable for helper dissectors
8999 if (proto_is_pino(protocol))
9000 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9001
9002 return protocol->is_enabled;
9003}
9004
9005bool_Bool
9006// NOLINTNEXTLINE(misc-no-recursion)
9007proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9008{
9009 //parent protocol determines enable/disable for helper dissectors
9010 if (proto_is_pino(protocol))
9011 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9012
9013 return protocol->enabled_by_default;
9014}
9015
9016bool_Bool
9017// NOLINTNEXTLINE(misc-no-recursion)
9018proto_can_toggle_protocol(const int proto_id)
9019{
9020 protocol_t *protocol;
9021
9022 protocol = find_protocol_by_id(proto_id);
9023 //parent protocol determines toggling for helper dissectors
9024 if (proto_is_pino(protocol))
9025 return proto_can_toggle_protocol(protocol->parent_proto_id);
9026
9027 return protocol->can_toggle;
9028}
9029
9030void
9031proto_disable_by_default(const int proto_id)
9032{
9033 protocol_t *protocol;
9034
9035 protocol = find_protocol_by_id(proto_id);
9036 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9036, "protocol->can_toggle"
))))
;
9037 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", 9037, "proto_is_pino(protocol) == 0"
))))
;
9038 protocol->is_enabled = false0;
9039 protocol->enabled_by_default = false0;
9040}
9041
9042void
9043proto_set_decoding(const int proto_id, const bool_Bool enabled)
9044{
9045 protocol_t *protocol;
9046
9047 protocol = find_protocol_by_id(proto_id);
9048 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9048, "protocol->can_toggle"
))))
;
9049 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", 9049, "proto_is_pino(protocol) == 0"
))))
;
9050 protocol->is_enabled = enabled;
9051}
9052
9053void
9054proto_disable_all(void)
9055{
9056 /* This doesn't explicitly disable heuristic protocols,
9057 * but the heuristic doesn't get called if the parent
9058 * protocol isn't enabled.
9059 */
9060 protocol_t *protocol;
9061 GList *list_item = protocols;
9062
9063 if (protocols == NULL((void*)0))
9064 return;
9065
9066 while (list_item) {
9067 protocol = (protocol_t *)list_item->data;
9068 if (protocol->can_toggle) {
9069 protocol->is_enabled = false0;
9070 }
9071 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9072 }
9073}
9074
9075static void
9076heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9077{
9078 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9079
9080 heur->enabled = heur->enabled_by_default;
9081}
9082
9083void
9084proto_reenable_all(void)
9085{
9086 protocol_t *protocol;
9087 GList *list_item = protocols;
9088
9089 if (protocols == NULL((void*)0))
9090 return;
9091
9092 while (list_item) {
9093 protocol = (protocol_t *)list_item->data;
9094 if (protocol->can_toggle)
9095 protocol->is_enabled = protocol->enabled_by_default;
9096 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9097 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9098 }
9099}
9100
9101void
9102proto_set_cant_toggle(const int proto_id)
9103{
9104 protocol_t *protocol;
9105
9106 protocol = find_protocol_by_id(proto_id);
9107 protocol->can_toggle = false0;
9108}
9109
9110static int
9111proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9112{
9113 g_ptr_array_add(proto->fields, hfi);
9114
9115 return proto_register_field_init(hfi, parent);
9116}
9117
9118/* for use with static arrays only, since we don't allocate our own copies
9119of the header_field_info struct contained within the hf_register_info struct */
9120void
9121proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9122{
9123 hf_register_info *ptr = hf;
9124 protocol_t *proto;
9125 int i;
9126
9127 proto = find_protocol_by_id(parent);
9128
9129 /* if (proto == NULL) - error or return? */
9130
9131 if (proto->fields == NULL((void*)0)) {
9132 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9133 * GLib introduced g_ptr_array_new_from_array, which might have
9134 * given a reason to actually use it. (#17774)
9135 */
9136 proto->fields = g_ptr_array_sized_new(num_records);
9137 }
9138
9139 for (i = 0; i < num_records; i++, ptr++) {
9140 /*
9141 * Make sure we haven't registered this yet.
9142 * Most fields have variables associated with them that
9143 * are initialized to 0; some are initialized to -1 (which
9144 * was the standard before 4.4).
9145 *
9146 * XXX - Since this is called almost 300000 times at startup,
9147 * it might be nice to compare to only 0 and require
9148 * dissectors to pass in zero for unregistered fields.
9149 */
9150 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9151 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9152 "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)
9153 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9154 return;
9155 }
9156
9157 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9158 }
9159}
9160
9161/* deregister already registered fields */
9162void
9163proto_deregister_field (const int parent, int hf_id)
9164{
9165 header_field_info *hfi;
9166 protocol_t *proto;
9167 unsigned i;
9168
9169 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
9170 last_field_name = NULL((void*)0);
9171
9172 if (hf_id == -1 || hf_id == 0)
9173 return;
9174
9175 proto = find_protocol_by_id (parent);
9176 if (!proto || proto->fields == NULL((void*)0)) {
9177 return;
9178 }
9179
9180 for (i = 0; i < proto->fields->len; i++) {
9181 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9182 if (hfi->id == hf_id) {
9183 /* Found the hf_id in this protocol */
9184 wmem_map_remove(gpa_name_map, hfi->abbrev);
9185 g_ptr_array_remove_index_fast(proto->fields, i);
9186 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9187 return;
9188 }
9189 }
9190}
9191
9192/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9193void
9194proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9195{
9196 header_field_info *hfinfo;
9197 protocol_t *proto;
9198
9199 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
9200 last_field_name = NULL((void*)0);
9201
9202 proto = find_protocol_by_id(parent);
9203 if (proto && proto->fields && proto->fields->len > 0) {
9204 unsigned i = proto->fields->len;
9205 do {
9206 i--;
9207
9208 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9209 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) )
) {
9210 hfinfo_remove_from_gpa_name_map(hfinfo);
9211 expert_deregister_expertinfo(hfinfo->abbrev);
9212 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9213 g_ptr_array_remove_index_fast(proto->fields, i);
9214 }
9215 } while (i > 0);
9216 }
9217}
9218
9219void
9220proto_add_deregistered_data (void *data)
9221{
9222 g_ptr_array_add(deregistered_data, data);
9223}
9224
9225void
9226proto_add_deregistered_slice (size_t block_size, void *mem_block)
9227{
9228 struct g_slice_data *slice_data = g_slice_new(struct g_slice_data)((struct g_slice_data*) g_slice_alloc ((sizeof (struct g_slice_data
) > 0 ? sizeof (struct g_slice_data) : 1)))
;
9229
9230 slice_data->block_size = block_size;
9231 slice_data->mem_block = mem_block;
9232
9233 g_ptr_array_add(deregistered_slice, slice_data);
9234}
9235
9236void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9237{
9238 if (field_strings == NULL((void*)0)) {
9239 return;
9240 }
9241
9242 switch (field_type) {
9243 case FT_FRAMENUM:
9244 /* This is just an integer represented as a pointer */
9245 break;
9246 case FT_PROTOCOL: {
9247 protocol_t *protocol = (protocol_t *)field_strings;
9248 g_free((char *)protocol->short_name)(__builtin_object_size (((char *)protocol->short_name), 0)
!= ((size_t) - 1)) ? g_free_sized ((char *)protocol->short_name
, __builtin_object_size (((char *)protocol->short_name), 0
)) : (g_free) ((char *)protocol->short_name)
;
9249 break;
9250 }
9251 case FT_BOOLEAN: {
9252 true_false_string *tf = (true_false_string *)field_strings;
9253 g_free((char *)tf->true_string)(__builtin_object_size (((char *)tf->true_string), 0) != (
(size_t) - 1)) ? g_free_sized ((char *)tf->true_string, __builtin_object_size
(((char *)tf->true_string), 0)) : (g_free) ((char *)tf->
true_string)
;
9254 g_free((char *)tf->false_string)(__builtin_object_size (((char *)tf->false_string), 0) != (
(size_t) - 1)) ? g_free_sized ((char *)tf->false_string, __builtin_object_size
(((char *)tf->false_string), 0)) : (g_free) ((char *)tf->
false_string)
;
9255 break;
9256 }
9257 case FT_UINT40:
9258 case FT_INT40:
9259 case FT_UINT48:
9260 case FT_INT48:
9261 case FT_UINT56:
9262 case FT_INT56:
9263 case FT_UINT64:
9264 case FT_INT64: {
9265 if (field_display & BASE_UNIT_STRING0x00001000) {
9266 unit_name_string *unit = (unit_name_string *)field_strings;
9267 g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != ((
size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size
(((char *)unit->singular), 0)) : (g_free) ((char *)unit->
singular)
;
9268 g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size
(((char *)unit->plural), 0)) : (g_free) ((char *)unit->
plural)
;
9269 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9270 range_string *rs = (range_string *)field_strings;
9271 while (rs->strptr) {
9272 g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size
(((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr
)
;
9273 rs++;
9274 }
9275 } else if (field_display & BASE_EXT_STRING0x00000200) {
9276 val64_string_ext *vse = (val64_string_ext *)field_strings;
9277 val64_string *vs = (val64_string *)vse->_vs_p;
9278 while (vs->strptr) {
9279 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9280 vs++;
9281 }
9282 val64_string_ext_free(vse);
9283 field_strings = NULL((void*)0);
9284 } else if (field_display == BASE_CUSTOM) {
9285 /* this will be a pointer to a function, don't free that */
9286 field_strings = NULL((void*)0);
9287 } else {
9288 val64_string *vs64 = (val64_string *)field_strings;
9289 while (vs64->strptr) {
9290 g_free((char *)vs64->strptr)(__builtin_object_size (((char *)vs64->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs64->strptr, __builtin_object_size
(((char *)vs64->strptr), 0)) : (g_free) ((char *)vs64->
strptr)
;
9291 vs64++;
9292 }
9293 }
9294 break;
9295 }
9296 case FT_CHAR:
9297 case FT_UINT8:
9298 case FT_INT8:
9299 case FT_UINT16:
9300 case FT_INT16:
9301 case FT_UINT24:
9302 case FT_INT24:
9303 case FT_UINT32:
9304 case FT_INT32:
9305 case FT_FLOAT:
9306 case FT_DOUBLE: {
9307 if (field_display & BASE_UNIT_STRING0x00001000) {
9308 unit_name_string *unit = (unit_name_string *)field_strings;
9309 g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != ((
size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size
(((char *)unit->singular), 0)) : (g_free) ((char *)unit->
singular)
;
9310 g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size
(((char *)unit->plural), 0)) : (g_free) ((char *)unit->
plural)
;
9311 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9312 range_string *rs = (range_string *)field_strings;
9313 while (rs->strptr) {
9314 g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size
(((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr
)
;
9315 rs++;
9316 }
9317 } else if (field_display & BASE_EXT_STRING0x00000200) {
9318 value_string_ext *vse = (value_string_ext *)field_strings;
9319 value_string *vs = (value_string *)vse->_vs_p;
9320 while (vs->strptr) {
9321 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9322 vs++;
9323 }
9324 value_string_ext_free(vse);
9325 field_strings = NULL((void*)0);
9326 } else if (field_display == BASE_CUSTOM) {
9327 /* this will be a pointer to a function, don't free that */
9328 field_strings = NULL((void*)0);
9329 } else {
9330 value_string *vs = (value_string *)field_strings;
9331 while (vs->strptr) {
9332 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9333 vs++;
9334 }
9335 }
9336 break;
9337 default:
9338 break;
9339 }
9340 }
9341
9342 if (field_type != FT_FRAMENUM) {
9343 g_free((void *)field_strings)(__builtin_object_size (((void *)field_strings), 0) != ((size_t
) - 1)) ? g_free_sized ((void *)field_strings, __builtin_object_size
(((void *)field_strings), 0)) : (g_free) ((void *)field_strings
)
;
9344 }
9345}
9346
9347static void
9348free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9349{
9350 header_field_info *hfi = (header_field_info *) data;
9351 int hf_id = hfi->id;
9352
9353 g_free((char *)hfi->name)(__builtin_object_size (((char *)hfi->name), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->name, __builtin_object_size
(((char *)hfi->name), 0)) : (g_free) ((char *)hfi->name
)
;
9354 g_free((char *)hfi->abbrev)(__builtin_object_size (((char *)hfi->abbrev), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->abbrev, __builtin_object_size
(((char *)hfi->abbrev), 0)) : (g_free) ((char *)hfi->abbrev
)
;
9355 g_free((char *)hfi->blurb)(__builtin_object_size (((char *)hfi->blurb), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->blurb, __builtin_object_size
(((char *)hfi->blurb), 0)) : (g_free) ((char *)hfi->blurb
)
;
9356
9357 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9358
9359 if (hfi->parent == -1)
9360 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)
;
9361
9362 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9363}
9364
9365static void
9366free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9367{
9368 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9369}
9370
9371static void
9372free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9373{
9374 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9375
9376 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9377 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)
;
9378}
9379
9380/* free deregistered fields and data */
9381void
9382proto_free_deregistered_fields (void)
9383{
9384 expert_free_deregistered_expertinfos();
9385
9386 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9387 g_ptr_array_free(deregistered_fields, true1);
9388 deregistered_fields = g_ptr_array_new();
9389
9390 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9391 g_ptr_array_free(deregistered_data, true1);
9392 deregistered_data = g_ptr_array_new();
9393
9394 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9395 g_ptr_array_free(deregistered_slice, true1);
9396 deregistered_slice = g_ptr_array_new();
9397}
9398
9399static const value_string hf_display[] = {
9400 { BASE_NONE, "BASE_NONE" },
9401 { BASE_DEC, "BASE_DEC" },
9402 { BASE_HEX, "BASE_HEX" },
9403 { BASE_OCT, "BASE_OCT" },
9404 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9405 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9406 { BASE_CUSTOM, "BASE_CUSTOM" },
9407 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9408 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9409 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9410 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9411 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9412 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9413 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9414 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9415 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9416 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9417 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9418 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9419 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9420 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9421 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9422 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9423 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9424 { BASE_PT_UDP, "BASE_PT_UDP" },
9425 { BASE_PT_TCP, "BASE_PT_TCP" },
9426 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9427 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9428 { BASE_OUI, "BASE_OUI" },
9429 { 0, NULL((void*)0) } };
9430
9431const char* proto_field_display_to_string(int field_display)
9432{
9433 return val_to_str_const(field_display, hf_display, "Unknown");
9434}
9435
9436static inline port_type
9437display_to_port_type(field_display_e e)
9438{
9439 switch (e) {
9440 case BASE_PT_UDP:
9441 return PT_UDP;
9442 case BASE_PT_TCP:
9443 return PT_TCP;
9444 case BASE_PT_DCCP:
9445 return PT_DCCP;
9446 case BASE_PT_SCTP:
9447 return PT_SCTP;
9448 default:
9449 break;
9450 }
9451 return PT_NONE;
9452}
9453
9454/* temporary function containing assert part for easier profiling */
9455static void
9456tmp_fld_check_assert(header_field_info *hfinfo)
9457{
9458 char* tmp_str;
9459
9460 /* The field must have a name (with length > 0) */
9461 if (!hfinfo->name || !hfinfo->name[0]) {
9462 if (hfinfo->abbrev)
9463 /* Try to identify the field */
9464 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)
9465 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9466 else
9467 /* Hum, no luck */
9468 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)"
)
;
9469 }
9470
9471 /* fields with an empty string for an abbreviation aren't filterable */
9472 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9473 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)
;
9474
9475 /* TODO: This check is a significant percentage of startup time (~10%),
9476 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9477 It might be nice to have a way to disable this check when, e.g.,
9478 running TShark many times with the same configuration. */
9479 /* Check that the filter name (abbreviation) is legal;
9480 * it must contain only alphanumerics, '-', "_", and ".". */
9481 unsigned char c;
9482 c = module_check_valid_name(hfinfo->abbrev, false0);
9483 if (c) {
9484 if (c == '.') {
9485 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)
;
9486 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9487 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)
;
9488 } else {
9489 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)
;
9490 }
9491 }
9492
9493 /* These types of fields are allowed to have value_strings,
9494 * true_false_strings or a protocol_t struct
9495 */
9496 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9497 switch (hfinfo->type) {
9498
9499 /*
9500 * These types are allowed to support display value_strings,
9501 * value64_strings, the extended versions of the previous
9502 * two, range strings, or unit strings.
9503 */
9504 case FT_CHAR:
9505 case FT_UINT8:
9506 case FT_UINT16:
9507 case FT_UINT24:
9508 case FT_UINT32:
9509 case FT_UINT40:
9510 case FT_UINT48:
9511 case FT_UINT56:
9512 case FT_UINT64:
9513 case FT_INT8:
9514 case FT_INT16:
9515 case FT_INT24:
9516 case FT_INT32:
9517 case FT_INT40:
9518 case FT_INT48:
9519 case FT_INT56:
9520 case FT_INT64:
9521 case FT_BOOLEAN:
9522 case FT_PROTOCOL:
9523 break;
9524
9525 /*
9526 * This is allowed to have a value of type
9527 * enum ft_framenum_type to indicate what relationship
9528 * the frame in question has to the frame in which
9529 * the field is put.
9530 */
9531 case FT_FRAMENUM:
9532 break;
9533
9534 /*
9535 * These types are allowed to support only unit strings.
9536 */
9537 case FT_FLOAT:
9538 case FT_DOUBLE:
9539 case FT_IEEE_11073_SFLOAT:
9540 case FT_IEEE_11073_FLOAT:
9541 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9542 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))
9543 " (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))
9544 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))
;
9545 }
9546 break;
9547
9548 /*
9549 * These types are allowed to support display
9550 * time_value_strings.
9551 */
9552 case FT_ABSOLUTE_TIME:
9553 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9554 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9555 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9556 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9557 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))
9558 " (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))
9559 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))
;
9560 }
9561 break;
9562
9563 /*
9564 * This type is only allowed to support a string if it's
9565 * a protocol (for pinos).
9566 */
9567 case FT_BYTES:
9568 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9569 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))
9570 " (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))
9571 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))
;
9572 }
9573 break;
9574
9575 default:
9576 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))
9577 " (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))
9578 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))
;
9579 }
9580 }
9581
9582 /* TODO: This check may slow down startup, and output quite a few warnings.
9583 It would be good to be able to enable this (and possibly other checks?)
9584 in non-release builds. */
9585#ifdef ENABLE_CHECK_FILTER
9586 /* Check for duplicate value_string values.
9587 There are lots that have the same value *and* string, so for now only
9588 report those that have same value but different string. */
9589 if ((hfinfo->strings != NULL((void*)0)) &&
9590 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9591 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9592 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9593 (
9594 (hfinfo->type == FT_CHAR) ||
9595 (hfinfo->type == FT_UINT8) ||
9596 (hfinfo->type == FT_UINT16) ||
9597 (hfinfo->type == FT_UINT24) ||
9598 (hfinfo->type == FT_UINT32) ||
9599 (hfinfo->type == FT_INT8) ||
9600 (hfinfo->type == FT_INT16) ||
9601 (hfinfo->type == FT_INT24) ||
9602 (hfinfo->type == FT_INT32) )) {
9603
9604 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9605 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9606 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9607 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9608 } else {
9609 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9610 CHECK_HF_VALUE(value_string, "u", start_values);
9611 }
9612 } else {
9613 const value_string *start_values = (const value_string*)hfinfo->strings;
9614 CHECK_HF_VALUE(value_string, "u", start_values);
9615 }
9616 }
9617
9618 if (hfinfo->type == FT_BOOLEAN) {
9619 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9620 if (tfs) {
9621 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9622 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9623 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9624 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9625 }
9626 }
9627 }
9628
9629 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9630 const range_string *rs = (const range_string*)(hfinfo->strings);
9631 if (rs) {
9632 const range_string *this_it = rs;
9633
9634 do {
9635 if (this_it->value_max < this_it->value_min) {
9636 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"
, 9640, __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)
9637 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9640, __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)
9638 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9640, __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)
9639 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9640, __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)
9640 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9640, __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)
;
9641 ++this_it;
9642 continue;
9643 }
9644
9645 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9646 /* Not OK if this one is completely hidden by an earlier one! */
9647 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9648 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"
, 9654, __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)
9649 "(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"
, 9654, __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)
9650 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
9651 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
9652 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
9653 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
9654 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9654, __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)
;
9655 }
9656 }
9657 ++this_it;
9658 } while (this_it->strptr);
9659 }
9660 }
9661#endif
9662
9663 switch (hfinfo->type) {
9664
9665 case FT_CHAR:
9666 /* Require the char type to have BASE_HEX, BASE_OCT,
9667 * BASE_CUSTOM, or BASE_NONE as its base.
9668 *
9669 * If the display value is BASE_NONE and there is a
9670 * strings conversion then the dissector writer is
9671 * telling us that the field's numerical value is
9672 * meaningless; we'll avoid showing the value to the
9673 * user.
9674 */
9675 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9676 case BASE_HEX:
9677 case BASE_OCT:
9678 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9679 break;
9680 case BASE_NONE:
9681 if (hfinfo->strings == NULL((void*)0))
9682 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9683 " but is being displayed as BASE_NONE but"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9684 " without a strings conversion",proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9685 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9686 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9687 break;
9688 default:
9689 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9690 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)
9691 " 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)
9692 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)
9693 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)
;
9694 //wmem_free(NULL, tmp_str);
9695 }
9696 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9697 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
))
9698 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
))
9699 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
))
;
9700 }
9701 break;
9702 case FT_INT8:
9703 case FT_INT16:
9704 case FT_INT24:
9705 case FT_INT32:
9706 case FT_INT40:
9707 case FT_INT48:
9708 case FT_INT56:
9709 case FT_INT64:
9710 /* Hexadecimal and octal are, in printf() and everywhere
9711 * else, unsigned so don't allow dissectors to register a
9712 * signed field to be displayed unsigned. (Else how would
9713 * we display negative values?)
9714 */
9715 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9716 case BASE_HEX:
9717 case BASE_OCT:
9718 case BASE_DEC_HEX:
9719 case BASE_HEX_DEC:
9720 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9721 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)
9722 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)
9723 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)
;
9724 //wmem_free(NULL, tmp_str);
9725 }
9726 /* FALL THROUGH */
9727 case FT_UINT8:
9728 case FT_UINT16:
9729 case FT_UINT24:
9730 case FT_UINT32:
9731 case FT_UINT40:
9732 case FT_UINT48:
9733 case FT_UINT56:
9734 case FT_UINT64:
9735 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
))
) {
9736 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9737 if (hfinfo->type != FT_UINT16) {
9738 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))
9739 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))
9740 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))
;
9741 }
9742 if (hfinfo->strings != NULL((void*)0)) {
9743 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)
9744 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)
9745 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)
;
9746 }
9747 if (hfinfo->bitmask != 0) {
9748 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)
9749 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)
9750 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)
;
9751 }
9752 wmem_free(NULL((void*)0), tmp_str);
9753 break;
9754 }
9755
9756 if (hfinfo->display == BASE_OUI) {
9757 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9758 if (!FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| ftype_wire_size(hfinfo->type) < 3) {
9759 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))
9760 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))
9761 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))
;
9762 }
9763 if (hfinfo->strings != NULL((void*)0)) {
9764 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)
9765 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)
9766 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)
;
9767 }
9768 /* It can be a FT_UINT24 with a 0 bitmask, or
9769 * larger with a bitmask with 24 bits set. */
9770 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9771 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)
9772 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)
9773 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)
;
9774 }
9775 wmem_free(NULL((void*)0), tmp_str);
9776 break;
9777 }
9778
9779 /* Require integral types (other than frame number,
9780 * which is always displayed in decimal) to have a
9781 * number base.
9782 *
9783 * If the display value is BASE_NONE and there is a
9784 * strings conversion then the dissector writer is
9785 * telling us that the field's numerical value is
9786 * meaningless; we'll avoid showing the value to the
9787 * user.
9788 */
9789 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9790 case BASE_DEC:
9791 case BASE_HEX:
9792 case BASE_OCT:
9793 case BASE_DEC_HEX:
9794 case BASE_HEX_DEC:
9795 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9796 break;
9797 case BASE_NONE:
9798 if (hfinfo->strings == NULL((void*)0)) {
9799 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
))
9800 " 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
))
9801 " 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
))
9802 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
))
9803 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
))
;
9804 }
9805 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9806 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
))
9807 " 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
))
9808 " 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
))
9809 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
))
9810 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
))
;
9811 }
9812 break;
9813
9814 default:
9815 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9816 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)
9817 " 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)
9818 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)
9819 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)
;
9820 //wmem_free(NULL, tmp_str);
9821 }
9822 break;
9823 case FT_BYTES:
9824 case FT_UINT_BYTES:
9825 /* Require bytes to have a "display type" that could
9826 * add a character between displayed bytes.
9827 */
9828 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9829 case BASE_NONE:
9830 case SEP_DOT:
9831 case SEP_DASH:
9832 case SEP_COLON:
9833 case SEP_SPACE:
9834 break;
9835 default:
9836 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9837 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)
9838 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)
;
9839 //wmem_free(NULL, tmp_str);
9840 }
9841 if (hfinfo->bitmask != 0)
9842 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9843 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9844 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9845 //allowed to support string if its a protocol (for pinos)
9846 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9847 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
))
9848 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
))
9849 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
))
;
9850 break;
9851
9852 case FT_PROTOCOL:
9853 case FT_FRAMENUM:
9854 if (hfinfo->display != BASE_NONE) {
9855 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9856 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)
9857 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)
9858 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)
;
9859 //wmem_free(NULL, tmp_str);
9860 }
9861 if (hfinfo->bitmask != 0)
9862 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
))
9863 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
))
9864 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
))
;
9865 break;
9866
9867 case FT_BOOLEAN:
9868 break;
9869
9870 case FT_ABSOLUTE_TIME:
9871 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9872 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9873 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)
9874 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)
;
9875 //wmem_free(NULL, tmp_str);
9876 }
9877 if (hfinfo->bitmask != 0)
9878 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
))
9879 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
))
9880 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
))
;
9881 break;
9882
9883 case FT_STRING:
9884 case FT_STRINGZ:
9885 case FT_UINT_STRING:
9886 case FT_STRINGZPAD:
9887 case FT_STRINGZTRUNC:
9888 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9889 case BASE_NONE:
9890 case BASE_STR_WSP:
9891 break;
9892
9893 default:
9894 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9895 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)
9896 " 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)
9897 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)
9898 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)
;
9899 //wmem_free(NULL, tmp_str);
9900 }
9901
9902 if (hfinfo->bitmask != 0)
9903 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
))
9904 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
))
9905 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
))
;
9906 if (hfinfo->strings != NULL((void*)0))
9907 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
))
9908 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
))
9909 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
))
;
9910 break;
9911
9912 case FT_IPv4:
9913 switch (hfinfo->display) {
9914 case BASE_NONE:
9915 case BASE_NETMASK:
9916 break;
9917
9918 default:
9919 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9920 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)
9921 " 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)
9922 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)
9923 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)
;
9924 //wmem_free(NULL, tmp_str);
9925 break;
9926 }
9927 break;
9928 case FT_FLOAT:
9929 case FT_DOUBLE:
9930 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9931 case BASE_NONE:
9932 case BASE_DEC:
9933 case BASE_HEX:
9934 case BASE_EXP:
9935 case BASE_CUSTOM:
9936 break;
9937 default:
9938 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9939 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)
9940 " 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)
9941 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)
9942 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)
;
9943 //wmem_free(NULL, tmp_str);
9944 }
9945 if (hfinfo->bitmask != 0)
9946 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
))
9947 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
))
9948 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
))
;
9949 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9950 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
))
9951 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
))
9952 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
))
;
9953 break;
9954 case FT_IEEE_11073_SFLOAT:
9955 case FT_IEEE_11073_FLOAT:
9956 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9957 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9958 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)
9959 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)
9960 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)
9961 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)
;
9962 //wmem_free(NULL, tmp_str);
9963 }
9964 if (hfinfo->bitmask != 0)
9965 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
))
9966 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
))
9967 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
))
;
9968 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9969 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
))
9970 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
))
9971 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
))
;
9972 break;
9973 default:
9974 if (hfinfo->display != BASE_NONE) {
9975 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9976 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)
9977 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)
9978 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)
9979 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)
;
9980 //wmem_free(NULL, tmp_str);
9981 }
9982 if (hfinfo->bitmask != 0)
9983 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
))
9984 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
))
9985 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
))
;
9986 if (hfinfo->strings != NULL((void*)0))
9987 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
))
9988 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
))
9989 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
))
;
9990 break;
9991 }
9992}
9993
9994static void
9995register_type_length_mismatch(void)
9996{
9997 static ei_register_info ei[] = {
9998 { &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)}}
}},
9999 { &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)}}
}},
10000 };
10001
10002 expert_module_t* expert_type_length_mismatch;
10003
10004 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10005
10006 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10007 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10008
10009 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10010 disabling them makes no sense. */
10011 proto_set_cant_toggle(proto_type_length_mismatch);
10012}
10013
10014static void
10015register_byte_array_string_decodinws_error(void)
10016{
10017 static ei_register_info ei[] = {
10018 { &ei_byte_array_string_decoding_failed_error,
10019 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10020 "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)}}
10021 }
10022 },
10023 };
10024
10025 expert_module_t* expert_byte_array_string_decoding_error;
10026
10027 proto_byte_array_string_decoding_error =
10028 proto_register_protocol("Byte Array-String Decoding Error",
10029 "Byte Array-string decoding error",
10030 "_ws.byte_array_string.decoding_error");
10031
10032 expert_byte_array_string_decoding_error =
10033 expert_register_protocol(proto_byte_array_string_decoding_error);
10034 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10035
10036 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10037 disabling them makes no sense. */
10038 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10039}
10040
10041static void
10042register_date_time_string_decodinws_error(void)
10043{
10044 static ei_register_info ei[] = {
10045 { &ei_date_time_string_decoding_failed_error,
10046 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10047 "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)}}
10048 }
10049 },
10050 };
10051
10052 expert_module_t* expert_date_time_string_decoding_error;
10053
10054 proto_date_time_string_decoding_error =
10055 proto_register_protocol("Date and Time-String Decoding Error",
10056 "Date and Time-string decoding error",
10057 "_ws.date_time_string.decoding_error");
10058
10059 expert_date_time_string_decoding_error =
10060 expert_register_protocol(proto_date_time_string_decoding_error);
10061 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10062
10063 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10064 disabling them makes no sense. */
10065 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10066}
10067
10068static void
10069register_string_errors(void)
10070{
10071 static ei_register_info ei[] = {
10072 { &ei_string_trailing_characters,
10073 { "_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)}}
}
10074 },
10075 };
10076
10077 expert_module_t* expert_string_errors;
10078
10079 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10080
10081 expert_string_errors = expert_register_protocol(proto_string_errors);
10082 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10083
10084 /* "String Errors" isn't really a protocol, it's an error indication;
10085 disabling them makes no sense. */
10086 proto_set_cant_toggle(proto_string_errors);
10087}
10088
10089static int
10090proto_register_field_init(header_field_info *hfinfo, const int parent)
10091{
10092
10093 tmp_fld_check_assert(hfinfo);
10094
10095 hfinfo->parent = parent;
10096 hfinfo->same_name_next = NULL((void*)0);
10097 hfinfo->same_name_prev_id = -1;
10098
10099 /* if we always add and never delete, then id == len - 1 is correct */
10100 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10101 if (!gpa_hfinfo.hfi) {
10102 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10103 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10104 /* The entry with index 0 is not used. */
10105 gpa_hfinfo.hfi[0] = NULL((void*)0);
10106 gpa_hfinfo.len = 1;
10107 } else {
10108 gpa_hfinfo.allocated_len += 1000;
10109 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10110 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10111 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10112 }
10113 }
10114 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10115 gpa_hfinfo.len++;
10116 hfinfo->id = gpa_hfinfo.len - 1;
10117
10118 /* if we have real names, enter this field in the name tree */
10119 /* Already checked in tmp_fld_check_assert */
10120 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10121 {
10122
10123 header_field_info *same_name_next_hfinfo;
10124
10125 /* We allow multiple hfinfo's to be registered under the same
10126 * abbreviation. This was done for X.25, as, depending
10127 * on whether it's modulo-8 or modulo-128 operation,
10128 * some bitfield fields may be in different bits of
10129 * a byte, and we want to be able to refer to that field
10130 * with one name regardless of whether the packets
10131 * are modulo-8 or modulo-128 packets. */
10132
10133 /* wmem_map_insert - if key is already present the previous
10134 * hfinfo with the same key/name is returned, otherwise NULL */
10135 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10136 if (same_name_hfinfo) {
10137 /* There's already a field with this name.
10138 * Put the current field *before* that field
10139 * in the list of fields with this name, Thus,
10140 * we end up with an effectively
10141 * doubly-linked-list of same-named hfinfo's,
10142 * with the head of the list (stored in the
10143 * hash) being the last seen hfinfo.
10144 */
10145 same_name_next_hfinfo =
10146 same_name_hfinfo->same_name_next;
10147
10148 hfinfo->same_name_next = same_name_next_hfinfo;
10149 if (same_name_next_hfinfo)
10150 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10151
10152 same_name_hfinfo->same_name_next = hfinfo;
10153 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10154#ifdef ENABLE_CHECK_FILTER
10155 while (same_name_hfinfo) {
10156 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10157 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", 10157
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10158 same_name_hfinfo = same_name_hfinfo->same_name_next;
10159 }
10160#endif
10161 }
10162 }
10163
10164 return hfinfo->id;
10165}
10166
10167void
10168proto_register_subtree_array(int * const *indices, const int num_indices)
10169{
10170 int i;
10171 int *const *ptr = indices;
10172
10173 /*
10174 * If we've already allocated the array of tree types, expand
10175 * it; this lets plugins such as mate add tree types after
10176 * the initial startup. (If we haven't already allocated it,
10177 * we don't allocate it; on the first pass, we just assign
10178 * ett values and keep track of how many we've assigned, and
10179 * when we're finished registering all dissectors we allocate
10180 * the array, so that we do only one allocation rather than
10181 * wasting CPU time and memory by growing the array for each
10182 * dissector that registers ett values.)
10183 */
10184 if (tree_is_expanded != NULL((void*)0)) {
10185 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10186
10187 /* set new items to 0 */
10188 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10189 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10190 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10191 }
10192
10193 /*
10194 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10195 * returning the indices through the pointers in the array whose
10196 * first element is pointed to by "indices", and update
10197 * "num_tree_types" appropriately.
10198 */
10199 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10200 if (**ptr != -1 && **ptr != 0) {
10201 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.")
10202 " 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.")
10203 " 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.")
10204 " 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.")
;
10205 }
10206 **ptr = num_tree_types;
10207 }
10208}
10209
10210static void
10211mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10212{
10213 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10214 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10215 char *last_char;
10216
10217 /* ..... field_name: dataaaaaaaaaaaaa
10218 * |
10219 * ^^^^^ name_pos
10220 *
10221 * ..... field_name […]: dataaaaaaaaaaaaa
10222 *
10223 * name_pos==0 means that we have only data or only a field_name
10224 */
10225
10226 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10226, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10227
10228 if (name_pos >= size - trunc_len) {
10229 /* No room for trunc_str after the field_name, put it first. */
10230 name_pos = 0;
10231 }
10232
10233 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10234 if (name_pos == 0) {
10235 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10236 memcpy(label_str, trunc_str + 1, trunc_len);
10237 } else {
10238 memcpy(label_str + name_pos, trunc_str, trunc_len);
10239 }
10240 /* in general, label_str is UTF-8
10241 we can truncate it only at the beginning of a new character
10242 we go backwards from the byte right after our buffer and
10243 find the next starting byte of a UTF-8 character, this is
10244 where we cut
10245 there's no need to use g_utf8_find_prev_char(), the search
10246 will always succeed since we copied trunc_str into the
10247 buffer */
10248 /* g_utf8_prev_char does not deference the memory address
10249 * passed in (until after decrementing it, so it is perfectly
10250 * legal to pass in a pointer one past the last element.
10251 */
10252 last_char = g_utf8_prev_char(label_str + size);
10253 *last_char = '\0';
10254 /* This is unnecessary (above always terminates), but try to
10255 * convince Coverity to avoid dozens of false positives. */
10256 label_str[size - 1] = '\0';
10257
10258 if (value_pos && *value_pos > 0) {
10259 if (name_pos == 0) {
10260 *value_pos += trunc_len;
10261 } else {
10262 /* Move one back to include trunc_str in the value. */
10263 *value_pos -= 1;
10264 }
10265 }
10266
10267 /* Check if value_pos is past label_str. */
10268 if (value_pos && *value_pos >= size) {
10269 *value_pos = size - 1;
10270 }
10271}
10272
10273static void
10274label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10275{
10276 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10277}
10278
10279static size_t
10280label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10281{
10282 size_t name_pos;
10283
10284 /* "%s: %s", hfinfo->name, text */
10285 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)
;
10286 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10287 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10288 if (value_pos) {
10289 *value_pos = pos;
10290 }
10291 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10292 }
10293
10294 if (pos >= ITEM_LABEL_LENGTH240) {
10295 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10296 label_mark_truncated(label_str, name_pos, value_pos);
10297 }
10298
10299 return pos;
10300}
10301
10302static size_t
10303label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10304{
10305 size_t name_pos;
10306
10307 /* "%s: %s (%s)", hfinfo->name, text, descr */
10308 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)
;
10309 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10310 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10311 if (value_pos) {
10312 *value_pos = pos;
10313 }
10314 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10315 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)
;
10316 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)
;
10317 } else {
10318 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)
;
10319 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10320 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)
;
10321 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10322 }
10323 }
10324
10325 if (pos >= ITEM_LABEL_LENGTH240) {
10326 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10327 label_mark_truncated(label_str, name_pos, value_pos);
10328 }
10329
10330 return pos;
10331}
10332
10333void
10334proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10335{
10336 const header_field_info *hfinfo;
10337 const char *str;
10338 const uint8_t *bytes;
10339 uint32_t integer;
10340 const ipv4_addr_and_mask *ipv4;
10341 const ipv6_addr_and_prefix *ipv6;
10342 const e_guid_t *guid;
10343 char *name;
10344 address addr;
10345 char *addr_str;
10346 char *tmp;
10347
10348 if (!label_str) {
10349 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10349, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10350 return;
10351 }
10352
10353 label_str[0]= '\0';
10354
10355 if (!fi) {
10356 return;
10357 }
10358
10359 hfinfo = fi->hfinfo;
10360
10361 switch (hfinfo->type) {
10362 case FT_NONE:
10363 case FT_PROTOCOL:
10364 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10365 if (value_pos) {
10366 *value_pos = strlen(hfinfo->name);
10367 }
10368 break;
10369
10370 case FT_BOOLEAN:
10371 fill_label_boolean(fi, label_str, value_pos);
10372 break;
10373
10374 case FT_BYTES:
10375 case FT_UINT_BYTES:
10376 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10377 fvalue_get_bytes_data(fi->value),
10378 (unsigned)fvalue_length2(fi->value));
10379 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10380 wmem_free(NULL((void*)0), tmp);
10381 break;
10382
10383 case FT_CHAR:
10384 if (hfinfo->bitmask) {
10385 fill_label_bitfield_char(fi, label_str, value_pos);
10386 } else {
10387 fill_label_char(fi, label_str, value_pos);
10388 }
10389 break;
10390
10391 /* Four types of integers to take care of:
10392 * Bitfield, with val_string
10393 * Bitfield, w/o val_string
10394 * Non-bitfield, with val_string
10395 * Non-bitfield, w/o val_string
10396 */
10397 case FT_UINT8:
10398 case FT_UINT16:
10399 case FT_UINT24:
10400 case FT_UINT32:
10401 if (hfinfo->bitmask) {
10402 fill_label_bitfield(fi, label_str, value_pos, false0);
10403 } else {
10404 fill_label_number(fi, label_str, value_pos, false0);
10405 }
10406 break;
10407
10408 case FT_FRAMENUM:
10409 fill_label_number(fi, label_str, value_pos, false0);
10410 break;
10411
10412 case FT_UINT40:
10413 case FT_UINT48:
10414 case FT_UINT56:
10415 case FT_UINT64:
10416 if (hfinfo->bitmask) {
10417 fill_label_bitfield64(fi, label_str, value_pos, false0);
10418 } else {
10419 fill_label_number64(fi, label_str, value_pos, false0);
10420 }
10421 break;
10422
10423 case FT_INT8:
10424 case FT_INT16:
10425 case FT_INT24:
10426 case FT_INT32:
10427 if (hfinfo->bitmask) {
10428 fill_label_bitfield(fi, label_str, value_pos, true1);
10429 } else {
10430 fill_label_number(fi, label_str, value_pos, true1);
10431 }
10432 break;
10433
10434 case FT_INT40:
10435 case FT_INT48:
10436 case FT_INT56:
10437 case FT_INT64:
10438 if (hfinfo->bitmask) {
10439 fill_label_bitfield64(fi, label_str, value_pos, true1);
10440 } else {
10441 fill_label_number64(fi, label_str, value_pos, true1);
10442 }
10443 break;
10444
10445 case FT_FLOAT:
10446 case FT_DOUBLE:
10447 fill_label_float(fi, label_str, value_pos);
10448 break;
10449
10450 case FT_ABSOLUTE_TIME:
10451 {
10452 const nstime_t *value = fvalue_get_time(fi->value);
10453 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10454 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10455 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10456 }
10457 if (hfinfo->strings) {
10458 /*
10459 * Table of time values to be displayed
10460 * specially.
10461 */
10462 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10463 if (time_string != NULL((void*)0)) {
10464 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10465 break;
10466 }
10467 }
10468 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10469 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10470 wmem_free(NULL((void*)0), tmp);
10471 break;
10472 }
10473 case FT_RELATIVE_TIME:
10474 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10475 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10476 wmem_free(NULL((void*)0), tmp);
10477 break;
10478
10479 case FT_IPXNET:
10480 integer = fvalue_get_uinteger(fi->value);
10481 tmp = get_ipxnet_name(NULL((void*)0), integer);
10482 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10483 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10484 wmem_free(NULL((void*)0), tmp);
10485 wmem_free(NULL((void*)0), addr_str);
10486 break;
10487
10488 case FT_VINES:
10489 addr.type = AT_VINES;
10490 addr.len = VINES_ADDR_LEN6;
10491 addr.data = fvalue_get_bytes_data(fi->value);
10492
10493 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10494 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10495 wmem_free(NULL((void*)0), addr_str);
10496 break;
10497
10498 case FT_ETHER:
10499 bytes = fvalue_get_bytes_data(fi->value);
10500
10501 addr.type = AT_ETHER;
10502 addr.len = 6;
10503 addr.data = bytes;
10504
10505 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10506 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10507 wmem_free(NULL((void*)0), addr_str);
10508 break;
10509
10510 case FT_IPv4:
10511 ipv4 = fvalue_get_ipv4(fi->value);
10512 set_address_ipv4(&addr, ipv4);
10513
10514 if (hfinfo->display == BASE_NETMASK) {
10515 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10516 } else {
10517 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10518 }
10519 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10520 wmem_free(NULL((void*)0), addr_str);
10521 free_address(&addr);
10522 break;
10523
10524 case FT_IPv6:
10525 ipv6 = fvalue_get_ipv6(fi->value);
10526 set_address_ipv6(&addr, ipv6);
10527
10528 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10529 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10530 wmem_free(NULL((void*)0), addr_str);
10531 free_address(&addr);
10532 break;
10533
10534 case FT_FCWWN:
10535 bytes = fvalue_get_bytes_data(fi->value);
10536 addr.type = AT_FCWWN;
10537 addr.len = FCWWN_ADDR_LEN8;
10538 addr.data = bytes;
10539
10540 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10541 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10542 wmem_free(NULL((void*)0), addr_str);
10543 break;
10544
10545 case FT_GUID:
10546 guid = fvalue_get_guid(fi->value);
10547 tmp = guid_to_str(NULL((void*)0), guid);
10548 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10549 wmem_free(NULL((void*)0), tmp);
10550 break;
10551
10552 case FT_OID:
10553 bytes = fvalue_get_bytes_data(fi->value);
10554 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10555 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10556 if (name) {
10557 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10558 wmem_free(NULL((void*)0), name);
10559 } else {
10560 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10561 }
10562 wmem_free(NULL((void*)0), tmp);
10563 break;
10564
10565 case FT_REL_OID:
10566 bytes = fvalue_get_bytes_data(fi->value);
10567 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10568 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10569 if (name) {
10570 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10571 wmem_free(NULL((void*)0), name);
10572 } else {
10573 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10574 }
10575 wmem_free(NULL((void*)0), tmp);
10576 break;
10577
10578 case FT_SYSTEM_ID:
10579 bytes = fvalue_get_bytes_data(fi->value);
10580 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10581 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10582 wmem_free(NULL((void*)0), tmp);
10583 break;
10584
10585 case FT_EUI64:
10586 bytes = fvalue_get_bytes_data(fi->value);
10587 addr.type = AT_EUI64;
10588 addr.len = EUI64_ADDR_LEN8;
10589 addr.data = bytes;
10590
10591 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10592 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10593 wmem_free(NULL((void*)0), addr_str);
10594 break;
10595 case FT_STRING:
10596 case FT_STRINGZ:
10597 case FT_UINT_STRING:
10598 case FT_STRINGZPAD:
10599 case FT_STRINGZTRUNC:
10600 case FT_AX25:
10601 str = fvalue_get_string(fi->value);
10602 label_fill(label_str, 0, hfinfo, str, value_pos);
10603 break;
10604
10605 case FT_IEEE_11073_SFLOAT:
10606 case FT_IEEE_11073_FLOAT:
10607 fill_label_ieee_11073_float(fi, label_str, value_pos);
10608 break;
10609
10610 default:
10611 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
))
10612 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
))
10613 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
))
10614 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
))
;
10615 break;
10616 }
10617}
10618
10619static void
10620fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10621{
10622 char *p;
10623 unsigned bitfield_byte_length = 0;
10624 int bitwidth;
10625 uint64_t unshifted_value;
10626 uint64_t value;
10627
10628 const header_field_info *hfinfo = fi->hfinfo;
10629
10630 value = fvalue_get_uinteger64(fi->value);
10631 if (hfinfo->bitmask) {
10632 /* Figure out the bit width */
10633 bitwidth = hfinfo_container_bitwidth(hfinfo);
10634
10635 /* Un-shift bits */
10636 unshifted_value = value;
10637 unshifted_value <<= hfinfo_bitshift(hfinfo);
10638
10639 /* Create the bitfield first */
10640 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10641 bitfield_byte_length = (unsigned) (p - label_str);
10642 }
10643
10644 /* Fill in the textual info */
10645 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10646}
10647
10648static const char *
10649hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10650{
10651 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10652 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10653
10654 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10655 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10656 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10657 else
10658 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10659 }
10660
10661 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10662 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10663
10664 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10665 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10666
10667 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10668}
10669
10670static const char *
10671hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10672{
10673 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10674 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10675 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10676 else
10677 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10678 }
10679
10680 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10681 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10682
10683 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10684 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10685
10686 /* If this is reached somebody registered a 64-bit field with a 32-bit
10687 * value-string, which isn't right. */
10688 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)
10689 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10690
10691 /* This is necessary to squelch MSVC errors; is there
10692 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10693 never returns? */
10694 return NULL((void*)0);
10695}
10696
10697static const char *
10698hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10699{
10700 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10701 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10702
10703 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)
;
10704
10705 /* This is necessary to squelch MSVC errors; is there
10706 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10707 never returns? */
10708 return NULL((void*)0);
10709}
10710
10711static const char *
10712hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10713{
10714 const char *str = hf_try_val_to_str(value, hfinfo);
10715
10716 return (str) ? str : unknown_str;
10717}
10718
10719static const char *
10720hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10721{
10722 const char *str = hf_try_val64_to_str(value, hfinfo);
10723
10724 return (str) ? str : unknown_str;
10725}
10726
10727/* Fills data for bitfield chars with val_strings */
10728static void
10729fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10730{
10731 char *p;
10732 unsigned bitfield_byte_length;
10733 int bitwidth;
10734 uint32_t unshifted_value;
10735 uint32_t value;
10736
10737 char buf[32];
10738 const char *out;
10739
10740 const header_field_info *hfinfo = fi->hfinfo;
10741
10742 /* Figure out the bit width */
10743 bitwidth = hfinfo_container_bitwidth(hfinfo);
10744
10745 /* Un-shift bits */
10746 value = fvalue_get_uinteger(fi->value);
10747
10748 unshifted_value = value;
10749 if (hfinfo->bitmask) {
10750 unshifted_value <<= hfinfo_bitshift(hfinfo);
10751 }
10752
10753 /* Create the bitfield first */
10754 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10755 bitfield_byte_length = (unsigned) (p - label_str);
10756
10757 /* Fill in the textual info using stored (shifted) value */
10758 if (hfinfo->display == BASE_CUSTOM) {
10759 char tmp[ITEM_LABEL_LENGTH240];
10760 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10761
10762 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10762, "fmtfunc"))))
;
10763 fmtfunc(tmp, value);
10764 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10765 }
10766 else if (hfinfo->strings) {
10767 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10768
10769 out = hfinfo_char_vals_format(hfinfo, buf, value);
10770 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10771 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10772 else
10773 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10774 }
10775 else {
10776 out = hfinfo_char_value_format(hfinfo, buf, value);
10777
10778 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10779 }
10780}
10781
10782/* Fills data for bitfield ints with val_strings */
10783static void
10784fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10785{
10786 char *p;
10787 unsigned bitfield_byte_length;
10788 int bitwidth;
10789 uint32_t value, unshifted_value;
10790 char buf[NUMBER_LABEL_LENGTH80];
10791 const char *out;
10792
10793 const header_field_info *hfinfo = fi->hfinfo;
10794
10795 /* Figure out the bit width */
10796 if (fi->flags & FI_VARINT0x00040000)
10797 bitwidth = fi->length*8;
10798 else
10799 bitwidth = hfinfo_container_bitwidth(hfinfo);
10800
10801 /* Un-shift bits */
10802 if (is_signed)
10803 value = fvalue_get_sinteger(fi->value);
10804 else
10805 value = fvalue_get_uinteger(fi->value);
10806
10807 unshifted_value = value;
10808 if (hfinfo->bitmask) {
10809 unshifted_value <<= hfinfo_bitshift(hfinfo);
10810 }
10811
10812 /* Create the bitfield first */
10813 if (fi->flags & FI_VARINT0x00040000)
10814 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10815 else
10816 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10817 bitfield_byte_length = (unsigned) (p - label_str);
10818
10819 /* Fill in the textual info using stored (shifted) value */
10820 if (hfinfo->display == BASE_CUSTOM) {
10821 char tmp[ITEM_LABEL_LENGTH240];
10822 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10823
10824 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10824, "fmtfunc"))))
;
10825 fmtfunc(tmp, value);
10826 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10827 }
10828 else if (hfinfo->strings) {
10829 const char *val_str = hf_try_val_to_str(value, hfinfo);
10830
10831 out = hfinfo_number_vals_format(hfinfo, buf, value);
10832 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10833 /*
10834 * Unique values only display value_string string
10835 * if there is a match. Otherwise it's just a number
10836 */
10837 if (val_str) {
10838 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10839 } else {
10840 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10841 }
10842 } else {
10843 if (val_str == NULL((void*)0))
10844 val_str = "Unknown";
10845
10846 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10847 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10848 else
10849 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10850 }
10851 }
10852 else {
10853 out = hfinfo_number_value_format(hfinfo, buf, value);
10854
10855 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10856 }
10857}
10858
10859static void
10860fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10861{
10862 char *p;
10863 unsigned bitfield_byte_length;
10864 int bitwidth;
10865 uint64_t value, unshifted_value;
10866 char buf[NUMBER_LABEL_LENGTH80];
10867 const char *out;
10868
10869 const header_field_info *hfinfo = fi->hfinfo;
10870
10871 /* Figure out the bit width */
10872 if (fi->flags & FI_VARINT0x00040000)
10873 bitwidth = fi->length*8;
10874 else
10875 bitwidth = hfinfo_container_bitwidth(hfinfo);
10876
10877 /* Un-shift bits */
10878 if (is_signed)
10879 value = fvalue_get_sinteger64(fi->value);
10880 else
10881 value = fvalue_get_uinteger64(fi->value);
10882
10883 unshifted_value = value;
10884 if (hfinfo->bitmask) {
10885 unshifted_value <<= hfinfo_bitshift(hfinfo);
10886 }
10887
10888 /* Create the bitfield first */
10889 if (fi->flags & FI_VARINT0x00040000)
10890 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10891 else
10892 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10893 bitfield_byte_length = (unsigned) (p - label_str);
10894
10895 /* Fill in the textual info using stored (shifted) value */
10896 if (hfinfo->display == BASE_CUSTOM) {
10897 char tmp[ITEM_LABEL_LENGTH240];
10898 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10899
10900 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10900, "fmtfunc64"
))))
;
10901 fmtfunc64(tmp, value);
10902 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10903 }
10904 else if (hfinfo->strings) {
10905 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10906
10907 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10908 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10909 /*
10910 * Unique values only display value_string string
10911 * if there is a match. Otherwise it's just a number
10912 */
10913 if (val_str) {
10914 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10915 } else {
10916 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10917 }
10918 } else {
10919 if (val_str == NULL((void*)0))
10920 val_str = "Unknown";
10921
10922 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10923 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10924 else
10925 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10926 }
10927 }
10928 else {
10929 out = hfinfo_number_value_format64(hfinfo, buf, value);
10930
10931 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10932 }
10933}
10934
10935static void
10936fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10937{
10938 const header_field_info *hfinfo = fi->hfinfo;
10939 uint32_t value;
10940
10941 char buf[32];
10942 const char *out;
10943
10944 value = fvalue_get_uinteger(fi->value);
10945
10946 /* Fill in the textual info */
10947 if (hfinfo->display == BASE_CUSTOM) {
10948 char tmp[ITEM_LABEL_LENGTH240];
10949 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10950
10951 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10951, "fmtfunc"))))
;
10952 fmtfunc(tmp, value);
10953 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10954 }
10955 else if (hfinfo->strings) {
10956 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10957
10958 out = hfinfo_char_vals_format(hfinfo, buf, value);
10959 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10960 }
10961 else {
10962 out = hfinfo_char_value_format(hfinfo, buf, value);
10963
10964 label_fill(label_str, 0, hfinfo, out, value_pos);
10965 }
10966}
10967
10968static void
10969fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10970{
10971 const header_field_info *hfinfo = fi->hfinfo;
10972 uint32_t value;
10973
10974 char buf[NUMBER_LABEL_LENGTH80];
10975 const char *out;
10976
10977 if (is_signed)
10978 value = fvalue_get_sinteger(fi->value);
10979 else
10980 value = fvalue_get_uinteger(fi->value);
10981
10982 /* Fill in the textual info */
10983 if (hfinfo->display == BASE_CUSTOM) {
10984 char tmp[ITEM_LABEL_LENGTH240];
10985 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10986
10987 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10987, "fmtfunc"))))
;
10988 fmtfunc(tmp, value);
10989 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10990 }
10991 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10992 /*
10993 * It makes no sense to have a value-string table for a
10994 * frame-number field - they're just integers giving
10995 * the ordinal frame number.
10996 */
10997 const char *val_str = hf_try_val_to_str(value, hfinfo);
10998
10999 out = hfinfo_number_vals_format(hfinfo, buf, value);
11000 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11001 /*
11002 * Unique values only display value_string string
11003 * if there is a match. Otherwise it's just a number
11004 */
11005 if (val_str) {
11006 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11007 } else {
11008 label_fill(label_str, 0, hfinfo, out, value_pos);
11009 }
11010 } else {
11011 if (val_str == NULL((void*)0))
11012 val_str = "Unknown";
11013
11014 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11015 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11016 else
11017 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11018 }
11019 }
11020 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
))
) {
11021 char tmp[ITEM_LABEL_LENGTH240];
11022
11023 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11024 display_to_port_type((field_display_e)hfinfo->display), value);
11025 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11026 }
11027 else {
11028 out = hfinfo_number_value_format(hfinfo, buf, value);
11029
11030 label_fill(label_str, 0, hfinfo, out, value_pos);
11031 }
11032}
11033
11034static void
11035fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11036{
11037 const header_field_info *hfinfo = fi->hfinfo;
11038 uint64_t value;
11039
11040 char buf[NUMBER_LABEL_LENGTH80];
11041 const char *out;
11042
11043 if (is_signed)
11044 value = fvalue_get_sinteger64(fi->value);
11045 else
11046 value = fvalue_get_uinteger64(fi->value);
11047
11048 /* Fill in the textual info */
11049 if (hfinfo->display == BASE_CUSTOM) {
11050 char tmp[ITEM_LABEL_LENGTH240];
11051 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11052
11053 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11053, "fmtfunc64"
))))
;
11054 fmtfunc64(tmp, value);
11055 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11056 }
11057 else if (hfinfo->strings) {
11058 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11059
11060 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11061 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11062 /*
11063 * Unique values only display value_string string
11064 * if there is a match. Otherwise it's just a number
11065 */
11066 if (val_str) {
11067 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11068 } else {
11069 label_fill(label_str, 0, hfinfo, out, value_pos);
11070 }
11071 } else {
11072 if (val_str == NULL((void*)0))
11073 val_str = "Unknown";
11074
11075 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11076 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11077 else
11078 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11079 }
11080 }
11081 else {
11082 out = hfinfo_number_value_format64(hfinfo, buf, value);
11083
11084 label_fill(label_str, 0, hfinfo, out, value_pos);
11085 }
11086}
11087
11088static size_t
11089fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11090{
11091 int display;
11092 int n;
11093 double value;
11094
11095 if (label_str_size < 12) {
11096 /* Not enough room to write an entire floating point value. */
11097 return 0;
11098 }
11099
11100 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11101 value = fvalue_get_floating(fi->value);
11102
11103 if (display == BASE_CUSTOM) {
11104 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11105 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11105, "fmtfunc"))))
;
11106 fmtfunc(label_str, value);
11107 return strlen(label_str);
11108 }
11109
11110 switch (display) {
11111 case BASE_NONE:
11112 if (fi->hfinfo->type == FT_FLOAT) {
11113 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11114 } else {
11115 n = (int)strlen(dtoa_g_fmt(label_str, value));
11116 }
11117 break;
11118 case BASE_DEC:
11119 n = snprintf(label_str, label_str_size, "%f", value);
11120 break;
11121 case BASE_HEX:
11122 n = snprintf(label_str, label_str_size, "%a", value);
11123 break;
11124 case BASE_EXP:
11125 n = snprintf(label_str, label_str_size, "%e", value);
11126 break;
11127 default:
11128 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11128
, __func__, "assertion \"not reached\" failed")
;
11129 }
11130 if (n < 0) {
11131 return 0; /* error */
11132 }
11133 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11134 const char *hf_str_val;
11135 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11136 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11137 }
11138 if (n > label_str_size) {
11139 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11139, __func__, "label length too small"); } } while (0)
;
11140 return strlen(label_str);
11141 }
11142
11143 return n;
11144}
11145
11146void
11147fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11148{
11149 char tmp[ITEM_LABEL_LENGTH240];
11150
11151 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11152 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11153}
11154
11155static size_t
11156fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11157{
11158 int display;
11159 size_t pos = 0;
11160 double value;
11161 char* tmp_str;
11162
11163 if (label_str_size < 12) {
11164 /* Not enough room to write an entire floating point value. */
11165 return 0;
11166 }
11167
11168 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11169 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11170 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11171 wmem_free(NULL((void*)0), tmp_str);
11172
11173 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11174 const char *hf_str_val;
11175 fvalue_to_double(fi->value, &value);
11176 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11177 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)
;
11178 }
11179 if ((int)pos > label_str_size) {
11180 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11180, __func__, "label length too small"); } } while (0)
;
11181 return strlen(label_str);
11182 }
11183
11184 return pos;
11185}
11186
11187void
11188fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11189{
11190 char tmp[ITEM_LABEL_LENGTH240];
11191
11192 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11193 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11194}
11195
11196int
11197hfinfo_bitshift(const header_field_info *hfinfo)
11198{
11199 return ws_ctz(hfinfo->bitmask);
11200}
11201
11202
11203static int
11204hfinfo_bitoffset(const header_field_info *hfinfo)
11205{
11206 if (!hfinfo->bitmask) {
11207 return 0;
11208 }
11209
11210 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11211 * as the first bit */
11212 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11213}
11214
11215static int
11216hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11217{
11218 if (!hfinfo->bitmask) {
11219 return 0;
11220 }
11221
11222 /* ilog2 = first set bit, ctz = last set bit */
11223 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11224}
11225
11226static int
11227hfinfo_type_bitwidth(enum ftenum type)
11228{
11229 int bitwidth = 0;
11230
11231 switch (type) {
11232 case FT_CHAR:
11233 case FT_UINT8:
11234 case FT_INT8:
11235 bitwidth = 8;
11236 break;
11237 case FT_UINT16:
11238 case FT_INT16:
11239 bitwidth = 16;
11240 break;
11241 case FT_UINT24:
11242 case FT_INT24:
11243 bitwidth = 24;
11244 break;
11245 case FT_UINT32:
11246 case FT_INT32:
11247 bitwidth = 32;
11248 break;
11249 case FT_UINT40:
11250 case FT_INT40:
11251 bitwidth = 40;
11252 break;
11253 case FT_UINT48:
11254 case FT_INT48:
11255 bitwidth = 48;
11256 break;
11257 case FT_UINT56:
11258 case FT_INT56:
11259 bitwidth = 56;
11260 break;
11261 case FT_UINT64:
11262 case FT_INT64:
11263 bitwidth = 64;
11264 break;
11265 default:
11266 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11266))
;
11267 ;
11268 }
11269 return bitwidth;
11270}
11271
11272
11273static int
11274hfinfo_container_bitwidth(const header_field_info *hfinfo)
11275{
11276 if (!hfinfo->bitmask) {
11277 return 0;
11278 }
11279
11280 if (hfinfo->type == FT_BOOLEAN) {
11281 return hfinfo->display; /* hacky? :) */
11282 }
11283
11284 return hfinfo_type_bitwidth(hfinfo->type);
11285}
11286
11287static int
11288hfinfo_hex_digits(const header_field_info *hfinfo)
11289{
11290 int bitwidth;
11291
11292 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11293 * appropriate to determine the number of hex digits for the field.
11294 * So instead, we compute it from the bitmask.
11295 */
11296 if (hfinfo->bitmask != 0) {
11297 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11298 } else {
11299 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11300 }
11301
11302 /* Divide by 4, rounding up, to get number of hex digits. */
11303 return (bitwidth + 3) / 4;
11304}
11305
11306const char *
11307hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11308{
11309 char *ptr = &buf[6];
11310 static const char hex_digits[16] =
11311 { '0', '1', '2', '3', '4', '5', '6', '7',
11312 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11313
11314 *ptr = '\0';
11315 *(--ptr) = '\'';
11316 /* Properly format value */
11317 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11318 /*
11319 * Printable, so just show the character, and, if it needs
11320 * to be escaped, escape it.
11321 */
11322 *(--ptr) = value;
11323 if (value == '\\' || value == '\'')
11324 *(--ptr) = '\\';
11325 } else {
11326 /*
11327 * Non-printable; show it as an escape sequence.
11328 */
11329 switch (value) {
11330
11331 case '\0':
11332 /*
11333 * Show a NUL with only one digit.
11334 */
11335 *(--ptr) = '0';
11336 break;
11337
11338 case '\a':
11339 case '\b':
11340 case '\f':
11341 case '\n':
11342 case '\r':
11343 case '\t':
11344 case '\v':
11345 *(--ptr) = value - '\a' + 'a';
11346 break;
11347
11348 default:
11349 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11350
11351 case BASE_OCT:
11352 *(--ptr) = (value & 0x7) + '0';
11353 value >>= 3;
11354 *(--ptr) = (value & 0x7) + '0';
11355 value >>= 3;
11356 *(--ptr) = (value & 0x7) + '0';
11357 break;
11358
11359 case BASE_HEX:
11360 *(--ptr) = hex_digits[value & 0x0F];
11361 value >>= 4;
11362 *(--ptr) = hex_digits[value & 0x0F];
11363 *(--ptr) = 'x';
11364 break;
11365
11366 default:
11367 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11368 }
11369 }
11370 *(--ptr) = '\\';
11371 }
11372 *(--ptr) = '\'';
11373 return ptr;
11374}
11375
11376static const char *
11377hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11378{
11379 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11380 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
))
;
11381
11382 *ptr = '\0';
11383 /* Properly format value */
11384 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11385 case BASE_DEC:
11386 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11387
11388 case BASE_DEC_HEX:
11389 *(--ptr) = ')';
11390 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11391 *(--ptr) = '(';
11392 *(--ptr) = ' ';
11393 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11394 return ptr;
11395
11396 case BASE_OCT:
11397 return oct_to_str_back(ptr, value);
11398
11399 case BASE_HEX:
11400 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11401
11402 case BASE_HEX_DEC:
11403 *(--ptr) = ')';
11404 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11405 *(--ptr) = '(';
11406 *(--ptr) = ' ';
11407 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11408 return ptr;
11409
11410 case BASE_PT_UDP:
11411 case BASE_PT_TCP:
11412 case BASE_PT_DCCP:
11413 case BASE_PT_SCTP:
11414 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11415 display_to_port_type((field_display_e)display), value);
11416 return buf;
11417 case BASE_OUI:
11418 {
11419 uint8_t p_oui[3];
11420 const char *manuf_name;
11421
11422 p_oui[0] = value >> 16 & 0xFF;
11423 p_oui[1] = value >> 8 & 0xFF;
11424 p_oui[2] = value & 0xFF;
11425
11426 /* Attempt an OUI lookup. */
11427 manuf_name = uint_get_manuf_name_if_known(value);
11428 if (manuf_name == NULL((void*)0)) {
11429 /* Could not find an OUI. */
11430 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11431 }
11432 else {
11433 /* Found an address string. */
11434 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11435 }
11436 return buf;
11437 }
11438
11439 default:
11440 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11441 }
11442 return ptr;
11443}
11444
11445static const char *
11446hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11447{
11448 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11449 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
))
;
11450
11451 *ptr = '\0';
11452 /* Properly format value */
11453 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11454 case BASE_DEC:
11455 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11456
11457 case BASE_DEC_HEX:
11458 *(--ptr) = ')';
11459 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11460 *(--ptr) = '(';
11461 *(--ptr) = ' ';
11462 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11463 return ptr;
11464
11465 case BASE_OCT:
11466 return oct64_to_str_back(ptr, value);
11467
11468 case BASE_HEX:
11469 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11470
11471 case BASE_HEX_DEC:
11472 *(--ptr) = ')';
11473 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11474 *(--ptr) = '(';
11475 *(--ptr) = ' ';
11476 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11477 return ptr;
11478
11479 default:
11480 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11481 }
11482
11483 return ptr;
11484}
11485
11486static const char *
11487hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11488{
11489 int display = hfinfo->display;
11490
11491 if (hfinfo->type == FT_FRAMENUM) {
11492 /*
11493 * Frame numbers are always displayed in decimal.
11494 */
11495 display = BASE_DEC;
11496 }
11497
11498 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11499}
11500
11501static const char *
11502hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11503{
11504 int display = hfinfo->display;
11505
11506 if (hfinfo->type == FT_FRAMENUM) {
11507 /*
11508 * Frame numbers are always displayed in decimal.
11509 */
11510 display = BASE_DEC;
11511 }
11512
11513 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11514}
11515
11516static const char *
11517hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11518{
11519 /* Get the underlying BASE_ value */
11520 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11521
11522 return hfinfo_char_value_format_display(display, buf, value);
11523}
11524
11525static const char *
11526hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11527{
11528 /* Get the underlying BASE_ value */
11529 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11530
11531 if (hfinfo->type == FT_FRAMENUM) {
11532 /*
11533 * Frame numbers are always displayed in decimal.
11534 */
11535 display = BASE_DEC;
11536 }
11537
11538 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11539 display = BASE_DEC;
11540 } else if (display == BASE_OUI) {
11541 display = BASE_HEX;
11542 }
11543
11544 switch (display) {
11545 case BASE_NONE:
11546 /* case BASE_DEC: */
11547 case BASE_DEC_HEX:
11548 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11549 case BASE_CUSTOM:
11550 display = BASE_DEC;
11551 break;
11552
11553 /* case BASE_HEX: */
11554 case BASE_HEX_DEC:
11555 display = BASE_HEX;
11556 break;
11557 }
11558
11559 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11560}
11561
11562static const char *
11563hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11564{
11565 /* Get the underlying BASE_ value */
11566 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11567
11568 if (hfinfo->type == FT_FRAMENUM) {
11569 /*
11570 * Frame numbers are always displayed in decimal.
11571 */
11572 display = BASE_DEC;
11573 }
11574
11575 switch (display) {
11576 case BASE_NONE:
11577 /* case BASE_DEC: */
11578 case BASE_DEC_HEX:
11579 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11580 case BASE_CUSTOM:
11581 display = BASE_DEC;
11582 break;
11583
11584 /* case BASE_HEX: */
11585 case BASE_HEX_DEC:
11586 display = BASE_HEX;
11587 break;
11588 }
11589
11590 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11591}
11592
11593static const char *
11594hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11595{
11596 /* Get the underlying BASE_ value */
11597 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11598
11599 return hfinfo_char_value_format_display(display, buf, value);
11600}
11601
11602static const char *
11603hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11604{
11605 /* Get the underlying BASE_ value */
11606 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11607
11608 if (display == BASE_NONE)
11609 return NULL((void*)0);
11610
11611 if (display == BASE_DEC_HEX)
11612 display = BASE_DEC;
11613 if (display == BASE_HEX_DEC)
11614 display = BASE_HEX;
11615
11616 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11617}
11618
11619static const char *
11620hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11621{
11622 /* Get the underlying BASE_ value */
11623 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11624
11625 if (display == BASE_NONE)
11626 return NULL((void*)0);
11627
11628 if (display == BASE_DEC_HEX)
11629 display = BASE_DEC;
11630 if (display == BASE_HEX_DEC)
11631 display = BASE_HEX;
11632
11633 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11634}
11635
11636const char *
11637proto_registrar_get_name(const int n)
11638{
11639 header_field_info *hfinfo;
11640
11641 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", 11641
, __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", 11641
, "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", 11641, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11642 return hfinfo->name;
11643}
11644
11645const char *
11646proto_registrar_get_abbrev(const int n)
11647{
11648 header_field_info *hfinfo;
11649
11650 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", 11650
, __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", 11650
, "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", 11650, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11651 return hfinfo->abbrev;
11652}
11653
11654enum ftenum
11655proto_registrar_get_ftype(const int n)
11656{
11657 header_field_info *hfinfo;
11658
11659 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11659
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11659
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11659, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11660 return hfinfo->type;
11661}
11662
11663int
11664proto_registrar_get_parent(const int n)
11665{
11666 header_field_info *hfinfo;
11667
11668 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", 11668
, __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", 11668
, "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", 11668, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11669 return hfinfo->parent;
11670}
11671
11672bool_Bool
11673proto_registrar_is_protocol(const int n)
11674{
11675 header_field_info *hfinfo;
11676
11677 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", 11677
, __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", 11677
, "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", 11677, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11678 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11679}
11680
11681/* Returns length of field in packet (not necessarily the length
11682 * in our internal representation, as in the case of IPv4).
11683 * 0 means undeterminable at time of registration
11684 * -1 means the field is not registered. */
11685int
11686proto_registrar_get_length(const int n)
11687{
11688 header_field_info *hfinfo;
11689
11690 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", 11690
, __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", 11690
, "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", 11690, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11691 return ftype_wire_size(hfinfo->type);
11692}
11693
11694size_t
11695proto_registrar_get_count(struct proto_registrar_stats *stats)
11696{
11697 header_field_info *hfinfo;
11698
11699 // Index zero is not used. We have to skip it.
11700 size_t total_count = gpa_hfinfo.len - 1;
11701 if (stats == NULL((void*)0)) {
11702 return total_count;
11703 }
11704 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11705 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11706 stats->deregistered_count++;
11707 continue; /* This is a deregistered protocol or header field */
11708 }
11709
11710 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", 11710
, __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", 11710, "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", 11710, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11711
11712 if (proto_registrar_is_protocol(id))
11713 stats->protocol_count++;
11714
11715 if (hfinfo->same_name_prev_id != -1)
11716 stats->same_name_count++;
11717 }
11718
11719 return total_count;
11720}
11721
11722/* Looks for a protocol or a field in a proto_tree. Returns true if
11723 * it exists anywhere, or false if it exists nowhere. */
11724bool_Bool
11725proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11726{
11727 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11728
11729 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11730 return true1;
11731 }
11732 else {
11733 return false0;
11734 }
11735}
11736
11737/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11738 * This only works if the hfindex was "primed" before the dissection
11739 * took place, as we just pass back the already-created GPtrArray*.
11740 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11741 * handles that. */
11742GPtrArray *
11743proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11744{
11745 if (!tree)
11746 return NULL((void*)0);
11747
11748 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11749 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11750 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11751 else
11752 return NULL((void*)0);
11753}
11754
11755bool_Bool
11756proto_tracking_interesting_fields(const proto_tree *tree)
11757{
11758 GHashTable *interesting_hfids;
11759
11760 if (!tree)
11761 return false0;
11762
11763 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11764
11765 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11766}
11767
11768/* Helper struct for proto_find_info() and proto_all_finfos() */
11769typedef struct {
11770 GPtrArray *array;
11771 int id;
11772} ffdata_t;
11773
11774/* Helper function for proto_find_info() */
11775static bool_Bool
11776find_finfo(proto_node *node, void * data)
11777{
11778 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11779 if (fi && fi->hfinfo) {
11780 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11781 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11782 }
11783 }
11784
11785 /* Don't stop traversing. */
11786 return false0;
11787}
11788
11789/* Helper function for proto_find_first_info() */
11790static bool_Bool
11791find_first_finfo(proto_node *node, void *data)
11792{
11793 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11794 if (fi && fi->hfinfo) {
11795 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11796 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11797
11798 /* Stop traversing. */
11799 return true1;
11800 }
11801 }
11802
11803 /* Continue traversing. */
11804 return false0;
11805}
11806
11807/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11808* This works on any proto_tree, primed or unprimed, but actually searches
11809* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11810* The caller does need to free the returned GPtrArray with
11811* g_ptr_array_free(<array>, true).
11812*/
11813GPtrArray *
11814proto_find_finfo(proto_tree *tree, const int id)
11815{
11816 ffdata_t ffdata;
11817
11818 ffdata.array = g_ptr_array_new();
11819 ffdata.id = id;
11820
11821 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11822
11823 return ffdata.array;
11824}
11825
11826/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11827* This works on any proto_tree, primed or unprimed, but actually searches
11828* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11829* The caller does need to free the returned GPtrArray with
11830* g_ptr_array_free(<array>, true).
11831*/
11832GPtrArray *
11833proto_find_first_finfo(proto_tree *tree, const int id)
11834{
11835 ffdata_t ffdata;
11836
11837 ffdata.array = g_ptr_array_new();
11838 ffdata.id = id;
11839
11840 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11841
11842 return ffdata.array;
11843}
11844
11845/* Helper function for proto_all_finfos() */
11846static bool_Bool
11847every_finfo(proto_node *node, void * data)
11848{
11849 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11850 if (fi && fi->hfinfo) {
11851 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11852 }
11853
11854 /* Don't stop traversing. */
11855 return false0;
11856}
11857
11858/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11859 * The caller does need to free the returned GPtrArray with
11860 * g_ptr_array_free(<array>, true).
11861 */
11862GPtrArray *
11863proto_all_finfos(proto_tree *tree)
11864{
11865 ffdata_t ffdata;
11866
11867 /* Pre allocate enough space to hold all fields in most cases */
11868 ffdata.array = g_ptr_array_sized_new(512);
11869 ffdata.id = 0;
11870
11871 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11872
11873 return ffdata.array;
11874}
11875
11876
11877typedef struct {
11878 unsigned offset;
11879 field_info *finfo;
11880 tvbuff_t *tvb;
11881} offset_search_t;
11882
11883static bool_Bool
11884check_for_offset(proto_node *node, void * data)
11885{
11886 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11887 offset_search_t *offsearch = (offset_search_t *)data;
11888
11889 /* !fi == the top most container node which holds nothing */
11890 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11891 if (offsearch->offset >= (unsigned) fi->start &&
11892 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11893
11894 offsearch->finfo = fi;
11895 return false0; /* keep traversing */
11896 }
11897 }
11898 return false0; /* keep traversing */
11899}
11900
11901/* Search a proto_tree backwards (from leaves to root) looking for the field
11902 * whose start/length occupies 'offset' */
11903/* XXX - I couldn't find an easy way to search backwards, so I search
11904 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11905 * the one I want to return to the user. This algorithm is inefficient
11906 * and could be re-done, but I'd have to handle all the children and
11907 * siblings of each node myself. When I have more time I'll do that.
11908 * (yeah right) */
11909field_info *
11910proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11911{
11912 offset_search_t offsearch;
11913
11914 offsearch.offset = offset;
11915 offsearch.finfo = NULL((void*)0);
11916 offsearch.tvb = tvb;
11917
11918 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11919
11920 return offsearch.finfo;
11921}
11922
11923typedef struct {
11924 unsigned length;
11925 char *buf;
11926} decoded_data_t;
11927
11928static bool_Bool
11929check_for_undecoded(proto_node *node, void * data)
11930{
11931 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11932 decoded_data_t* decoded = (decoded_data_t*)data;
11933 unsigned i;
11934 unsigned byte;
11935 unsigned bit;
11936
11937 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11938 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11939 byte = i / 8;
11940 bit = i % 8;
11941 decoded->buf[byte] |= (1 << bit);
11942 }
11943 }
11944
11945 return false0;
11946}
11947
11948char*
11949proto_find_undecoded_data(proto_tree *tree, unsigned length)
11950{
11951 decoded_data_t decoded;
11952 decoded.length = length;
11953 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11954
11955 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11956 return decoded.buf;
11957}
11958
11959/* Dumps the protocols in the registration database to stdout. An independent
11960 * program can take this output and format it into nice tables or HTML or
11961 * whatever.
11962 *
11963 * There is one record per line. The fields are tab-delimited.
11964 *
11965 * Field 1 = protocol name
11966 * Field 2 = protocol short name
11967 * Field 3 = protocol filter name
11968 * Field 4 = protocol enabled
11969 * Field 5 = protocol enabled by default
11970 * Field 6 = protocol can toggle
11971 */
11972void
11973proto_registrar_dump_protocols(void)
11974{
11975 protocol_t *protocol;
11976 int i;
11977 void *cookie = NULL((void*)0);
11978
11979
11980 i = proto_get_first_protocol(&cookie);
11981 while (i != -1) {
11982 protocol = find_protocol_by_id(i);
11983 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11984 protocol->name,
11985 protocol->short_name,
11986 protocol->filter_name,
11987 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11988 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11989 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11990 i = proto_get_next_protocol(&cookie);
11991 }
11992}
11993
11994/* Dumps the value_strings, extended value string headers, range_strings
11995 * or true/false strings for fields that have them.
11996 * There is one record per line. Fields are tab-delimited.
11997 * There are four types of records: Value String, Extended Value String Header,
11998 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11999 * the type of record.
12000 *
12001 * Note that a record will be generated only if the value_string,... is referenced
12002 * in a registered hfinfo entry.
12003 *
12004 *
12005 * Value Strings
12006 * -------------
12007 * Field 1 = 'V'
12008 * Field 2 = Field abbreviation to which this value string corresponds
12009 * Field 3 = Integer value
12010 * Field 4 = String
12011 *
12012 * Extended Value String Headers
12013 * -----------------------------
12014 * Field 1 = 'E'
12015 * Field 2 = Field abbreviation to which this extended value string header corresponds
12016 * Field 3 = Extended Value String "Name"
12017 * Field 4 = Number of entries in the associated value_string array
12018 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12019 *
12020 * Range Strings
12021 * -------------
12022 * Field 1 = 'R'
12023 * Field 2 = Field abbreviation to which this range string corresponds
12024 * Field 3 = Integer value: lower bound
12025 * Field 4 = Integer value: upper bound
12026 * Field 5 = String
12027 *
12028 * True/False Strings
12029 * ------------------
12030 * Field 1 = 'T'
12031 * Field 2 = Field abbreviation to which this true/false string corresponds
12032 * Field 3 = True String
12033 * Field 4 = False String
12034 */
12035void
12036proto_registrar_dump_values(void)
12037{
12038 header_field_info *hfinfo;
12039 int i, len, vi;
12040 const value_string *vals;
12041 const val64_string *vals64;
12042 const range_string *range;
12043 const true_false_string *tfs;
12044 const unit_name_string *units;
12045
12046 len = gpa_hfinfo.len;
12047 for (i = 1; i < len ; i++) {
12048 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12049 continue; /* This is a deregistered protocol or field */
12050
12051 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", 12051
, __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", 12051
, "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", 12051, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12052
12053 if (hfinfo->id == hf_text_only) {
12054 continue;
12055 }
12056
12057 /* ignore protocols */
12058 if (proto_registrar_is_protocol(i)) {
12059 continue;
12060 }
12061 /* process header fields */
12062#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12063 /*
12064 * If this field isn't at the head of the list of
12065 * fields with this name, skip this field - all
12066 * fields with the same name are really just versions
12067 * of the same field stored in different bits, and
12068 * should have the same type/radix/value list, and
12069 * just differ in their bit masks. (If a field isn't
12070 * a bitfield, but can be, say, 1 or 2 bytes long,
12071 * it can just be made FT_UINT16, meaning the
12072 * *maximum* length is 2 bytes, and be used
12073 * for all lengths.)
12074 */
12075 if (hfinfo->same_name_prev_id != -1)
12076 continue;
12077#endif
12078 vals = NULL((void*)0);
12079 vals64 = NULL((void*)0);
12080 range = NULL((void*)0);
12081 tfs = NULL((void*)0);
12082 units = NULL((void*)0);
12083
12084 if (hfinfo->strings != NULL((void*)0)) {
12085 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12086 (hfinfo->type == FT_CHAR ||
12087 hfinfo->type == FT_UINT8 ||
12088 hfinfo->type == FT_UINT16 ||
12089 hfinfo->type == FT_UINT24 ||
12090 hfinfo->type == FT_UINT32 ||
12091 hfinfo->type == FT_UINT40 ||
12092 hfinfo->type == FT_UINT48 ||
12093 hfinfo->type == FT_UINT56 ||
12094 hfinfo->type == FT_UINT64 ||
12095 hfinfo->type == FT_INT8 ||
12096 hfinfo->type == FT_INT16 ||
12097 hfinfo->type == FT_INT24 ||
12098 hfinfo->type == FT_INT32 ||
12099 hfinfo->type == FT_INT40 ||
12100 hfinfo->type == FT_INT48 ||
12101 hfinfo->type == FT_INT56 ||
12102 hfinfo->type == FT_INT64 ||
12103 hfinfo->type == FT_FLOAT ||
12104 hfinfo->type == FT_DOUBLE)) {
12105
12106 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12107 range = (const range_string *)hfinfo->strings;
12108 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12109 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12110 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12111 } else {
12112 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12113 }
12114 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12115 vals64 = (const val64_string *)hfinfo->strings;
12116 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12117 units = (const unit_name_string *)hfinfo->strings;
12118 } else {
12119 vals = (const value_string *)hfinfo->strings;
12120 }
12121 }
12122 else if (hfinfo->type == FT_BOOLEAN) {
12123 tfs = (const struct true_false_string *)hfinfo->strings;
12124 }
12125 }
12126
12127 /* Print value strings? */
12128 if (vals) {
12129 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12130 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12131 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12132 if (!val64_string_ext_validate(vse_p)) {
12133 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12133, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12134 continue;
12135 }
12136 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12137 printf("E\t%s\t%u\t%s\t%s\n",
12138 hfinfo->abbrev,
12139 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12140 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12141 val64_string_ext_match_type_str(vse_p));
12142 } else {
12143 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12144 if (!value_string_ext_validate(vse_p)) {
12145 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12145, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12146 continue;
12147 }
12148 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12149 printf("E\t%s\t%u\t%s\t%s\n",
12150 hfinfo->abbrev,
12151 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12152 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12153 value_string_ext_match_type_str(vse_p));
12154 }
12155 }
12156 vi = 0;
12157 while (vals[vi].strptr) {
12158 /* Print in the proper base */
12159 if (hfinfo->type == FT_CHAR) {
12160 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12161 printf("V\t%s\t'%c'\t%s\n",
12162 hfinfo->abbrev,
12163 vals[vi].value,
12164 vals[vi].strptr);
12165 } else {
12166 if (hfinfo->display == BASE_HEX) {
12167 printf("V\t%s\t'\\x%02x'\t%s\n",
12168 hfinfo->abbrev,
12169 vals[vi].value,
12170 vals[vi].strptr);
12171 }
12172 else {
12173 printf("V\t%s\t'\\%03o'\t%s\n",
12174 hfinfo->abbrev,
12175 vals[vi].value,
12176 vals[vi].strptr);
12177 }
12178 }
12179 } else {
12180 if (hfinfo->display == BASE_HEX) {
12181 printf("V\t%s\t0x%x\t%s\n",
12182 hfinfo->abbrev,
12183 vals[vi].value,
12184 vals[vi].strptr);
12185 }
12186 else {
12187 printf("V\t%s\t%u\t%s\n",
12188 hfinfo->abbrev,
12189 vals[vi].value,
12190 vals[vi].strptr);
12191 }
12192 }
12193 vi++;
12194 }
12195 }
12196 else if (vals64) {
12197 vi = 0;
12198 while (vals64[vi].strptr) {
12199 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12200 hfinfo->abbrev,
12201 vals64[vi].value,
12202 vals64[vi].strptr);
12203 vi++;
12204 }
12205 }
12206
12207 /* print range strings? */
12208 else if (range) {
12209 vi = 0;
12210 while (range[vi].strptr) {
12211 /* Print in the proper base */
12212 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12213 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12214 hfinfo->abbrev,
12215 range[vi].value_min,
12216 range[vi].value_max,
12217 range[vi].strptr);
12218 }
12219 else {
12220 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12221 hfinfo->abbrev,
12222 range[vi].value_min,
12223 range[vi].value_max,
12224 range[vi].strptr);
12225 }
12226 vi++;
12227 }
12228 }
12229
12230 /* Print true/false strings? */
12231 else if (tfs) {
12232 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12233 tfs->true_string, tfs->false_string);
12234 }
12235 /* Print unit strings? */
12236 else if (units) {
12237 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12238 units->singular, units->plural ? units->plural : "(no plural)");
12239 }
12240 }
12241}
12242
12243/* Prints the number of registered fields.
12244 * Useful for determining an appropriate value for
12245 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12246 *
12247 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12248 * the number of fields, true otherwise.
12249 */
12250bool_Bool
12251proto_registrar_dump_fieldcount(void)
12252{
12253 struct proto_registrar_stats stats = {0, 0, 0};
12254 size_t total_count = proto_registrar_get_count(&stats);
12255
12256 printf("There are %zu header fields registered, of which:\n"
12257 "\t%zu are deregistered\n"
12258 "\t%zu are protocols\n"
12259 "\t%zu have the same name as another field\n\n",
12260 total_count, stats.deregistered_count, stats.protocol_count,
12261 stats.same_name_count);
12262
12263 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12264 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12265 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12266 "\n");
12267
12268 printf("The header field table consumes %u KiB of memory.\n",
12269 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12270 printf("The fields themselves consume %u KiB of memory.\n",
12271 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12272
12273 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12274}
12275
12276static void
12277elastic_add_base_mapping(json_dumper *dumper)
12278{
12279 json_dumper_set_member_name(dumper, "index_patterns");
12280 json_dumper_begin_array(dumper);
12281 // The index names from write_json_index() in print.c
12282 json_dumper_value_string(dumper, "packets-*");
12283 json_dumper_end_array(dumper);
12284
12285 json_dumper_set_member_name(dumper, "settings");
12286 json_dumper_begin_object(dumper);
12287 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12288 json_dumper_value_anyf(dumper, "%d", 1000000);
12289 json_dumper_end_object(dumper);
12290}
12291
12292static char*
12293ws_type_to_elastic(unsigned type)
12294{
12295 switch(type) {
12296 case FT_INT8:
12297 return "byte";
12298 case FT_UINT8:
12299 case FT_INT16:
12300 return "short";
12301 case FT_UINT16:
12302 case FT_INT32:
12303 case FT_UINT24:
12304 case FT_INT24:
12305 return "integer";
12306 case FT_FRAMENUM:
12307 case FT_UINT32:
12308 case FT_UINT40:
12309 case FT_UINT48:
12310 case FT_UINT56:
12311 case FT_INT40:
12312 case FT_INT48:
12313 case FT_INT56:
12314 case FT_INT64:
12315 return "long";
12316 case FT_UINT64:
12317 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12318 case FT_FLOAT:
12319 return "float";
12320 case FT_DOUBLE:
12321 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12322 return "double";
12323 case FT_IPv6:
12324 case FT_IPv4:
12325 return "ip";
12326 case FT_ABSOLUTE_TIME:
12327 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12328 case FT_BOOLEAN:
12329 return "boolean";
12330 default:
12331 return NULL((void*)0);
12332 }
12333}
12334
12335static char*
12336dot_to_underscore(char* str)
12337{
12338 unsigned i;
12339 for (i = 0; i < strlen(str); i++) {
12340 if (str[i] == '.')
12341 str[i] = '_';
12342 }
12343 return str;
12344}
12345
12346/* Dumps a mapping file for ElasticSearch
12347 * This is the v1 (legacy) _template API.
12348 * At some point it may need to be updated with the composable templates
12349 * introduced in Elasticsearch 7.8 (_index_template)
12350 */
12351void
12352proto_registrar_dump_elastic(const char* filter)
12353{
12354 header_field_info *hfinfo;
12355 header_field_info *parent_hfinfo;
12356 unsigned i;
12357 bool_Bool open_object = true1;
12358 const char* prev_proto = NULL((void*)0);
12359 char* str;
12360 char** protos = NULL((void*)0);
12361 char* proto;
12362 bool_Bool found;
12363 unsigned j;
12364 char* type;
12365 char* prev_item = NULL((void*)0);
12366
12367 /* We have filtering protocols. Extract them. */
12368 if (filter) {
12369 protos = g_strsplit(filter, ",", -1);
12370 }
12371
12372 /*
12373 * To help tracking down the json tree, objects have been appended with a comment:
12374 * n.label -> where n is the indentation level and label the name of the object
12375 */
12376
12377 json_dumper dumper = {
12378 .output_file = stdoutstdout,
12379 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12380 };
12381 json_dumper_begin_object(&dumper); // 1.root
12382 elastic_add_base_mapping(&dumper);
12383
12384 json_dumper_set_member_name(&dumper, "mappings");
12385 json_dumper_begin_object(&dumper); // 2.mappings
12386
12387 json_dumper_set_member_name(&dumper, "properties");
12388 json_dumper_begin_object(&dumper); // 3.properties
12389 json_dumper_set_member_name(&dumper, "timestamp");
12390 json_dumper_begin_object(&dumper); // 4.timestamp
12391 json_dumper_set_member_name(&dumper, "type");
12392 json_dumper_value_string(&dumper, "date");
12393 json_dumper_end_object(&dumper); // 4.timestamp
12394
12395 json_dumper_set_member_name(&dumper, "layers");
12396 json_dumper_begin_object(&dumper); // 4.layers
12397 json_dumper_set_member_name(&dumper, "properties");
12398 json_dumper_begin_object(&dumper); // 5.properties
12399
12400 for (i = 1; i < gpa_hfinfo.len; i++) {
12401 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12402 continue; /* This is a deregistered protocol or header field */
12403
12404 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", 12404
, __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", 12404
, "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", 12404, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12405
12406 /*
12407 * Skip the pseudo-field for "proto_tree_add_text()" since
12408 * we don't want it in the list of filterable protocols.
12409 */
12410 if (hfinfo->id == hf_text_only)
12411 continue;
12412
12413 if (!proto_registrar_is_protocol(i)) {
12414 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", 12414
, __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", 12414
, "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", 12414
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12415
12416 /*
12417 * Skip the field if filter protocols have been set and this one's
12418 * parent is not listed.
12419 */
12420 if (protos) {
12421 found = false0;
12422 j = 0;
12423 proto = protos[0];
12424 while(proto) {
12425 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12426 found = true1;
12427 break;
12428 }
12429 j++;
12430 proto = protos[j];
12431 }
12432 if (!found)
12433 continue;
12434 }
12435
12436 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12437 json_dumper_end_object(&dumper); // 7.properties
12438 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12439 open_object = true1;
12440 }
12441
12442 prev_proto = parent_hfinfo->abbrev;
12443
12444 if (open_object) {
12445 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12446 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12447 json_dumper_set_member_name(&dumper, "properties");
12448 json_dumper_begin_object(&dumper); // 7.properties
12449 open_object = false0;
12450 }
12451 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12452 type = ws_type_to_elastic(hfinfo->type);
12453 /* when type is NULL, we have the default mapping: string */
12454 if (type) {
12455 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12456 dot_to_underscore(str);
12457 if (g_strcmp0(prev_item, str)) {
12458 json_dumper_set_member_name(&dumper, str);
12459 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12460 json_dumper_set_member_name(&dumper, "type");
12461 json_dumper_value_string(&dumper, type);
12462 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12463 }
12464 g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized
(prev_item, __builtin_object_size ((prev_item), 0)) : (g_free
) (prev_item)
;
12465 prev_item = str;
12466 }
12467 }
12468 }
12469 g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized
(prev_item, __builtin_object_size ((prev_item), 0)) : (g_free
) (prev_item)
;
12470
12471 if (prev_proto) {
12472 json_dumper_end_object(&dumper); // 7.properties
12473 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12474 }
12475
12476 json_dumper_end_object(&dumper); // 5.properties
12477 json_dumper_end_object(&dumper); // 4.layers
12478 json_dumper_end_object(&dumper); // 3.properties
12479 json_dumper_end_object(&dumper); // 2.mappings
12480 json_dumper_end_object(&dumper); // 1.root
12481 bool_Bool ret = json_dumper_finish(&dumper);
12482 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12482, "ret"))))
;
12483
12484 g_strfreev(protos);
12485}
12486
12487/* Dumps the contents of the registration database to stdout. An independent
12488 * program can take this output and format it into nice tables or HTML or
12489 * whatever.
12490 *
12491 * There is one record per line. Each record is either a protocol or a header
12492 * field, differentiated by the first field. The fields are tab-delimited.
12493 *
12494 * Protocols
12495 * ---------
12496 * Field 1 = 'P'
12497 * Field 2 = descriptive protocol name
12498 * Field 3 = protocol abbreviation
12499 *
12500 * Header Fields
12501 * -------------
12502 * Field 1 = 'F'
12503 * Field 2 = descriptive field name
12504 * Field 3 = field abbreviation
12505 * Field 4 = type ( textual representation of the ftenum type )
12506 * Field 5 = parent protocol abbreviation
12507 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12508 * Field 7 = bitmask: format: hex: 0x....
12509 * Field 8 = blurb describing field
12510 */
12511void
12512proto_registrar_dump_fields(void)
12513{
12514 header_field_info *hfinfo, *parent_hfinfo;
12515 int i, len;
12516 const char *enum_name;
12517 const char *base_name;
12518 const char *blurb;
12519 char width[5];
12520
12521 len = gpa_hfinfo.len;
12522 for (i = 1; i < len ; i++) {
12523 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12524 continue; /* This is a deregistered protocol or header field */
12525
12526 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", 12526
, __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", 12526
, "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", 12526, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12527
12528 /*
12529 * Skip the pseudo-field for "proto_tree_add_text()" since
12530 * we don't want it in the list of filterable fields.
12531 */
12532 if (hfinfo->id == hf_text_only)
12533 continue;
12534
12535 /* format for protocols */
12536 if (proto_registrar_is_protocol(i)) {
12537 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12538 }
12539 /* format for header fields */
12540 else {
12541 /*
12542 * If this field isn't at the head of the list of
12543 * fields with this name, skip this field - all
12544 * fields with the same name are really just versions
12545 * of the same field stored in different bits, and
12546 * should have the same type/radix/value list, and
12547 * just differ in their bit masks. (If a field isn't
12548 * a bitfield, but can be, say, 1 or 2 bytes long,
12549 * it can just be made FT_UINT16, meaning the
12550 * *maximum* length is 2 bytes, and be used
12551 * for all lengths.)
12552 */
12553 if (hfinfo->same_name_prev_id != -1)
12554 continue;
12555
12556 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", 12556
, __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", 12556
, "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", 12556
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12557
12558 enum_name = ftype_name(hfinfo->type);
12559 base_name = "";
12560
12561 if (hfinfo->type == FT_CHAR ||
12562 hfinfo->type == FT_UINT8 ||
12563 hfinfo->type == FT_UINT16 ||
12564 hfinfo->type == FT_UINT24 ||
12565 hfinfo->type == FT_UINT32 ||
12566 hfinfo->type == FT_UINT40 ||
12567 hfinfo->type == FT_UINT48 ||
12568 hfinfo->type == FT_UINT56 ||
12569 hfinfo->type == FT_UINT64 ||
12570 hfinfo->type == FT_INT8 ||
12571 hfinfo->type == FT_INT16 ||
12572 hfinfo->type == FT_INT24 ||
12573 hfinfo->type == FT_INT32 ||
12574 hfinfo->type == FT_INT40 ||
12575 hfinfo->type == FT_INT48 ||
12576 hfinfo->type == FT_INT56 ||
12577 hfinfo->type == FT_INT64) {
12578
12579 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12580 case BASE_NONE:
12581 case BASE_DEC:
12582 case BASE_HEX:
12583 case BASE_OCT:
12584 case BASE_DEC_HEX:
12585 case BASE_HEX_DEC:
12586 case BASE_CUSTOM:
12587 case BASE_PT_UDP:
12588 case BASE_PT_TCP:
12589 case BASE_PT_DCCP:
12590 case BASE_PT_SCTP:
12591 case BASE_OUI:
12592 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12593 break;
12594 default:
12595 base_name = "????";
12596 break;
12597 }
12598 } else if (hfinfo->type == FT_BOOLEAN) {
12599 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12600 snprintf(width, sizeof(width), "%d", hfinfo->display);
12601 base_name = width;
12602 }
12603
12604 blurb = hfinfo->blurb;
12605 if (blurb == NULL((void*)0))
12606 blurb = "";
12607 else if (strlen(blurb) == 0)
12608 blurb = "\"\"";
12609
12610 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12611 hfinfo->name, hfinfo->abbrev, enum_name,
12612 parent_hfinfo->abbrev, base_name,
12613 hfinfo->bitmask, blurb);
12614 }
12615 }
12616}
12617
12618/* Dumps all abbreviated field and protocol completions of the given string to
12619 * stdout. An independent program may use this for command-line tab completion
12620 * of fields.
12621 */
12622bool_Bool
12623proto_registrar_dump_field_completions(const char *prefix)
12624{
12625 header_field_info *hfinfo;
12626 int i, len;
12627 size_t prefix_len;
12628 bool_Bool matched = false0;
12629
12630 prefix_len = strlen(prefix);
12631 len = gpa_hfinfo.len;
12632 for (i = 1; i < len ; i++) {
12633 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12634 continue; /* This is a deregistered protocol or header field */
12635
12636 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", 12636
, __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", 12636
, "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", 12636, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12637
12638 /*
12639 * Skip the pseudo-field for "proto_tree_add_text()" since
12640 * we don't want it in the list of filterable fields.
12641 */
12642 if (hfinfo->id == hf_text_only)
12643 continue;
12644
12645 /* format for protocols */
12646 if (proto_registrar_is_protocol(i)) {
12647 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12648 matched = true1;
12649 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12650 }
12651 }
12652 /* format for header fields */
12653 else {
12654 /*
12655 * If this field isn't at the head of the list of
12656 * fields with this name, skip this field - all
12657 * fields with the same name are really just versions
12658 * of the same field stored in different bits, and
12659 * should have the same type/radix/value list, and
12660 * just differ in their bit masks. (If a field isn't
12661 * a bitfield, but can be, say, 1 or 2 bytes long,
12662 * it can just be made FT_UINT16, meaning the
12663 * *maximum* length is 2 bytes, and be used
12664 * for all lengths.)
12665 */
12666 if (hfinfo->same_name_prev_id != -1)
12667 continue;
12668
12669 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12670 matched = true1;
12671 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12672 }
12673 }
12674 }
12675 return matched;
12676}
12677
12678/* Dumps field types and descriptive names to stdout. An independent
12679 * program can take this output and format it into nice tables or HTML or
12680 * whatever.
12681 *
12682 * There is one record per line. The fields are tab-delimited.
12683 *
12684 * Field 1 = field type name, e.g. FT_UINT8
12685 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12686 */
12687void
12688proto_registrar_dump_ftypes(void)
12689{
12690 int fte;
12691
12692 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12693 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12694 }
12695}
12696
12697/* This function indicates whether it's possible to construct a
12698 * "match selected" display filter string for the specified field,
12699 * returns an indication of whether it's possible, and, if it's
12700 * possible and "filter" is non-null, constructs the filter and
12701 * sets "*filter" to point to it.
12702 * You do not need to [g_]free() this string since it will be automatically
12703 * freed once the next packet is dissected.
12704 */
12705static bool_Bool
12706construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12707 char **filter)
12708{
12709 const header_field_info *hfinfo;
12710 int start, length, length_remaining;
12711
12712 if (!finfo)
12713 return false0;
12714
12715 hfinfo = finfo->hfinfo;
12716 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12716, "hfinfo"))))
;
12717
12718 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12719 * then "the numeric value ... is not used when preparing
12720 * filters for the field in question." If it's any other
12721 * base, we'll generate the filter normally (which will
12722 * be numeric, even though the human-readable string does
12723 * work for filtering.)
12724 *
12725 * XXX - It might be nice to use fvalue_to_string_repr() in
12726 * "proto_item_fill_label()" as well, although, there, you'd
12727 * have to deal with the base *and* with resolved values for
12728 * addresses.
12729 *
12730 * Perhaps in addition to taking the repr type (DISPLAY
12731 * or DFILTER) and the display (base), fvalue_to_string_repr()
12732 * should have the the "strings" values in the header_field_info
12733 * structure for the field as a parameter, so it can have
12734 * if the field is Boolean or an enumerated integer type,
12735 * the tables used to generate human-readable values.
12736 */
12737 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12738 const char *str = NULL((void*)0);
12739
12740 switch (hfinfo->type) {
12741
12742 case FT_INT8:
12743 case FT_INT16:
12744 case FT_INT24:
12745 case FT_INT32:
12746 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12747 break;
12748
12749 case FT_CHAR:
12750 case FT_UINT8:
12751 case FT_UINT16:
12752 case FT_UINT24:
12753 case FT_UINT32:
12754 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12755 break;
12756
12757 default:
12758 break;
12759 }
12760
12761 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12762 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12763 return true1;
12764 }
12765 }
12766
12767 switch (hfinfo->type) {
12768
12769 case FT_PROTOCOL:
12770 if (filter != NULL((void*)0))
12771 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12772 break;
12773
12774 case FT_NONE:
12775 /*
12776 * If the length is 0, just match the name of the
12777 * field.
12778 *
12779 * (Also check for negative values, just in case,
12780 * as we'll cast it to an unsigned value later.)
12781 */
12782 length = finfo->length;
12783 if (length == 0) {
12784 if (filter != NULL((void*)0))
12785 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12786 break;
12787 }
12788 if (length < 0)
12789 return false0;
12790
12791 /*
12792 * This doesn't have a value, so we'd match
12793 * on the raw bytes at this address.
12794 *
12795 * Should we be allowed to access to the raw bytes?
12796 * If "edt" is NULL, the answer is "no".
12797 */
12798 if (edt == NULL((void*)0))
12799 return false0;
12800
12801 /*
12802 * Is this field part of the raw frame tvbuff?
12803 * If not, we can't use "frame[N:M]" to match
12804 * it.
12805 *
12806 * XXX - should this be frame-relative, or
12807 * protocol-relative?
12808 *
12809 * XXX - does this fallback for non-registered
12810 * fields even make sense?
12811 */
12812 if (finfo->ds_tvb != edt->tvb)
12813 return false0; /* you lose */
12814
12815 /*
12816 * Don't go past the end of that tvbuff.
12817 */
12818 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12819 if (length > length_remaining)
12820 length = length_remaining;
12821 if (length <= 0)
12822 return false0;
12823
12824 if (filter != NULL((void*)0)) {
12825 start = finfo->start;
12826 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12827 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12828 wmem_free(NULL((void*)0), str);
12829 }
12830 break;
12831
12832 /* By default, use the fvalue's "to_string_repr" method. */
12833 default:
12834 if (filter != NULL((void*)0)) {
12835 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12836 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12837 wmem_free(NULL((void*)0), str);
12838 }
12839 break;
12840 }
12841
12842 return true1;
12843}
12844
12845/*
12846 * Returns true if we can do a "match selected" on the field, false
12847 * otherwise.
12848 */
12849bool_Bool
12850proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12851{
12852 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12853}
12854
12855/* This function attempts to construct a "match selected" display filter
12856 * string for the specified field; if it can do so, it returns a pointer
12857 * to the string, otherwise it returns NULL.
12858 *
12859 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12860 */
12861char *
12862proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12863{
12864 char *filter = NULL((void*)0);
12865
12866 if (!construct_match_selected_string(finfo, edt, &filter))
12867 {
12868 wmem_free(NULL((void*)0), filter);
12869 return NULL((void*)0);
12870 }
12871 return filter;
12872}
12873
12874/* This function is common code for all proto_tree_add_bitmask... functions.
12875 */
12876
12877static bool_Bool
12878proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12879 const unsigned len, const int ett, int * const *fields,
12880 const int flags, bool_Bool first,
12881 bool_Bool use_parent_tree,
12882 proto_tree* tree, uint64_t value)
12883{
12884 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12885 uint64_t bitmask = 0;
12886 uint64_t tmpval;
12887 header_field_info *hf;
12888 uint32_t integer32;
12889 int bit_offset;
12890 int no_of_bits;
12891
12892 if (!*fields)
12893 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"
)
;
12894
12895 if (len > 8)
12896 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12897 /**
12898 * packet-frame.c uses len=0 since the value is taken from the packet
12899 * metadata, not the packet bytes. In that case, assume that all bits
12900 * in the provided value are valid.
12901 */
12902 if (len > 0) {
12903 available_bits >>= (8 - len)*8;
12904 }
12905
12906 if (use_parent_tree == false0)
12907 tree = proto_item_add_subtree(item, ett);
12908
12909 while (*fields) {
12910 uint64_t present_bits;
12911 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", 12911, __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", 12911
, "**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", 12911, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12912 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", 12912
, "hf->bitmask != 0", hf->abbrev))))
;
12913
12914 bitmask |= hf->bitmask;
12915
12916 /* Skip fields that aren't fully present */
12917 present_bits = available_bits & hf->bitmask;
12918 if (present_bits != hf->bitmask) {
12919 fields++;
12920 continue;
12921 }
12922
12923 switch (hf->type) {
12924 case FT_CHAR:
12925 case FT_UINT8:
12926 case FT_UINT16:
12927 case FT_UINT24:
12928 case FT_UINT32:
12929 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12930 break;
12931
12932 case FT_INT8:
12933 case FT_INT16:
12934 case FT_INT24:
12935 case FT_INT32:
12936 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12937 break;
12938
12939 case FT_UINT40:
12940 case FT_UINT48:
12941 case FT_UINT56:
12942 case FT_UINT64:
12943 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12944 break;
12945
12946 case FT_INT40:
12947 case FT_INT48:
12948 case FT_INT56:
12949 case FT_INT64:
12950 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12951 break;
12952
12953 case FT_BOOLEAN:
12954 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12955 break;
12956
12957 default:
12958 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))
12959 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))
12960 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))
12961 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))
;
12962 break;
12963 }
12964 if (flags & BMT_NO_APPEND0x01) {
12965 fields++;
12966 continue;
12967 }
12968 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12969
12970 /* XXX: README.developer and the comments have always defined
12971 * BMT_NO_INT as "only boolean flags are added to the title /
12972 * don't add non-boolean (integral) fields", but the
12973 * implementation has always added BASE_CUSTOM and fields with
12974 * value_strings, though not fields with unit_strings.
12975 * Possibly this is because some dissectors use a FT_UINT8
12976 * with a value_string for fields that should be a FT_BOOLEAN.
12977 */
12978 switch (hf->type) {
12979 case FT_CHAR:
12980 if (hf->display == BASE_CUSTOM) {
12981 char lbl[ITEM_LABEL_LENGTH240];
12982 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_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, (uint32_t) tmpval);
12986 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12987 hf->name, lbl);
12988 first = false0;
12989 }
12990 else if (hf->strings) {
12991 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12992 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12993 first = false0;
12994 }
12995 else if (!(flags & BMT_NO_INT0x02)) {
12996 char buf[32];
12997 const char *out;
12998
12999 if (!first) {
13000 proto_item_append_text(item, ", ");
13001 }
13002
13003 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13004 proto_item_append_text(item, "%s: %s", hf->name, out);
13005 first = false0;
13006 }
13007
13008 break;
13009
13010 case FT_UINT8:
13011 case FT_UINT16:
13012 case FT_UINT24:
13013 case FT_UINT32:
13014 if (hf->display == BASE_CUSTOM) {
13015 char lbl[ITEM_LABEL_LENGTH240];
13016 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13017
13018 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13018, "fmtfunc"))))
;
13019 fmtfunc(lbl, (uint32_t) tmpval);
13020 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13021 hf->name, lbl);
13022 first = false0;
13023 }
13024 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13025 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13026 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13027 first = false0;
13028 }
13029 else if (!(flags & BMT_NO_INT0x02)) {
13030 char buf[NUMBER_LABEL_LENGTH80];
13031 const char *out = NULL((void*)0);
13032
13033 if (!first) {
13034 proto_item_append_text(item, ", ");
13035 }
13036
13037 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13038 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13039 }
13040 if (out == NULL((void*)0)) {
13041 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13042 }
13043 proto_item_append_text(item, "%s: %s", hf->name, out);
13044 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13045 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13046 }
13047 first = false0;
13048 }
13049
13050 break;
13051
13052 case FT_INT8:
13053 case FT_INT16:
13054 case FT_INT24:
13055 case FT_INT32:
13056 integer32 = (uint32_t) tmpval;
13057 if (hf->bitmask) {
13058 no_of_bits = ws_count_ones(hf->bitmask);
13059 integer32 = ws_sign_ext32(integer32, no_of_bits);
13060 }
13061 if (hf->display == BASE_CUSTOM) {
13062 char lbl[ITEM_LABEL_LENGTH240];
13063 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13064
13065 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13065, "fmtfunc"))))
;
13066 fmtfunc(lbl, (int32_t) integer32);
13067 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13068 hf->name, lbl);
13069 first = false0;
13070 }
13071 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13072 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13073 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13074 first = false0;
13075 }
13076 else if (!(flags & BMT_NO_INT0x02)) {
13077 char buf[NUMBER_LABEL_LENGTH80];
13078 const char *out = NULL((void*)0);
13079
13080 if (!first) {
13081 proto_item_append_text(item, ", ");
13082 }
13083
13084 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13085 out = hf_try_val_to_str((int32_t) integer32, hf);
13086 }
13087 if (out == NULL((void*)0)) {
13088 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13089 }
13090 proto_item_append_text(item, "%s: %s", hf->name, out);
13091 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13092 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13093 }
13094 first = false0;
13095 }
13096
13097 break;
13098
13099 case FT_UINT40:
13100 case FT_UINT48:
13101 case FT_UINT56:
13102 case FT_UINT64:
13103 if (hf->display == BASE_CUSTOM) {
13104 char lbl[ITEM_LABEL_LENGTH240];
13105 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13106
13107 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13107, "fmtfunc"))))
;
13108 fmtfunc(lbl, tmpval);
13109 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13110 hf->name, lbl);
13111 first = false0;
13112 }
13113 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13114 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13115 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13116 first = false0;
13117 }
13118 else if (!(flags & BMT_NO_INT0x02)) {
13119 char buf[NUMBER_LABEL_LENGTH80];
13120 const char *out = NULL((void*)0);
13121
13122 if (!first) {
13123 proto_item_append_text(item, ", ");
13124 }
13125
13126 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13127 out = hf_try_val64_to_str(tmpval, hf);
13128 }
13129 if (out == NULL((void*)0)) {
13130 out = hfinfo_number_value_format64(hf, buf, tmpval);
13131 }
13132 proto_item_append_text(item, "%s: %s", hf->name, out);
13133 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13134 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13135 }
13136 first = false0;
13137 }
13138
13139 break;
13140
13141 case FT_INT40:
13142 case FT_INT48:
13143 case FT_INT56:
13144 case FT_INT64:
13145 if (hf->bitmask) {
13146 no_of_bits = ws_count_ones(hf->bitmask);
13147 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13148 }
13149 if (hf->display == BASE_CUSTOM) {
13150 char lbl[ITEM_LABEL_LENGTH240];
13151 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13152
13153 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13153, "fmtfunc"))))
;
13154 fmtfunc(lbl, (int64_t) tmpval);
13155 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13156 hf->name, lbl);
13157 first = false0;
13158 }
13159 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13160 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13161 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13162 first = false0;
13163 }
13164 else if (!(flags & BMT_NO_INT0x02)) {
13165 char buf[NUMBER_LABEL_LENGTH80];
13166 const char *out = NULL((void*)0);
13167
13168 if (!first) {
13169 proto_item_append_text(item, ", ");
13170 }
13171
13172 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13173 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13174 }
13175 if (out == NULL((void*)0)) {
13176 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13177 }
13178 proto_item_append_text(item, "%s: %s", hf->name, out);
13179 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13180 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13181 }
13182 first = false0;
13183 }
13184
13185 break;
13186
13187 case FT_BOOLEAN:
13188 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13189 /* If we have true/false strings, emit full - otherwise messages
13190 might look weird */
13191 const struct true_false_string *tfs =
13192 (const struct true_false_string *)hf->strings;
13193
13194 if (tmpval) {
13195 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13196 hf->name, tfs->true_string);
13197 first = false0;
13198 } else if (!(flags & BMT_NO_FALSE0x04)) {
13199 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13200 hf->name, tfs->false_string);
13201 first = false0;
13202 }
13203 } else if (hf->bitmask & value) {
13204 /* If the flag is set, show the name */
13205 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13206 first = false0;
13207 }
13208 break;
13209 default:
13210 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))
13211 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))
13212 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))
13213 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))
;
13214 break;
13215 }
13216
13217 fields++;
13218 }
13219
13220 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13221 * but then again most dissectors don't set the bitmask field for
13222 * the higher level bitmask hfi, so calculate the bitmask from the
13223 * fields present. */
13224 if (item) {
13225 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13226 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13227 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)
;
13228 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)
;
13229 }
13230 return first;
13231}
13232
13233/* This function will dissect a sequence of bytes that describe a
13234 * bitmask and supply the value of that sequence through a pointer.
13235 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13236 * to be dissected.
13237 * This field will form an expansion under which the individual fields of the
13238 * bitmask is dissected and displayed.
13239 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13240 *
13241 * fields is an array of pointers to int that lists all the fields of the
13242 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13243 * or another integer of the same type/size as hf_hdr with a mask specified.
13244 * This array is terminated by a NULL entry.
13245 *
13246 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13247 * FT_integer fields that have a value_string attached will have the
13248 * matched string displayed on the expansion line.
13249 */
13250proto_item *
13251proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13252 const unsigned offset, const int hf_hdr,
13253 const int ett, int * const *fields,
13254 const unsigned encoding, uint64_t *retval)
13255{
13256 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);
13257}
13258
13259/* This function will dissect a sequence of bytes that describe a
13260 * bitmask.
13261 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13262 * to be dissected.
13263 * This field will form an expansion under which the individual fields of the
13264 * bitmask is dissected and displayed.
13265 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13266 *
13267 * fields is an array of pointers to int that lists all the fields of the
13268 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13269 * or another integer of the same type/size as hf_hdr with a mask specified.
13270 * This array is terminated by a NULL entry.
13271 *
13272 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13273 * FT_integer fields that have a value_string attached will have the
13274 * matched string displayed on the expansion line.
13275 */
13276proto_item *
13277proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13278 const unsigned offset, const int hf_hdr,
13279 const int ett, int * const *fields,
13280 const unsigned encoding)
13281{
13282 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13283}
13284
13285/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13286 * what data is appended to the header.
13287 */
13288proto_item *
13289proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13290 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13291 uint64_t *retval)
13292{
13293 proto_item *item = NULL((void*)0);
13294 header_field_info *hf;
13295 unsigned len;
13296 uint64_t value;
13297
13298 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", 13298, __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", 13298
, "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", 13298, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13299 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", 13299, (hf)->abbrev)))
;
13300 len = ftype_wire_size(hf->type);
13301 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13302
13303 if (parent_tree) {
13304 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13305 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13306 flags, false0, false0, NULL((void*)0), value);
13307 }
13308
13309 *retval = value;
13310 if (hf->bitmask) {
13311 /* Mask out irrelevant portions */
13312 *retval &= hf->bitmask;
13313 /* Shift bits */
13314 *retval >>= hfinfo_bitshift(hf);
13315 }
13316
13317 return item;
13318}
13319
13320/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13321 * what data is appended to the header.
13322 */
13323proto_item *
13324proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13325 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13326{
13327 proto_item *item = NULL((void*)0);
13328 header_field_info *hf;
13329 unsigned len;
13330 uint64_t value;
13331
13332 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", 13332, __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", 13332
, "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", 13332, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13333 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", 13333, (hf)->abbrev)))
;
13334
13335 if (parent_tree) {
13336 len = ftype_wire_size(hf->type);
13337 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13338 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13339 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13340 flags, false0, false0, NULL((void*)0), value);
13341 }
13342
13343 return item;
13344}
13345
13346/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13347 can't be retrieved directly from tvb) */
13348proto_item *
13349proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13350 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13351{
13352 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13353 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13354}
13355
13356/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13357WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13358proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13359 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13360{
13361 proto_item *item = NULL((void*)0);
13362 header_field_info *hf;
13363 unsigned len;
13364
13365 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", 13365, __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", 13365
, "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", 13365, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13366 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", 13366, (hf)->abbrev)))
;
13367 /* the proto_tree_add_uint/_uint64() calls below
13368 will fail if tvb==NULL and len!=0 */
13369 len = tvb ? ftype_wire_size(hf->type) : 0;
13370
13371 if (parent_tree) {
13372 if (len <= 4)
13373 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13374 else
13375 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13376
13377 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13378 flags, false0, false0, NULL((void*)0), value);
13379 }
13380
13381 return item;
13382}
13383
13384/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13385void
13386proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13387 const unsigned len, int * const *fields, const unsigned encoding)
13388{
13389 uint64_t value;
13390
13391 if (tree) {
13392 value = get_uint64_value(tree, tvb, offset, len, encoding);
13393 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13394 BMT_NO_APPEND0x01, false0, true1, tree, value);
13395 }
13396}
13397
13398WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13399proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13400 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13401{
13402 uint64_t value;
13403
13404 value = get_uint64_value(tree, tvb, offset, len, encoding);
13405 if (tree) {
13406 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13407 BMT_NO_APPEND0x01, false0, true1, tree, value);
13408 }
13409 if (retval) {
13410 *retval = value;
13411 }
13412}
13413
13414WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13415proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13416 const unsigned len, int * const *fields, const uint64_t value)
13417{
13418 if (tree) {
13419 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13420 BMT_NO_APPEND0x01, false0, true1, tree, value);
13421 }
13422}
13423
13424
13425/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13426 * This is intended to support bitmask fields whose lengths can vary, perhaps
13427 * as the underlying standard evolves over time.
13428 * With this API there is the possibility of being called to display more or
13429 * less data than the dissector was coded to support.
13430 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13431 * Thus when presented with "too much" or "too little" data, MSbits will be
13432 * ignored or MSfields sacrificed.
13433 *
13434 * Only fields for which all defined bits are available are displayed.
13435 */
13436proto_item *
13437proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13438 const unsigned offset, const unsigned len, const int hf_hdr,
13439 const int ett, int * const *fields, struct expert_field* exp,
13440 const unsigned encoding)
13441{
13442 proto_item *item = NULL((void*)0);
13443 header_field_info *hf;
13444 unsigned decodable_len;
13445 unsigned decodable_offset;
13446 uint32_t decodable_value;
13447 uint64_t value;
13448
13449 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", 13449, __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", 13449
, "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", 13449, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13450 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", 13450, (hf)->abbrev)))
;
13451
13452 decodable_offset = offset;
13453 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13454
13455 /* If we are ftype_wire_size-limited,
13456 * make sure we decode as many LSBs as possible.
13457 */
13458 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13459 decodable_offset += (len - decodable_len);
13460 }
13461
13462 if (parent_tree) {
13463 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13464 decodable_len, encoding);
13465
13466 /* The root item covers all the bytes even if we can't decode them all */
13467 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13468 decodable_value);
13469 }
13470
13471 if (decodable_len < len) {
13472 /* Dissector likely requires updating for new protocol revision */
13473 expert_add_info_format(NULL((void*)0), item, exp,
13474 "Only least-significant %d of %d bytes decoded",
13475 decodable_len, len);
13476 }
13477
13478 if (item) {
13479 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13480 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13481 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13482 }
13483
13484 return item;
13485}
13486
13487/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13488proto_item *
13489proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13490 const unsigned offset, const unsigned len,
13491 const char *name, const char *fallback,
13492 const int ett, int * const *fields,
13493 const unsigned encoding, const int flags)
13494{
13495 proto_item *item = NULL((void*)0);
13496 uint64_t value;
13497
13498 if (parent_tree) {
13499 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13500 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13501 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13502 flags, true1, false0, NULL((void*)0), value) && fallback) {
13503 /* Still at first item - append 'fallback' text if any */
13504 proto_item_append_text(item, "%s", fallback);
13505 }
13506 }
13507
13508 return item;
13509}
13510
13511proto_item *
13512proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13513 const unsigned bit_offset, const int no_of_bits,
13514 const unsigned encoding)
13515{
13516 header_field_info *hfinfo;
13517 int octet_length;
13518 unsigned octet_offset;
13519
13520 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", 13520, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13520
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13520, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13521
13522 if (no_of_bits < 0) {
13523 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13524 }
13525 octet_length = (no_of_bits + 7) >> 3;
13526 octet_offset = bit_offset >> 3;
13527 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13528
13529 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13530 * but only after doing a bunch more work (which we can, in the common
13531 * case, shortcut here).
13532 */
13533 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13534 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", 13534
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13534, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13534, "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", 13534, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13535
13536 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13537}
13538
13539/*
13540 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13541 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13542 * Offset should be given in bits from the start of the tvb.
13543 */
13544
13545static proto_item *
13546_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13547 const unsigned bit_offset, const int no_of_bits,
13548 uint64_t *return_value, const unsigned encoding)
13549{
13550 unsigned offset;
13551 unsigned length;
13552 uint8_t tot_no_bits;
13553 char *bf_str;
13554 char lbl_str[ITEM_LABEL_LENGTH240];
13555 uint64_t value = 0;
13556 uint8_t *bytes = NULL((void*)0);
13557 size_t bytes_length = 0;
13558
13559 proto_item *pi;
13560 header_field_info *hf_field;
13561
13562 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13563 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", 13563, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13563
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13563, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13564
13565 if (hf_field->bitmask != 0) {
13566 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)
13567 " 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)
13568 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)
;
13569 }
13570
13571 if (no_of_bits < 0) {
13572 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13573 } else if (no_of_bits == 0) {
13574 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)
13575 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)
;
13576 }
13577
13578 /* Byte align offset */
13579 offset = bit_offset>>3;
13580
13581 /*
13582 * Calculate the number of octets used to hold the bits
13583 */
13584 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13585 length = (tot_no_bits + 7) >> 3;
13586
13587 if (no_of_bits < 65) {
13588 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13589 } else if (hf_field->type != FT_BYTES) {
13590 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)
13591 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)
;
13592 return NULL((void*)0);
13593 }
13594
13595 /* Sign extend for signed types */
13596 switch (hf_field->type) {
13597 case FT_INT8:
13598 case FT_INT16:
13599 case FT_INT24:
13600 case FT_INT32:
13601 case FT_INT40:
13602 case FT_INT48:
13603 case FT_INT56:
13604 case FT_INT64:
13605 value = ws_sign_ext64(value, no_of_bits);
13606 break;
13607
13608 default:
13609 break;
13610 }
13611
13612 if (return_value) {
13613 *return_value = value;
13614 }
13615
13616 /* Coast clear. Try and fake it */
13617 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13618 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", 13618
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13618, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13618, "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", 13618, __func__, "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); } } }
;
13619
13620 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13621
13622 switch (hf_field->type) {
13623 case FT_BOOLEAN:
13624 /* Boolean field */
13625 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13626 "%s = %s: %s",
13627 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13628 break;
13629
13630 case FT_CHAR:
13631 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13632 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13633 break;
13634
13635 case FT_UINT8:
13636 case FT_UINT16:
13637 case FT_UINT24:
13638 case FT_UINT32:
13639 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13640 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13641 break;
13642
13643 case FT_INT8:
13644 case FT_INT16:
13645 case FT_INT24:
13646 case FT_INT32:
13647 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13648 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13649 break;
13650
13651 case FT_UINT40:
13652 case FT_UINT48:
13653 case FT_UINT56:
13654 case FT_UINT64:
13655 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13656 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13657 break;
13658
13659 case FT_INT40:
13660 case FT_INT48:
13661 case FT_INT56:
13662 case FT_INT64:
13663 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13664 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13665 break;
13666
13667 case FT_BYTES:
13668 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13669 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13670 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13671 proto_item_set_text(pi, "%s", lbl_str);
13672 return pi;
13673
13674 /* TODO: should handle FT_UINT_BYTES ? */
13675
13676 default:
13677 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))
13678 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))
13679 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))
13680 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))
;
13681 return NULL((void*)0);
13682 }
13683
13684 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13685 return pi;
13686}
13687
13688proto_item *
13689proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13690 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13691 uint64_t *return_value)
13692{
13693 proto_item *pi;
13694 int no_of_bits;
13695 unsigned octet_offset;
13696 unsigned mask_initial_bit_offset;
13697 unsigned mask_greatest_bit_offset;
13698 unsigned octet_length;
13699 uint8_t i;
13700 char bf_str[256];
13701 char lbl_str[ITEM_LABEL_LENGTH240];
13702 uint64_t value;
13703 uint64_t composite_bitmask;
13704 uint64_t composite_bitmap;
13705
13706 header_field_info *hf_field;
13707
13708 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13709 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", 13709, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13709
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13709, "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
13710
13711 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13712 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)
13713 " 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)
13714 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)
;
13715 }
13716
13717 mask_initial_bit_offset = bit_offset % 8;
13718
13719 no_of_bits = 0;
13720 value = 0;
13721 i = 0;
13722 mask_greatest_bit_offset = 0;
13723 composite_bitmask = 0;
13724 composite_bitmap = 0;
13725
13726 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
13727 uint64_t crumb_mask, crumb_value;
13728 uint8_t crumb_end_bit_offset;
13729
13730 crumb_value = tvb_get_bits64(tvb,
13731 bit_offset + crumb_spec[i].crumb_bit_offset,
13732 crumb_spec[i].crumb_bit_length,
13733 ENC_BIG_ENDIAN0x00000000);
13734 value += crumb_value;
13735 no_of_bits += crumb_spec[i].crumb_bit_length;
13736 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", 13736
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13737
13738 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13739 octet containing the initial offset.
13740 If the mask is beyond 32 bits, then give up on bit map display.
13741 This could be improved in future, probably showing a table
13742 of 32 or 64 bits per row */
13743 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13744 crumb_end_bit_offset = mask_initial_bit_offset
13745 + crumb_spec[i].crumb_bit_offset
13746 + crumb_spec[i].crumb_bit_length;
13747 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'
13748
13749 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13750 mask_greatest_bit_offset = crumb_end_bit_offset;
13751 }
13752 /* Currently the bitmap of the crumbs are only shown if
13753 * smaller than 32 bits. Do not bother calculating the
13754 * mask if it is larger than that. */
13755 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13756 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'
13757 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13758 }
13759 }
13760 /* Shift left for the next segment */
13761 value <<= crumb_spec[++i].crumb_bit_length;
13762 }
13763
13764 /* Sign extend for signed types */
13765 switch (hf_field->type) {
13766 case FT_INT8:
13767 case FT_INT16:
13768 case FT_INT24:
13769 case FT_INT32:
13770 case FT_INT40:
13771 case FT_INT48:
13772 case FT_INT56:
13773 case FT_INT64:
13774 value = ws_sign_ext64(value, no_of_bits);
13775 break;
13776 default:
13777 break;
13778 }
13779
13780 if (return_value) {
13781 *return_value = value;
13782 }
13783
13784 /* Coast clear. Try and fake it */
13785 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13786 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", 13786
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13786, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13786, "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", 13786, __func__, "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); } } }
;
13787
13788 /* initialise the format string */
13789 bf_str[0] = '\0';
13790
13791 octet_offset = bit_offset >> 3;
13792
13793 /* Round up mask length to nearest octet */
13794 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13795 mask_greatest_bit_offset = octet_length << 3;
13796
13797 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13798 It would be a useful enhancement to eliminate this restriction. */
13799 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13800 other_decode_bitfield_value(bf_str,
13801 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13802 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13803 mask_greatest_bit_offset);
13804 } else {
13805 /* If the bitmask is too large, try to describe its contents. */
13806 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13807 }
13808
13809 switch (hf_field->type) {
13810 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13811 /* Boolean field */
13812 return proto_tree_add_boolean_format(tree, hfindex,
13813 tvb, octet_offset, octet_length, value,
13814 "%s = %s: %s",
13815 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13816 break;
13817
13818 case FT_CHAR:
13819 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13820 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13821 break;
13822
13823 case FT_UINT8:
13824 case FT_UINT16:
13825 case FT_UINT24:
13826 case FT_UINT32:
13827 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13828 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13829 break;
13830
13831 case FT_INT8:
13832 case FT_INT16:
13833 case FT_INT24:
13834 case FT_INT32:
13835 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13836 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13837 break;
13838
13839 case FT_UINT40:
13840 case FT_UINT48:
13841 case FT_UINT56:
13842 case FT_UINT64:
13843 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13844 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13845 break;
13846
13847 case FT_INT40:
13848 case FT_INT48:
13849 case FT_INT56:
13850 case FT_INT64:
13851 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13852 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13853 break;
13854
13855 default:
13856 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))
13857 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))
13858 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))
13859 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))
;
13860 return NULL((void*)0);
13861 }
13862 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13863 return pi;
13864}
13865
13866void
13867proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13868 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13869{
13870 header_field_info *hfinfo;
13871 unsigned start = bit_offset >> 3;
13872 unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13873
13874 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13875 * so that we can use the tree's memory scope in calculating the string */
13876 tvb_ensure_bytes_exist(tvb, start, length);
13877 if (!tree) return;
13878
13879 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", 13879, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13879
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13879, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13880 proto_tree_add_text_internal(tree, tvb, start, length,
13881 "%s crumb %d of %s (decoded above)",
13882 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13883 tvb_get_bits32(tvb,
13884 bit_offset,
13885 crumb_spec[crumb_index].crumb_bit_length,
13886 ENC_BIG_ENDIAN0x00000000),
13887 ENC_BIG_ENDIAN0x00000000),
13888 crumb_index,
13889 hfinfo->name);
13890}
13891
13892proto_item *
13893proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13894 const unsigned bit_offset, const int no_of_bits,
13895 uint64_t *return_value, const unsigned encoding)
13896{
13897 proto_item *item;
13898
13899 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13900 bit_offset, no_of_bits,
13901 return_value, encoding))) {
13902 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)
;
13903 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)
;
13904 }
13905 return item;
13906}
13907
13908static proto_item *
13909_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13910 tvbuff_t *tvb, const unsigned bit_offset,
13911 const int no_of_bits, void *value_ptr,
13912 const unsigned encoding, char *value_str)
13913{
13914 unsigned offset;
13915 unsigned length;
13916 uint8_t tot_no_bits;
13917 char *str;
13918 uint64_t value = 0;
13919 header_field_info *hf_field;
13920
13921 /* We do not have to return a value, try to fake it as soon as possible */
13922 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13923 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", 13923
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13923, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13923, "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", 13923, __func__, "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); } } }
;
13924
13925 if (hf_field->bitmask != 0) {
13926 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)
13927 " 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)
13928 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)
;
13929 }
13930
13931 if (no_of_bits < 0) {
13932 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13933 } else if (no_of_bits == 0) {
13934 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)
13935 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)
;
13936 }
13937
13938 /* Byte align offset */
13939 offset = bit_offset>>3;
13940
13941 /*
13942 * Calculate the number of octets used to hold the bits
13943 */
13944 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13945 length = tot_no_bits>>3;
13946 /* If we are using part of the next octet, increase length by 1 */
13947 if (tot_no_bits & 0x07)
13948 length++;
13949
13950 if (no_of_bits < 65) {
13951 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13952 } else {
13953 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)
13954 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)
;
13955 return NULL((void*)0);
13956 }
13957
13958 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13959
13960 (void) g_strlcat(str, " = ", 256+64);
13961 (void) g_strlcat(str, hf_field->name, 256+64);
13962
13963 /*
13964 * This function does not receive an actual value but a dimensionless pointer to that value.
13965 * For this reason, the type of the header field is examined in order to determine
13966 * what kind of value we should read from this address.
13967 * The caller of this function must make sure that for the specific header field type the address of
13968 * a compatible value is provided.
13969 */
13970 switch (hf_field->type) {
13971 case FT_BOOLEAN:
13972 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13973 "%s: %s", str, value_str);
13974 break;
13975
13976 case FT_CHAR:
13977 case FT_UINT8:
13978 case FT_UINT16:
13979 case FT_UINT24:
13980 case FT_UINT32:
13981 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13982 "%s: %s", str, value_str);
13983 break;
13984
13985 case FT_UINT40:
13986 case FT_UINT48:
13987 case FT_UINT56:
13988 case FT_UINT64:
13989 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13990 "%s: %s", str, value_str);
13991 break;
13992
13993 case FT_INT8:
13994 case FT_INT16:
13995 case FT_INT24:
13996 case FT_INT32:
13997 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13998 "%s: %s", str, value_str);
13999 break;
14000
14001 case FT_INT40:
14002 case FT_INT48:
14003 case FT_INT56:
14004 case FT_INT64:
14005 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14006 "%s: %s", str, value_str);
14007 break;
14008
14009 case FT_FLOAT:
14010 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14011 "%s: %s", str, value_str);
14012 break;
14013
14014 default:
14015 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))
14016 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))
14017 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))
14018 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))
;
14019 return NULL((void*)0);
14020 }
14021}
14022
14023static proto_item *
14024proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14025 tvbuff_t *tvb, const unsigned bit_offset,
14026 const int no_of_bits, void *value_ptr,
14027 const unsigned encoding, char *value_str)
14028{
14029 proto_item *item;
14030
14031 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14032 tvb, bit_offset, no_of_bits,
14033 value_ptr, encoding, value_str))) {
14034 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)
;
14035 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)
;
14036 }
14037 return item;
14038}
14039
14040#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);
\
14041 va_start(ap, format)__builtin_va_start(ap, format); \
14042 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14043 va_end(ap)__builtin_va_end(ap);
14044
14045proto_item *
14046proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14047 tvbuff_t *tvb, const unsigned bit_offset,
14048 const int no_of_bits, uint32_t value,
14049 const unsigned encoding,
14050 const char *format, ...)
14051{
14052 va_list ap;
14053 char *dst;
14054 header_field_info *hf_field;
14055
14056 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14057
14058 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", 14058
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14058, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14058, "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", 14058, __func__, "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); } } }
;
14059
14060 switch (hf_field->type) {
14061 case FT_UINT8:
14062 case FT_UINT16:
14063 case FT_UINT24:
14064 case FT_UINT32:
14065 break;
14066
14067 default:
14068 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)
14069 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)
;
14070 return NULL((void*)0);
14071 }
14072
14073 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);
;
14074
14075 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14076}
14077
14078proto_item *
14079proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14080 tvbuff_t *tvb, const unsigned bit_offset,
14081 const int no_of_bits, uint64_t value,
14082 const unsigned encoding,
14083 const char *format, ...)
14084{
14085 va_list ap;
14086 char *dst;
14087 header_field_info *hf_field;
14088
14089 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14090
14091 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", 14091
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14091, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14091, "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", 14091, __func__, "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); } } }
;
14092
14093 switch (hf_field->type) {
14094 case FT_UINT40:
14095 case FT_UINT48:
14096 case FT_UINT56:
14097 case FT_UINT64:
14098 break;
14099
14100 default:
14101 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)
14102 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)
;
14103 return NULL((void*)0);
14104 }
14105
14106 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);
;
14107
14108 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14109}
14110
14111proto_item *
14112proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14113 tvbuff_t *tvb, const unsigned bit_offset,
14114 const int no_of_bits, float value,
14115 const unsigned encoding,
14116 const char *format, ...)
14117{
14118 va_list ap;
14119 char *dst;
14120 header_field_info *hf_field;
14121
14122 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14123
14124 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", 14124
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14124, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14124, "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", 14124, __func__, "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); } } }
;
14125
14126 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",
14126, ((hf_field))->abbrev))))
;
14127
14128 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);
;
14129
14130 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14131}
14132
14133proto_item *
14134proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14135 tvbuff_t *tvb, const unsigned bit_offset,
14136 const int no_of_bits, int32_t value,
14137 const unsigned encoding,
14138 const char *format, ...)
14139{
14140 va_list ap;
14141 char *dst;
14142 header_field_info *hf_field;
14143
14144 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14145
14146 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", 14146
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14146, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14146, "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", 14146, __func__, "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); } } }
;
14147
14148 switch (hf_field->type) {
14149 case FT_INT8:
14150 case FT_INT16:
14151 case FT_INT24:
14152 case FT_INT32:
14153 break;
14154
14155 default:
14156 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)
14157 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)
;
14158 return NULL((void*)0);
14159 }
14160
14161 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);
;
14162
14163 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14164}
14165
14166proto_item *
14167proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14168 tvbuff_t *tvb, const unsigned bit_offset,
14169 const int no_of_bits, int64_t value,
14170 const unsigned encoding,
14171 const char *format, ...)
14172{
14173 va_list ap;
14174 char *dst;
14175 header_field_info *hf_field;
14176
14177 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14178
14179 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", 14179
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14179, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14179, "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", 14179, __func__, "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); } } }
;
14180
14181 switch (hf_field->type) {
14182 case FT_INT40:
14183 case FT_INT48:
14184 case FT_INT56:
14185 case FT_INT64:
14186 break;
14187
14188 default:
14189 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)
14190 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)
;
14191 return NULL((void*)0);
14192 }
14193
14194 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);
;
14195
14196 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14197}
14198
14199proto_item *
14200proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14201 tvbuff_t *tvb, const unsigned bit_offset,
14202 const int no_of_bits, uint64_t value,
14203 const unsigned encoding,
14204 const char *format, ...)
14205{
14206 va_list ap;
14207 char *dst;
14208 header_field_info *hf_field;
14209
14210 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14211
14212 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", 14212
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14212, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14212, "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", 14212, __func__, "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); } } }
;
14213
14214 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"
, 14214, ((hf_field))->abbrev))))
;
14215
14216 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);
;
14217
14218 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14219}
14220
14221proto_item *
14222proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14223 const unsigned bit_offset, const int no_of_chars)
14224{
14225 proto_item *pi;
14226 header_field_info *hfinfo;
14227 int byte_length;
14228 unsigned byte_offset;
14229 char *string;
14230
14231 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14232
14233 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", 14233
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14233, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14233, "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", 14233, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14234
14235 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"
, 14235, ((hfinfo))->abbrev))))
;
14236
14237 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14238 byte_offset = bit_offset >> 3;
14239
14240 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14241
14242 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14243 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14243, "byte_length >= 0"
))))
;
14244 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14245
14246 return pi;
14247}
14248
14249proto_item *
14250proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14251 const unsigned bit_offset, const int no_of_chars)
14252{
14253 proto_item *pi;
14254 header_field_info *hfinfo;
14255 int byte_length;
14256 unsigned byte_offset;
14257 char *string;
14258
14259 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14260
14261 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", 14261
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14261, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14261, "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", 14261, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14262
14263 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"
, 14263, ((hfinfo))->abbrev))))
;
14264
14265 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14266 byte_offset = bit_offset >> 3;
14267
14268 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14269
14270 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14271 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14271, "byte_length >= 0"
))))
;
14272 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14273
14274 return pi;
14275}
14276
14277const value_string proto_checksum_vals[] = {
14278 { PROTO_CHECKSUM_E_BAD, "Bad" },
14279 { PROTO_CHECKSUM_E_GOOD, "Good" },
14280 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14281 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14282 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14283
14284 { 0, NULL((void*)0) }
14285};
14286
14287#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14288
14289proto_item *
14290proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14291 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14292 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14293{
14294 header_field_info *hfinfo;
14295 uint32_t checksum;
14296 uint32_t len;
14297 proto_item* ti = NULL((void*)0);
14298 proto_item* ti2;
14299 bool_Bool incorrect_checksum = true1;
14300
14301 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", 14301, __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", 14301
, "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", 14301, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14302
14303 switch (hfinfo->type) {
14304 case FT_UINT8:
14305 len = 1;
14306 break;
14307 case FT_UINT16:
14308 len = 2;
14309 break;
14310 case FT_UINT24:
14311 len = 3;
14312 break;
14313 case FT_UINT32:
14314 len = 4;
14315 break;
14316 default:
14317 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)
14318 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14319 }
14320
14321 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14322 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14323 proto_item_set_generated(ti);
14324 // Backward compatible with use of -1
14325 if (hf_checksum_status > 0) {
14326 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14327 proto_item_set_generated(ti2);
14328 }
14329 return ti;
14330 }
14331
14332 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14333 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14334 proto_item_set_generated(ti);
14335 } else {
14336 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14337 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14338 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14339 if (computed_checksum == 0) {
14340 proto_item_append_text(ti, " [correct]");
14341 // Backward compatible with use of -1
14342 if (hf_checksum_status > 0) {
14343 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14344 proto_item_set_generated(ti2);
14345 }
14346 incorrect_checksum = false0;
14347 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14348 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14349 /* XXX - This can't distinguish between "shouldbe"
14350 * 0x0000 and 0xFFFF unless we know whether there
14351 * were any nonzero bits (other than the checksum).
14352 * Protocols should not use this path if they might
14353 * have an all zero packet.
14354 * Some implementations put the wrong zero; maybe
14355 * we should have a special expert info for that?
14356 */
14357 }
14358 } else {
14359 if (checksum == computed_checksum) {
14360 proto_item_append_text(ti, " [correct]");
14361 // Backward compatible with use of -1
14362 if (hf_checksum_status > 0) {
14363 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14364 proto_item_set_generated(ti2);
14365 }
14366 incorrect_checksum = false0;
14367 }
14368 }
14369
14370 if (incorrect_checksum) {
14371 // Backward compatible with use of -1
14372 if (hf_checksum_status > 0) {
14373 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14374 proto_item_set_generated(ti2);
14375 }
14376 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14377 proto_item_append_text(ti, " [incorrect]");
14378 if (bad_checksum_expert != NULL((void*)0))
14379 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14380 } else {
14381 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14382 if (bad_checksum_expert != NULL((void*)0))
14383 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);
14384 }
14385 }
14386 } else {
14387 // Backward compatible with use of -1
14388 if (hf_checksum_status > 0) {
14389 proto_item_append_text(ti, " [unverified]");
14390 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14391 proto_item_set_generated(ti2);
14392 }
14393 }
14394 }
14395
14396 return ti;
14397}
14398
14399proto_item *
14400proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14401 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14402 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14403{
14404 header_field_info *hfinfo;
14405 uint8_t *checksum = NULL((void*)0);
14406 proto_item* ti = NULL((void*)0);
14407 proto_item* ti2;
14408 bool_Bool incorrect_checksum = true1;
14409
14410 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", 14410, __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", 14410
, "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", 14410, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14411
14412 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",
14412, ((hfinfo))->abbrev))))
;
14413
14414 /* Make sure a NULL computed_checksum isn't dereferenced.
14415 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14416 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14417 * cases the behavior is unexpected and still a programmer error;
14418 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14419 * _NOT_PRESENT nor _GENERATED is correct.
14420 */
14421 DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS))((void) ((computed_checksum || ((flags & (0x01|0x02|0x10)
) == 0x00)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 14421, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14422
14423 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14424 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14425 proto_item_set_generated(ti);
14426 // Backward compatible with use of -1
14427 if (hf_checksum_status > 0) {
14428 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14429 proto_item_set_generated(ti2);
14430 }
14431 return ti;
14432 }
14433
14434 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14435 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14436 proto_item_set_generated(ti);
14437 return ti;
14438 }
14439
14440 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14441 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14442 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14443 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14444 bool_Bool non_zero_flag = false0;
14445 for (size_t index = 0; index < checksum_len; index++) {
14446 if (computed_checksum[index]) {
14447 non_zero_flag = true1;
14448 break;
14449 }
14450 }
14451 if (!non_zero_flag) {
14452 proto_item_append_text(ti, " [correct]");
14453 // Backward compatible with use of -1
14454 if (hf_checksum_status > 0) {
14455 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14456 proto_item_set_generated(ti2);
14457 }
14458 incorrect_checksum = false0;
14459 }
14460 } else {
14461 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14462 proto_item_append_text(ti, " [correct]");
14463 // Backward compatible with use of -1
14464 if (hf_checksum_status > 0) {
14465 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14466 proto_item_set_generated(ti2);
14467 }
14468 incorrect_checksum = false0;
14469 }
14470 }
14471
14472 if (incorrect_checksum) {
14473 // Backward compatible with use of -1
14474 if (hf_checksum_status > 0) {
14475 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14476 proto_item_set_generated(ti2);
14477 }
14478 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14479 proto_item_append_text(ti, " [incorrect]");
14480 if (bad_checksum_expert != NULL((void*)0))
14481 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14482 } else {
14483 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14484 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14485 if (bad_checksum_expert != NULL((void*)0))
14486 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14487 }
14488 }
14489 } else {
14490 // Backward compatible with use of -1
14491 if (hf_checksum_status > 0) {
14492 proto_item_append_text(ti, " [unverified]");
14493 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14494 proto_item_set_generated(ti2);
14495 }
14496 }
14497
14498 return ti;
14499}
14500
14501unsigned char
14502proto_check_field_name(const char *field_name)
14503{
14504 return module_check_valid_name(field_name, false0);
14505}
14506
14507unsigned char
14508proto_check_field_name_lower(const char *field_name)
14509{
14510 return module_check_valid_name(field_name, true1);
14511}
14512
14513bool_Bool
14514tree_expanded(int tree_type)
14515{
14516 if (tree_type <= 0) {
14517 return false0;
14518 }
14519 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", 14519, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14520 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14521}
14522
14523void
14524tree_expanded_set(int tree_type, bool_Bool value)
14525{
14526 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", 14526, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14527
14528 if (value)
14529 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14530 else
14531 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14532}
14533
14534/*
14535 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14536 *
14537 * Local variables:
14538 * c-basic-offset: 8
14539 * tab-width: 8
14540 * indent-tabs-mode: t
14541 * End:
14542 *
14543 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14544 * :indentSize=8:tabSize=8:noTabs=false:
14545 */