Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13788, 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-10-101034-3642-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <[email protected]>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 unsigned cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is equal to 0 */
102#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
103 if (length == 0) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is equal to 0 */
111#define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
112 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (length == 0) { ((void)0); return ((void*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const unsigned start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 unsigned start, int *length);
300
301static proto_item *
302proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303 unsigned start, unsigned *length);
304
305static void
306proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307static void
308proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309
310static void
311proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312static void
313proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314static void
315proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316static void
317proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318static void
319proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320static void
321proto_tree_set_string(field_info *fi, const char* value);
322static void
323proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326static void
327proto_tree_set_vines(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330static void
331proto_tree_set_ether(field_info *fi, const uint8_t* value);
332static void
333proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334static void
335proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336static void
337proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338static void
339proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340static void
341proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342static void
343proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344static void
345proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346static void
347proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348static void
349proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350static void
351proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352static void
353proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354static void
355proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356static void
357proto_tree_set_boolean(field_info *fi, uint64_t value);
358static void
359proto_tree_set_float(field_info *fi, float value);
360static void
361proto_tree_set_double(field_info *fi, double value);
362static void
363proto_tree_set_uint(field_info *fi, uint32_t value);
364static void
365proto_tree_set_int(field_info *fi, int32_t value);
366static void
367proto_tree_set_uint64(field_info *fi, uint64_t value);
368static void
369proto_tree_set_int64(field_info *fi, int64_t value);
370static void
371proto_tree_set_eui64(field_info *fi, const uint64_t value);
372static void
373proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374
375/* Handle type length mismatch (now filterable) expert info */
376static int proto_type_length_mismatch;
377static expert_field ei_type_length_mismatch_error;
378static expert_field ei_type_length_mismatch_warn;
379static void register_type_length_mismatch(void);
380
381/* Handle byte array string decoding errors with expert info */
382static int proto_byte_array_string_decoding_error;
383static expert_field ei_byte_array_string_decoding_failed_error;
384static void register_byte_array_string_decodinws_error(void);
385
386/* Handle date and time string decoding errors with expert info */
387static int proto_date_time_string_decoding_error;
388static expert_field ei_date_time_string_decoding_failed_error;
389static void register_date_time_string_decodinws_error(void);
390
391/* Handle string errors expert info */
392static int proto_string_errors;
393static expert_field ei_string_trailing_characters;
394static void register_string_errors(void);
395
396/* Handle varint errors expert info */
397static int proto_varint_errors;
398static expert_field ei_varint_decoding_failed_error;
399static void register_varint_errors(void);
400
401static int proto_register_field_init(header_field_info *hfinfo, const int parent);
402
403/* special-case header field used within proto.c */
404static header_field_info hfi_text_only =
405 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
406int hf_text_only;
407
408/* Structure for information about a protocol */
409struct _protocol {
410 const char *name; /* long description */
411 const char *short_name; /* short description */
412 const char *filter_name; /* name of this protocol in filters */
413 GPtrArray *fields; /* fields for this protocol */
414 int proto_id; /* field ID for this protocol */
415 bool_Bool is_enabled; /* true if protocol is enabled */
416 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
417 bool_Bool can_toggle; /* true if is_enabled can be changed */
418 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
419 For dissectors that need a protocol name so they
420 can be added to a dissector table, but use the
421 parent_proto_id for things like enable/disable */
422 GList *heur_list; /* Heuristic dissectors associated with this protocol */
423};
424
425/* List of all protocols */
426static GList *protocols;
427
428/* Structure stored for deregistered g_slice */
429struct g_slice_data {
430 size_t block_size;
431 void *mem_block;
432};
433
434/* Deregistered fields */
435static GPtrArray *deregistered_fields;
436static GPtrArray *deregistered_data;
437static GPtrArray *deregistered_slice;
438
439/* indexed by prefix, contains initializers */
440static GHashTable* prefixes;
441
442/* Contains information about a field when a dissector calls
443 * proto_tree_add_item. */
444#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
445#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
446
447/* Contains the space for proto_nodes. */
448#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
449 node->first_child = NULL((void*)0); \
450 node->last_child = NULL((void*)0); \
451 node->next = NULL((void*)0);
452
453#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
454 wmem_free(pool, node)
455
456/* String space for protocol and field items for the GUI */
457#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
458 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
459 il->value_pos = 0; \
460 il->value_len = 0;
461#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
462 wmem_free(pool, il);
463
464#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 464, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 464, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
465 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
466 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 466
, __func__, "Unregistered hf! index=%d", hfindex)
; \
467 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 467, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
468 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 468, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
469 hfinfo = gpa_hfinfo.hfi[hfindex];
470
471#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
472
473/* List which stores protocols and fields that have been registered */
474typedef struct _gpa_hfinfo_t {
475 uint32_t len;
476 uint32_t allocated_len;
477 header_field_info **hfi;
478} gpa_hfinfo_t;
479
480static gpa_hfinfo_t gpa_hfinfo;
481
482/* Hash table of abbreviations and IDs */
483static wmem_map_t *gpa_name_map;
484static header_field_info *same_name_hfinfo;
485
486/* Hash table protocol aliases. const char * -> const char * */
487static GHashTable *gpa_protocol_aliases;
488
489/*
490 * We're called repeatedly with the same field name when sorting a column.
491 * Cache our last gpa_name_map hit for faster lookups.
492 */
493static char *last_field_name;
494static header_field_info *last_hfinfo;
495
496/* Points to the first element of an array of bits, indexed by
497 a subtree item type; that array element is true if subtrees of
498 an item of that type are to be expanded. */
499static uint32_t *tree_is_expanded;
500
501/* Number of elements in that array. The entry with index 0 is not used. */
502int num_tree_types = 1;
503
504/* Name hashtables for fast detection of duplicate names */
505static GHashTable* proto_names;
506static GHashTable* proto_short_names;
507static GHashTable* proto_filter_names;
508
509static const char * const reserved_filter_names[] = {
510 /* Display filter keywords. */
511 "eq",
512 "ne",
513 "all_eq",
514 "any_eq",
515 "all_ne",
516 "any_ne",
517 "gt",
518 "ge",
519 "lt",
520 "le",
521 "bitand",
522 "bitwise_and",
523 "contains",
524 "matches",
525 "not",
526 "and",
527 "or",
528 "xor",
529 "in",
530 "any",
531 "all",
532 "true",
533 "false",
534 "nan",
535 "inf",
536 "infinity",
537 NULL((void*)0)
538};
539
540static GHashTable *proto_reserved_filter_names;
541static GQueue* saved_dir_queue;
542
543static int
544proto_compare_name(const void *p1_arg, const void *p2_arg)
545{
546 const protocol_t *p1 = (const protocol_t *)p1_arg;
547 const protocol_t *p2 = (const protocol_t *)p2_arg;
548
549 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
550}
551
552static GSList *dissector_plugins;
553
554#ifdef HAVE_PLUGINS1
555void
556proto_register_plugin(const proto_plugin *plug)
557{
558 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
559}
560#else /* HAVE_PLUGINS */
561void
562proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
563{
564 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 564, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
565}
566#endif /* HAVE_PLUGINS */
567
568static void
569call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
570{
571 proto_plugin *plug = (proto_plugin *)data;
572
573 if (plug->register_protoinfo) {
574 plug->register_protoinfo();
575 }
576}
577
578static void
579call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
580{
581 proto_plugin *plug = (proto_plugin *)data;
582
583 if (plug->register_handoff) {
584 plug->register_handoff();
585 }
586}
587
588void proto_pre_init(void)
589{
590 saved_dir_queue = g_queue_new();
591
592 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
593 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
594 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
595
596 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
597 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
598 /* GHashTable has no key destructor so the cast is safe. */
599 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
600 }
601
602 gpa_hfinfo.len = 0;
603 gpa_hfinfo.allocated_len = 0;
604 gpa_hfinfo.hfi = NULL((void*)0);
605 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
606 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
607 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
608 deregistered_fields = g_ptr_array_new();
609 deregistered_data = g_ptr_array_new();
610 deregistered_slice = g_ptr_array_new();
611}
612
613/* initialize data structures and register protocols and fields */
614void
615proto_init(GSList *register_all_plugin_protocols_list,
616 GSList *register_all_plugin_handoffs_list,
617 register_entity_func register_func, register_entity_func handoff_func,
618 register_cb cb,
619 void *client_data)
620{
621 /* Initialize the ftype subsystem */
622 ftypes_initialize();
623
624 /* Initialize the address type subsystem */
625 address_types_initialize();
626
627 /* Register one special-case FT_TEXT_ONLY field for use when
628 converting wireshark to new-style proto_tree. These fields
629 are merely strings on the GUI tree; they are not filterable */
630 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
631
632 /* Register the pseudo-protocols used for exceptions. */
633 register_show_exception();
634 register_type_length_mismatch();
635 register_byte_array_string_decodinws_error();
636 register_date_time_string_decodinws_error();
637 register_string_errors();
638 register_varint_errors();
639 ftypes_register_pseudofields();
640 col_register_protocol();
641
642 /* Have each built-in dissector register its protocols, fields,
643 dissector tables, and dissectors to be called through a
644 handle, and do whatever one-time initialization it needs to
645 do. */
646 if (register_func != NULL((void*)0))
647 register_func(cb, client_data);
648
649 /* Now call the registration routines for all epan plugins. */
650 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
651 ((void (*)(register_cb, void *))l->data)(cb, client_data);
652 }
653
654 /* Now call the registration routines for all dissector plugins. */
655 if (cb)
656 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
657 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
658
659 /* Now call the "handoff registration" routines of all built-in
660 dissectors; those routines register the dissector in other
661 dissectors' handoff tables, and fetch any dissector handles
662 they need. */
663 if (handoff_func != NULL((void*)0))
664 handoff_func(cb, client_data);
665
666 /* Now do the same with epan plugins. */
667 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
668 ((void (*)(register_cb, void *))l->data)(cb, client_data);
669 }
670
671 /* Now do the same with dissector plugins. */
672 if (cb)
673 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
674 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
675
676 /* sort the protocols by protocol name */
677 protocols = g_list_sort(protocols, proto_compare_name);
678
679 /* sort the dissector handles in dissector tables (for -G reports
680 * and -d error messages. The GUI sorts the handles itself.) */
681 packet_all_tables_sort_handles();
682
683 /* We've assigned all the subtree type values; allocate the array
684 for them, and zero it out. */
685 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
)))
;
686}
687
688static void
689proto_cleanup_base(void)
690{
691 protocol_t *protocol;
692 header_field_info *hfinfo;
693
694 /* Free the abbrev/ID hash table */
695 if (gpa_name_map) {
696 // XXX - We don't have a wmem_map_destroy, but
697 // it does get cleaned up when epan scope is
698 // destroyed
699 //g_hash_table_destroy(gpa_name_map);
700 gpa_name_map = NULL((void*)0);
701 }
702 if (gpa_protocol_aliases) {
703 g_hash_table_destroy(gpa_protocol_aliases);
704 gpa_protocol_aliases = NULL((void*)0);
705 }
706 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)
;
707 last_field_name = NULL((void*)0);
708
709 while (protocols) {
710 protocol = (protocol_t *)protocols->data;
711 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", 711
, __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", 711, "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", 711, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
712 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", 712, "protocol->proto_id == hfinfo->id"
))))
;
713
714 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)
;
715 if (protocol->parent_proto_id != -1) {
716 // pino protocol
717 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 717, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
718 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"
, 718, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
719 } else {
720 if (protocol->fields) {
721 g_ptr_array_free(protocol->fields, true1);
722 }
723 g_list_free(protocol->heur_list);
724 }
725 protocols = g_list_remove(protocols, protocol);
726 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
727 }
728
729 if (proto_names) {
730 g_hash_table_destroy(proto_names);
731 proto_names = NULL((void*)0);
732 }
733
734 if (proto_short_names) {
735 g_hash_table_destroy(proto_short_names);
736 proto_short_names = NULL((void*)0);
737 }
738
739 if (proto_filter_names) {
740 g_hash_table_destroy(proto_filter_names);
741 proto_filter_names = NULL((void*)0);
742 }
743
744 if (proto_reserved_filter_names) {
745 g_hash_table_destroy(proto_reserved_filter_names);
746 proto_reserved_filter_names = NULL((void*)0);
747 }
748
749 if (gpa_hfinfo.allocated_len) {
750 gpa_hfinfo.len = 0;
751 gpa_hfinfo.allocated_len = 0;
752 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)
;
753 gpa_hfinfo.hfi = NULL((void*)0);
754 }
755
756 if (deregistered_fields) {
757 g_ptr_array_free(deregistered_fields, true1);
758 deregistered_fields = NULL((void*)0);
759 }
760
761 if (deregistered_data) {
762 g_ptr_array_free(deregistered_data, true1);
763 deregistered_data = NULL((void*)0);
764 }
765
766 if (deregistered_slice) {
767 g_ptr_array_free(deregistered_slice, true1);
768 deregistered_slice = NULL((void*)0);
769 }
770
771 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)
;
772 tree_is_expanded = NULL((void*)0);
773
774 if (prefixes)
775 g_hash_table_destroy(prefixes);
776
777 if (saved_dir_queue != NULL((void*)0)) {
778 g_queue_clear_full(saved_dir_queue, g_free);
779 g_queue_free(saved_dir_queue);
780 saved_dir_queue = NULL((void*)0);
781 }
782}
783
784void
785proto_cleanup(void)
786{
787 proto_free_deregistered_fields();
788 proto_cleanup_base();
789
790 g_slist_free(dissector_plugins);
791 dissector_plugins = NULL((void*)0);
792}
793
794static bool_Bool
795ws_pushd(const char* dir)
796{
797 //Save the current working directory
798 const char* save_wd = get_current_working_dir();
799 if (save_wd != NULL((void*)0))
800 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
801
802 //Change to the new one
803#ifdef _WIN32
804 SetCurrentDirectory(utf_8to16(dir));
805 return true1;
806#else
807 return (chdir(dir) == 0);
808#endif
809}
810
811static bool_Bool
812ws_popd(void)
813{
814 int ret = 0;
815 char* saved_wd = g_queue_pop_head(saved_dir_queue);
816 if (saved_wd == NULL((void*)0))
817 return false0;
818
819 //Restore the previous one
820#ifdef _WIN32
821 SetCurrentDirectory(utf_8to16(saved_wd));
822#else
823 ret = chdir(saved_wd);
824#endif
825 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)
;
826 return (ret == 0);
827}
828
829void
830proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
831{
832 if (ws_pushd(dir))
833 {
834 func(param);
835 ws_popd();
836 }
837}
838
839static bool_Bool
840// NOLINTNEXTLINE(misc-no-recursion)
841proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
842 void *data)
843{
844 proto_node *pnode = tree;
845 proto_node *child;
846 proto_node *current;
847
848 if (func(pnode, data))
849 return true1;
850
851 child = pnode->first_child;
852 while (child != NULL((void*)0)) {
853 /*
854 * The routine we call might modify the child, e.g. by
855 * freeing it, so we get the child's successor before
856 * calling that routine.
857 */
858 current = child;
859 child = current->next;
860 // We recurse here, but we're limited by prefs.gui_max_tree_depth
861 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
862 return true1;
863 }
864
865 return false0;
866}
867
868void
869proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
870 void *data)
871{
872 proto_node *node = tree;
873 proto_node *current;
874
875 if (!node)
876 return;
877
878 node = node->first_child;
879 while (node != NULL((void*)0)) {
880 current = node;
881 node = current->next;
882 func((proto_tree *)current, data);
883 }
884}
885
886static void
887free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
888{
889 GPtrArray *ptrs = (GPtrArray *)value;
890 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
891 header_field_info *hfinfo;
892
893 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", 893, __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", 893, "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", 893, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
894 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
895 /* when a field is referenced by a filter this also
896 affects the refcount for the parent protocol so we need
897 to adjust the refcount for the parent as well
898 */
899 if (hfinfo->parent != -1) {
900 header_field_info *parent_hfinfo;
901 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", 901
, __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", 901, "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", 901, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
902 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
903 }
904 hfinfo->ref_type = HF_REF_TYPE_NONE;
905 }
906
907 g_ptr_array_free(ptrs, true1);
908}
909
910static void
911proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
912{
913 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
914
915 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
916
917 if (finfo) {
918 // The fvalue_t structure was allocated using fvalue_new_pool()
919 // (see new_field_info()) and will be reclaimed when the pool is
920 // freed, so we only release the type-specific data it owns here.
921 fvalue_cleanup(finfo->value);
922 finfo->value = NULL((void*)0);
923 }
924}
925
926void
927proto_tree_reset(proto_tree *tree)
928{
929 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
930
931 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
932
933 /* free tree data */
934 if (tree_data->interesting_hfids) {
935 /* Free all the GPtrArray's in the interesting_hfids hash. */
936 g_hash_table_foreach(tree_data->interesting_hfids,
937 free_GPtrArray_value, NULL((void*)0));
938
939 /* And then remove all values. */
940 g_hash_table_remove_all(tree_data->interesting_hfids);
941 }
942
943 /* Reset track of the number of children */
944 tree_data->count = 0;
945
946 /* Reset our loop checks */
947 tree_data->idle_count_ds_tvb = NULL((void*)0);
948 tree_data->max_start = 0;
949 tree_data->start_idle_count = 0;
950
951 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
952}
953
954/* frees the resources that the dissection a proto_tree uses */
955void
956proto_tree_free(proto_tree *tree)
957{
958 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
959
960 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
961
962 /* free tree data */
963 if (tree_data->interesting_hfids) {
964 /* Free all the GPtrArray's in the interesting_hfids hash. */
965 g_hash_table_foreach(tree_data->interesting_hfids,
966 free_GPtrArray_value, NULL((void*)0));
967
968 /* And then destroy the hash. */
969 g_hash_table_destroy(tree_data->interesting_hfids);
970 }
971
972 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)
;
973
974 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
975}
976
977/* Is the parsing being done for a visible proto_tree or an invisible one?
978 * By setting this correctly, the proto_tree creation is sped up by not
979 * having to call vsnprintf and copy strings around.
980 */
981bool_Bool
982proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
983{
984 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
985
986 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
987
988 return old_visible;
989}
990
991void
992proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
993{
994 if (tree)
995 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
996}
997
998/* Assume dissector set only its protocol fields.
999 This function is called by dissectors and allows the speeding up of filtering
1000 in wireshark; if this function returns false it is safe to reset tree to NULL
1001 and thus skip calling most of the expensive proto_tree_add_...()
1002 functions.
1003 If the tree is visible we implicitly assume the field is referenced.
1004*/
1005bool_Bool
1006proto_field_is_referenced(proto_tree *tree, int proto_id)
1007{
1008 register header_field_info *hfinfo;
1009
1010
1011 if (!tree)
1012 return false0;
1013
1014 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1015 return true1;
1016
1017 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", 1017, __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", 1017,
"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", 1017, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1018 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1019 return true1;
1020
1021 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1022 return true1;
1023
1024 return false0;
1025}
1026
1027
1028/* Finds a record in the hfinfo array by id. */
1029header_field_info *
1030proto_registrar_get_nth(unsigned hfindex)
1031{
1032 register header_field_info *hfinfo;
1033
1034 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", 1034, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1034,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1034, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1035 return hfinfo;
1036}
1037
1038
1039/* Prefix initialization
1040 * this allows for a dissector to register a display filter name prefix
1041 * so that it can delay the initialization of the hf array as long as
1042 * possible.
1043 */
1044
1045/* compute a hash for the part before the dot of a display filter */
1046static unsigned
1047prefix_hash (const void *key) {
1048 /* end the string at the dot and compute its hash */
1049 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1050 char* c = copy;
1051 unsigned tmp;
1052
1053 for (; *c; c++) {
1054 if (*c == '.') {
1055 *c = 0;
1056 break;
1057 }
1058 }
1059
1060 tmp = wmem_str_hash(copy);
1061 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1062 return tmp;
1063}
1064
1065/* are both strings equal up to the end or the dot? */
1066static gboolean
1067prefix_equal (const void *ap, const void *bp) {
1068 const char* a = (const char *)ap;
1069 const char* b = (const char *)bp;
1070
1071 do {
1072 char ac = *a++;
1073 char bc = *b++;
1074
1075 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1076
1077 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1078 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1079
1080 if (ac != bc) return FALSE(0);
1081 } while (1);
1082
1083 return FALSE(0);
1084}
1085
1086/* Register a new prefix for "delayed" initialization of field arrays */
1087void
1088proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1089 if (! prefixes ) {
1090 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1091 }
1092
1093 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1094}
1095
1096/* helper to call all prefix initializers */
1097static gboolean
1098initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1099 ((prefix_initializer_t)v)((const char *)k);
1100 return TRUE(!(0));
1101}
1102
1103/** Initialize every remaining uninitialized prefix. */
1104void
1105proto_initialize_all_prefixes(void) {
1106 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1107}
1108
1109/* Finds a record in the hfinfo array by name.
1110 * If it fails to find it in the already registered fields,
1111 * it tries to find and call an initializer in the prefixes
1112 * table and if so it looks again.
1113 */
1114
1115header_field_info *
1116proto_registrar_get_byname(const char *field_name)
1117{
1118 header_field_info *hfinfo;
1119 prefix_initializer_t pi;
1120
1121 if (!field_name)
1122 return NULL((void*)0);
1123
1124 if (g_strcmp0(field_name, last_field_name) == 0) {
1125 return last_hfinfo;
1126 }
1127
1128 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1129
1130 if (hfinfo) {
1131 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)
;
1132 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1133 last_hfinfo = hfinfo;
1134 return hfinfo;
1135 }
1136
1137 if (!prefixes)
1138 return NULL((void*)0);
1139
1140 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1141 pi(field_name);
1142 g_hash_table_remove(prefixes, field_name);
1143 } else {
1144 return NULL((void*)0);
1145 }
1146
1147 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1148
1149 if (hfinfo) {
1150 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)
;
1151 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1152 last_hfinfo = hfinfo;
1153 }
1154 return hfinfo;
1155}
1156
1157header_field_info*
1158proto_registrar_get_byalias(const char *alias_name)
1159{
1160 if (!alias_name) {
1161 return NULL((void*)0);
1162 }
1163
1164 /* Find our aliased protocol. */
1165 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1166 char *dot = strchr(an_copy, '.');
1167 if (dot) {
1168 *dot = '\0';
1169 }
1170 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1171 if (!proto_pfx) {
1172 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)
;
1173 return NULL((void*)0);
1174 }
1175
1176 /* Construct our aliased field and look it up. */
1177 GString *filter_name = g_string_new(proto_pfx);
1178 if (dot) {
1179 g_string_append_printf(filter_name, ".%s", dot+1);
1180 }
1181 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1182 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)
;
1183 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)))))
;
1184
1185 return hfinfo;
1186}
1187
1188int
1189proto_registrar_get_id_byname(const char *field_name)
1190{
1191 header_field_info *hfinfo;
1192
1193 hfinfo = proto_registrar_get_byname(field_name);
1194
1195 if (!hfinfo)
1196 return -1;
1197
1198 return hfinfo->id;
1199}
1200
1201static int
1202label_strcat_flags(const header_field_info *hfinfo)
1203{
1204 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1205 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1206
1207 return 0;
1208}
1209
1210static char *
1211format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1212 const uint8_t *bytes, unsigned length, size_t max_str_len)
1213{
1214 char *str = NULL((void*)0);
1215 const uint8_t *p;
1216 bool_Bool is_printable;
1217
1218 if (bytes) {
1219 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1220 /*
1221 * If all bytes are valid and printable UTF-8, show the
1222 * bytes as a string - in quotes to indicate that it's
1223 * a string.
1224 */
1225 if (isprint_utf8_string((const char*)bytes, length)) {
1226 str = wmem_strdup_printf(scope, "\"%.*s\"",
1227 (int)length, bytes);
1228 return str;
1229 }
1230 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1231 /*
1232 * Check whether all bytes are printable.
1233 */
1234 is_printable = true1;
1235 for (p = bytes; p < bytes+length; p++) {
1236 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1237 /* Not printable. */
1238 is_printable = false0;
1239 break;
1240 }
1241 }
1242
1243 /*
1244 * If all bytes are printable ASCII, show the bytes
1245 * as a string - in quotes to indicate that it's
1246 * a string.
1247 */
1248 if (is_printable) {
1249 str = wmem_strdup_printf(scope, "\"%.*s\"",
1250 (int)length, bytes);
1251 return str;
1252 }
1253 }
1254
1255 /*
1256 * Either it's not printable ASCII, or we don't care whether
1257 * it's printable ASCII; show it as hex bytes.
1258 */
1259 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1260 case SEP_DOT:
1261 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1262 break;
1263 case SEP_DASH:
1264 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1265 break;
1266 case SEP_COLON:
1267 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1268 break;
1269 case SEP_SPACE:
1270 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1271 break;
1272 case BASE_NONE:
1273 default:
1274 if (prefs.display_byte_fields_with_spaces) {
1275 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1276 } else {
1277 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1278 }
1279 break;
1280 }
1281 }
1282 else {
1283 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1284 str = wmem_strdup(scope, "<none>");
1285 } else {
1286 str = wmem_strdup(scope, "<MISSING>");
1287 }
1288 }
1289 return str;
1290}
1291
1292static char *
1293format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1294 const uint8_t *bytes, unsigned length)
1295{
1296 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1297}
1298
1299static void
1300ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1301{
1302 subtree_lvl *pushed_tree;
1303
1304 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"
, 1304, "ptvc->pushed_tree_max <= 256-8"))))
;
1305 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1306
1307 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1308 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1308, "pushed_tree != ((void*)0)"
))))
;
1309 ptvc->pushed_tree = pushed_tree;
1310}
1311
1312static void
1313ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1314{
1315 ptvc->pushed_tree = NULL((void*)0);
1316 ptvc->pushed_tree_max = 0;
1317 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", 1317, "ptvc->pushed_tree_index == 0"
))))
;
1318 ptvc->pushed_tree_index = 0;
1319}
1320
1321/* Allocates an initializes a ptvcursor_t with 3 variables:
1322 * proto_tree, tvbuff, and offset. */
1323ptvcursor_t *
1324ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1325{
1326 ptvcursor_t *ptvc;
1327
1328 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1329 ptvc->scope = scope;
1330 ptvc->tree = tree;
1331 ptvc->tvb = tvb;
1332 ptvc->offset = offset;
1333 ptvc->pushed_tree = NULL((void*)0);
1334 ptvc->pushed_tree_max = 0;
1335 ptvc->pushed_tree_index = 0;
1336 return ptvc;
1337}
1338
1339
1340/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1341void
1342ptvcursor_free(ptvcursor_t *ptvc)
1343{
1344 ptvcursor_free_subtree_levels(ptvc);
1345 wmem_free(ptvc->scope, ptvc);
1346}
1347
1348/* Returns tvbuff. */
1349tvbuff_t *
1350ptvcursor_tvbuff(ptvcursor_t *ptvc)
1351{
1352 return ptvc->tvb;
1353}
1354
1355/* Returns current offset. */
1356unsigned
1357ptvcursor_current_offset(ptvcursor_t *ptvc)
1358{
1359 return ptvc->offset;
1360}
1361
1362proto_tree *
1363ptvcursor_tree(ptvcursor_t *ptvc)
1364{
1365 if (!ptvc)
1366 return NULL((void*)0);
1367
1368 return ptvc->tree;
1369}
1370
1371void
1372ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1373{
1374 ptvc->tree = tree;
1375}
1376
1377/* creates a subtree, sets it as the working tree and pushes the old working tree */
1378proto_tree *
1379ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1380{
1381 subtree_lvl *subtree;
1382 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1383 ptvcursor_new_subtree_levels(ptvc);
1384
1385 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1386 subtree->tree = ptvc->tree;
1387 subtree->it= NULL((void*)0);
1388 ptvc->pushed_tree_index++;
1389 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1390}
1391
1392/* pops a subtree */
1393void
1394ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1395{
1396 subtree_lvl *subtree;
1397
1398 if (ptvc->pushed_tree_index <= 0)
1399 return;
1400
1401 ptvc->pushed_tree_index--;
1402 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1403 if (subtree->it != NULL((void*)0))
1404 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1405
1406 ptvc->tree = subtree->tree;
1407}
1408
1409/* saves the current tvb offset and the item in the current subtree level */
1410static void
1411ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1412{
1413 subtree_lvl *subtree;
1414
1415 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", 1415, "ptvc->pushed_tree_index > 0"
))))
;
1416
1417 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1418 subtree->it = it;
1419 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1420}
1421
1422/* Creates a subtree and adds it to the cursor as the working tree but does not
1423 * save the old working tree */
1424proto_tree *
1425ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1426{
1427 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1428 return ptvc->tree;
1429}
1430
1431static proto_tree *
1432ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1433{
1434 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1435 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1436 ptvcursor_subtree_set_item(ptvc, it);
1437 return ptvcursor_tree(ptvc);
1438}
1439
1440/* Add an item to the tree and create a subtree
1441 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1442 * In this case, when the subtree will be closed, the parent item length will
1443 * be equal to the advancement of the cursor since the creation of the subtree.
1444 */
1445proto_tree *
1446ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1447 const unsigned encoding, int ett_subtree)
1448{
1449 proto_item *it;
1450
1451 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1452 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1453}
1454
1455static proto_item *
1456proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1457
1458/* Add a text node to the tree and create a subtree
1459 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1460 * In this case, when the subtree will be closed, the item length will be equal
1461 * to the advancement of the cursor since the creation of the subtree.
1462 */
1463proto_tree *
1464ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1465 int ett_subtree, const char *format, ...)
1466{
1467 proto_item *pi;
1468 va_list ap;
1469 header_field_info *hfinfo;
1470 proto_tree *tree;
1471
1472 tree = ptvcursor_tree(ptvc);
1473
1474 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1475
1476 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", 1476
, __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", 1476, "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", 1476, "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", 1476, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1477
1478 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1479 ptvcursor_current_offset(ptvc), length);
1480
1481 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1481, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1482
1483 va_start(ap, format)__builtin_va_start(ap, format);
1484 proto_tree_set_representation(pi, format, ap);
1485 va_end(ap)__builtin_va_end(ap);
1486
1487 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1488}
1489
1490/* Add a text-only node, leaving it to our caller to fill the text in */
1491static proto_item *
1492proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1493{
1494 proto_item *pi;
1495
1496 if (tree == NULL((void*)0))
1497 return NULL((void*)0);
1498
1499 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1500
1501 return pi;
1502}
1503
1504/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1505proto_item *
1506proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1507 const char *format, ...)
1508{
1509 proto_item *pi;
1510 va_list ap;
1511 header_field_info *hfinfo;
1512
1513 tvb_ensure_bytes_exist(tvb, start, length);
1514
1515 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1516
1517 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", 1517
, __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", 1517, "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", 1517, "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", 1517, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1518
1519 pi = proto_tree_add_text_node(tree, tvb, start, length);
1520
1521 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1521, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1522
1523 va_start(ap, format)__builtin_va_start(ap, format);
1524 proto_tree_set_representation(pi, format, ap);
1525 va_end(ap)__builtin_va_end(ap);
1526
1527 return pi;
1528}
1529
1530/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1531proto_item *
1532proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1533 unsigned length, const char *format, va_list ap)
1534{
1535 proto_item *pi;
1536 header_field_info *hfinfo;
1537
1538 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1539 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1540 * the length to be what's in the tvbuff if length is -1, and the
1541 * minimum of length and what's in the tvbuff if not.
1542 */
1543
1544 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1545
1546 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", 1546
, __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", 1546, "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", 1546, "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", 1546, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1547
1548 pi = proto_tree_add_text_node(tree, tvb, start, length);
1549
1550 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1550, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1551
1552 proto_tree_set_representation(pi, format, ap);
1553
1554 return pi;
1555}
1556
1557/* Add a text-only node that creates a subtree underneath.
1558 */
1559proto_tree *
1560proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1561{
1562 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1563}
1564
1565/* Add a text-only node that creates a subtree underneath.
1566 */
1567proto_tree *
1568proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1569{
1570 proto_tree *pt;
1571 proto_item *pi;
1572 va_list ap;
1573
1574 if (length == -1) {
1575 length = tvb_captured_length_remaining(tvb, start);
1576 }
1577
1578 va_start(ap, format)__builtin_va_start(ap, format);
1579 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1580 va_end(ap)__builtin_va_end(ap);
1581
1582 if (tree_item != NULL((void*)0))
1583 *tree_item = pi;
1584
1585 pt = proto_item_add_subtree(pi, idx);
1586
1587 return pt;
1588}
1589
1590/* Add a text-only node for debugging purposes. The caller doesn't need
1591 * to worry about tvbuff, start, or length. Debug message gets sent to
1592 * STDOUT, too */
1593proto_item *
1594proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1595{
1596 proto_item *pi;
1597 va_list ap;
1598
1599 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1600
1601 if (pi) {
1602 va_start(ap, format)__builtin_va_start(ap, format);
1603 proto_tree_set_representation(pi, format, ap);
1604 va_end(ap)__builtin_va_end(ap);
1605 }
1606 va_start(ap, format)__builtin_va_start(ap, format);
1607 vprintf(format, ap);
1608 va_end(ap)__builtin_va_end(ap);
1609 printf("\n");
1610
1611 return pi;
1612}
1613
1614proto_item *
1615proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1616{
1617 proto_item *pi;
1618 header_field_info *hfinfo;
1619
1620 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1621
1622 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", 1622
, __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", 1622, "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", 1622, "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", 1622, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1623
1624 pi = proto_tree_add_text_node(tree, tvb, start, length);
1625
1626 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1626, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1627
1628 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1629
1630 return pi;
1631}
1632
1633proto_item *
1634proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1635{
1636 proto_item *pi;
1637 header_field_info *hfinfo;
1638 char *str;
1639
1640 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1641
1642 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", 1642
, __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", 1642, "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", 1642, "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", 1642, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1643
1644 pi = proto_tree_add_text_node(tree, tvb, start, length);
1645
1646 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1646, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1647
1648 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1649 proto_item_set_text(pi, "%s", str);
1650 wmem_free(NULL((void*)0), str);
1651
1652 return pi;
1653}
1654
1655void proto_report_dissector_bug(const char *format, ...)
1656{
1657 va_list args;
1658
1659 if (wireshark_abort_on_dissector_bug) {
1660 /*
1661 * Try to have the error message show up in the crash
1662 * information.
1663 */
1664 va_start(args, format)__builtin_va_start(args, format);
1665 ws_vadd_crash_info(format, args);
1666 va_end(args)__builtin_va_end(args);
1667
1668 /*
1669 * Print the error message.
1670 */
1671 va_start(args, format)__builtin_va_start(args, format);
1672 vfprintf(stderrstderr, format, args);
1673 va_end(args)__builtin_va_end(args);
1674 putc('\n', stderrstderr);
1675
1676 /*
1677 * And crash.
1678 */
1679 abort();
1680 } else {
1681 va_start(args, format)__builtin_va_start(args, format);
1682 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1683 va_end(args)__builtin_va_end(args);
1684 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1684
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1685 }
1686}
1687
1688/* We could probably get away with changing is_error to a minimum length value. */
1689static void
1690report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1691{
1692 if (is_error) {
1693 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1694 } else {
1695 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1696 }
1697
1698 if (is_error) {
1699 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1700 }
1701}
1702
1703static uint32_t
1704get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1705{
1706 uint32_t value;
1707 bool_Bool length_error;
1708
1709 switch (length) {
1710
1711 case 1:
1712 value = tvb_get_uint8(tvb, offset);
1713 if (encoding & ENC_ZIGBEE0x40000000) {
1714 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1715 value = 0;
1716 }
1717 }
1718 break;
1719
1720 case 2:
1721 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1722 : tvb_get_ntohs(tvb, offset);
1723 if (encoding & ENC_ZIGBEE0x40000000) {
1724 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1725 value = 0;
1726 }
1727 }
1728 break;
1729
1730 case 3:
1731 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1732 : tvb_get_ntoh24(tvb, offset);
1733 break;
1734
1735 case 4:
1736 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1737 : tvb_get_ntohl(tvb, offset);
1738 break;
1739
1740 default:
1741 if (length < 1) {
1742 length_error = true1;
1743 value = 0;
1744 } else {
1745 length_error = false0;
1746 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1747 : tvb_get_ntohl(tvb, offset);
1748 }
1749 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1750 break;
1751 }
1752 return value;
1753}
1754
1755static inline uint64_t
1756get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1757{
1758 uint64_t value;
1759
1760 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1761
1762 if (length < 1 || length > 8) {
1763 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1764 }
1765
1766 return value;
1767}
1768
1769static int32_t
1770get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1771{
1772 int32_t value;
1773 bool_Bool length_error;
1774
1775 switch (length) {
1776
1777 case 1:
1778 value = tvb_get_int8(tvb, offset);
1779 break;
1780
1781 case 2:
1782 value = encoding ? tvb_get_letohis(tvb, offset)
1783 : tvb_get_ntohis(tvb, offset);
1784 break;
1785
1786 case 3:
1787 value = encoding ? tvb_get_letohi24(tvb, offset)
1788 : tvb_get_ntohi24(tvb, offset);
1789 break;
1790
1791 case 4:
1792 value = encoding ? tvb_get_letohil(tvb, offset)
1793 : tvb_get_ntohil(tvb, offset);
1794 break;
1795
1796 default:
1797 if (length < 1) {
1798 length_error = true1;
1799 value = 0;
1800 } else {
1801 length_error = false0;
1802 value = encoding ? tvb_get_letohil(tvb, offset)
1803 : tvb_get_ntohil(tvb, offset);
1804 }
1805 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1806 break;
1807 }
1808 return value;
1809}
1810
1811/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1812 * be cast-able as a int64_t. This is weird, but what the code has always done.
1813 */
1814static inline uint64_t
1815get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1816{
1817 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1818
1819 switch (length) {
1820 case 7:
1821 value = ws_sign_ext64(value, 56);
1822 break;
1823 case 6:
1824 value = ws_sign_ext64(value, 48);
1825 break;
1826 case 5:
1827 value = ws_sign_ext64(value, 40);
1828 break;
1829 case 4:
1830 value = ws_sign_ext64(value, 32);
1831 break;
1832 case 3:
1833 value = ws_sign_ext64(value, 24);
1834 break;
1835 case 2:
1836 value = ws_sign_ext64(value, 16);
1837 break;
1838 case 1:
1839 value = ws_sign_ext64(value, 8);
1840 break;
1841 }
1842
1843 return value;
1844}
1845
1846/* For FT_STRING */
1847static inline const uint8_t *
1848get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1849 int length, unsigned *ret_length, const unsigned encoding)
1850{
1851 if (length == -1) {
1852 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1853 } else {
1854 *ret_length = length;
1855 }
1856 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1857}
1858
1859/* For FT_STRINGZ */
1860static inline const uint8_t *
1861get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1862 unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1863{
1864 const uint8_t *value;
1865
1866 if (length < -1) {
1867 report_type_length_mismatch(tree, "a string", length, true1);
1868 }
1869
1870 /* XXX - Ideally, every "null-terminated string which fits into a
1871 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1872 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1873 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1874 * as unknown length as well (since there is a trailing '\0', the real
1875 * length is never zero), allowing switching to unsigned lengths.
1876 */
1877 if (length == -1) {
1878 /* This can throw an exception */
1879 value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1880 } else {
1881 /* In this case, length signifies the length of the string.
1882 *
1883 * This could either be a null-padded string, which doesn't
1884 * necessarily have a '\0' at the end, or a null-terminated
1885 * string, with a trailing '\0'. (Yes, there are cases
1886 * where you have a string that's both counted and null-
1887 * terminated.)
1888 *
1889 * In the first case, we must allocate a buffer of length
1890 * "length+1", to make room for a trailing '\0'.
1891 *
1892 * In the second case, we don't assume that there is a
1893 * trailing '\0' there, as the packet might be malformed.
1894 * (XXX - should we throw an exception if there's no
1895 * trailing '\0'?) Therefore, we allocate a buffer of
1896 * length "length+1", and put in a trailing '\0', just to
1897 * be safe.
1898 *
1899 * (XXX - this would change if we made string values counted
1900 * rather than null-terminated.)
1901 */
1902 *ret_length = length;
1903 value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1904 }
1905 return value;
1906}
1907
1908/* For FT_UINT_STRING */
1909static inline const uint8_t *
1910get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1911 tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1912 const unsigned encoding)
1913{
1914 uint32_t n;
1915 const uint8_t *value;
1916
1917 /* I believe it's ok if this is called with a NULL tree */
1918 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1919 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1920 *ret_length = length + n;
1921 return value;
1922}
1923
1924/* For FT_STRINGZPAD */
1925static inline const uint8_t *
1926get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1927 int length, unsigned *ret_length, const unsigned encoding)
1928{
1929 /*
1930 * XXX - currently, string values are null-
1931 * terminated, so a "zero-padded" string
1932 * isn't special. If we represent string
1933 * values as something that includes a counted
1934 * array of bytes, we'll need to strip the
1935 * trailing NULs.
1936 */
1937 if (length == -1) {
1938 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1939 } else {
1940 *ret_length = length;
1941 }
1942 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1943}
1944
1945/* For FT_STRINGZTRUNC */
1946static inline const uint8_t *
1947get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1948 int length, unsigned *ret_length, const unsigned encoding)
1949{
1950 /*
1951 * XXX - currently, string values are null-
1952 * terminated, so a "zero-truncated" string
1953 * isn't special. If we represent string
1954 * values as something that includes a counted
1955 * array of bytes, we'll need to strip everything
1956 * starting with the terminating NUL.
1957 */
1958 if (length == -1) {
1959 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1960 } else {
1961 *ret_length = length;
1962 }
1963 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1964}
1965
1966/*
1967 * Deltas between the epochs for various non-UN*X time stamp formats and
1968 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1969 * stamp format.
1970 */
1971
1972/*
1973 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1974 * XXX - if it's OK if this is unsigned, can we just use
1975 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1976 */
1977#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1978
1979/*
1980 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1981 */
1982#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1983
1984/* this can be called when there is no tree, so tree may be null */
1985static void
1986get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1987 const int length, const unsigned encoding, nstime_t *time_stamp,
1988 const bool_Bool is_relative)
1989{
1990 uint32_t tmpsecs;
1991 uint64_t tmp64secs;
1992 uint64_t todusecs;
1993
1994 switch (encoding) {
1995
1996 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1997 /*
1998 * If the length is 16, 8-byte seconds, followed
1999 * by 8-byte fractional time in nanoseconds,
2000 * both big-endian.
2001 *
2002 * If the length is 12, 8-byte seconds, followed
2003 * by 4-byte fractional time in nanoseconds,
2004 * both big-endian.
2005 *
2006 * If the length is 8, 4-byte seconds, followed
2007 * by 4-byte fractional time in nanoseconds,
2008 * both big-endian.
2009 *
2010 * For absolute times, the seconds are seconds
2011 * since the UN*X epoch.
2012 */
2013 if (length == 16) {
2014 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2015 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2016 } else if (length == 12) {
2017 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2018 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2019 } else if (length == 8) {
2020 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2021 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2022 } else if (length == 4) {
2023 /*
2024 * Backwards compatibility.
2025 * ENC_TIME_SECS_NSECS is 0; using
2026 * ENC_BIG_ENDIAN by itself with a 4-byte
2027 * time-in-seconds value was done in the
2028 * past.
2029 */
2030 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2031 time_stamp->nsecs = 0;
2032 } else {
2033 time_stamp->secs = 0;
2034 time_stamp->nsecs = 0;
2035 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2036 }
2037 break;
2038
2039 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2040 /*
2041 * If the length is 16, 8-byte seconds, followed
2042 * by 8-byte fractional time in nanoseconds,
2043 * both little-endian.
2044 *
2045 * If the length is 12, 8-byte seconds, followed
2046 * by 4-byte fractional time in nanoseconds,
2047 * both little-endian.
2048 *
2049 * If the length is 8, 4-byte seconds, followed
2050 * by 4-byte fractional time in nanoseconds,
2051 * both little-endian.
2052 *
2053 * For absolute times, the seconds are seconds
2054 * since the UN*X epoch.
2055 */
2056 if (length == 16) {
2057 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2058 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2059 } else if (length == 12) {
2060 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2061 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2062 } else if (length == 8) {
2063 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2064 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2065 } else if (length == 4) {
2066 /*
2067 * Backwards compatibility.
2068 * ENC_TIME_SECS_NSECS is 0; using
2069 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2070 * time-in-seconds value was done in the
2071 * past.
2072 */
2073 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2074 time_stamp->nsecs = 0;
2075 } else {
2076 time_stamp->secs = 0;
2077 time_stamp->nsecs = 0;
2078 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2079 }
2080 break;
2081
2082 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2083 /*
2084 * NTP time stamp, big-endian.
2085 * Only supported for absolute times.
2086 */
2087 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2087, "!is_relative"
))))
;
2088
2089 /* We need a temporary variable here so the unsigned math
2090 * works correctly (for years > 2036 according to RFC 2030
2091 * chapter 3).
2092 *
2093 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2094 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2095 * If bit 0 is not set, the time is in the range 2036-2104 and
2096 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2097 */
2098 tmpsecs = tvb_get_ntohl(tvb, start);
2099 if ((tmpsecs & 0x80000000) != 0)
2100 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2101 else
2102 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2103
2104 if (length == 8) {
2105 tmp64secs = tvb_get_ntoh64(tvb, start);
2106 if (tmp64secs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 time_stamp->nsecs = 0;
2110 } else {
2111 /*
2112 * Convert 1/2^32s of a second to
2113 * nanoseconds.
2114 */
2115 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2116 }
2117 } else if (length == 4) {
2118 /*
2119 * Backwards compatibility.
2120 */
2121 if (tmpsecs == 0) {
2122 //This is "NULL" time
2123 time_stamp->secs = 0;
2124 }
2125 time_stamp->nsecs = 0;
2126 } else {
2127 time_stamp->secs = 0;
2128 time_stamp->nsecs = 0;
2129 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2130 }
2131 break;
2132
2133 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2134 /*
2135 * NTP time stamp, little-endian.
2136 * Only supported for absolute times.
2137 *
2138 * NTP doesn't use this, because it's an Internet format
2139 * and hence big-endian. Any implementation must decide
2140 * whether the NTP timestamp is a 64-bit unsigned fixed
2141 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2142 * with a 32-bit unsigned seconds field followed by a
2143 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2144 * the previous two).
2145 *
2146 * XXX: We do the latter, but no dissector uses this format.
2147 * OTOH, ERF timestamps do the former, so perhaps we
2148 * should switch the interpretation so that packet-erf.c
2149 * could use this directly?
2150 */
2151 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2151, "!is_relative"
))))
;
2152
2153 /* We need a temporary variable here so the unsigned math
2154 * works correctly (for years > 2036 according to RFC 2030
2155 * chapter 3).
2156 *
2157 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2158 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2159 * If bit 0 is not set, the time is in the range 2036-2104 and
2160 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2161 */
2162 tmpsecs = tvb_get_letohl(tvb, start);
2163 if ((tmpsecs & 0x80000000) != 0)
2164 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2165 else
2166 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2167
2168 if (length == 8) {
2169 tmp64secs = tvb_get_letoh64(tvb, start);
2170 if (tmp64secs == 0) {
2171 //This is "NULL" time
2172 time_stamp->secs = 0;
2173 time_stamp->nsecs = 0;
2174 } else {
2175 /*
2176 * Convert 1/2^32s of a second to
2177 * nanoseconds.
2178 */
2179 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2180 }
2181 } else if (length == 4) {
2182 /*
2183 * Backwards compatibility.
2184 */
2185 if (tmpsecs == 0) {
2186 //This is "NULL" time
2187 time_stamp->secs = 0;
2188 }
2189 time_stamp->nsecs = 0;
2190 } else {
2191 time_stamp->secs = 0;
2192 time_stamp->nsecs = 0;
2193 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2194 }
2195 break;
2196
2197 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2198 /*
2199 * S/3x0 and z/Architecture TOD clock time stamp,
2200 * big-endian. The epoch is January 1, 1900,
2201 * 00:00:00 (proleptic?) UTC.
2202 *
2203 * Only supported for absolute times.
2204 */
2205 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2205, "!is_relative"
))))
;
2206 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2206, "length == 8"
))))
;
2207
2208 if (length == 8) {
2209 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2210 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2211 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2212 } else {
2213 time_stamp->secs = 0;
2214 time_stamp->nsecs = 0;
2215 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2216 }
2217 break;
2218
2219 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2220 /*
2221 * S/3x0 and z/Architecture TOD clock time stamp,
2222 * little-endian. The epoch is January 1, 1900,
2223 * 00:00:00 (proleptic?) UTC.
2224 *
2225 * Only supported for absolute times.
2226 */
2227 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2227, "!is_relative"
))))
;
2228
2229 if (length == 8) {
2230 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2231 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2232 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2233 } else {
2234 time_stamp->secs = 0;
2235 time_stamp->nsecs = 0;
2236 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2237 }
2238 break;
2239
2240 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2241 /*
2242 * Time stamp using the same seconds/fraction format
2243 * as NTP, but with the origin of the time stamp being
2244 * the UNIX epoch rather than the NTP epoch; big-
2245 * endian.
2246 *
2247 * Only supported for absolute times.
2248 */
2249 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2249, "!is_relative"
))))
;
2250
2251 if (length == 8) {
2252 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2253 /*
2254 * Convert 1/2^32s of a second to nanoseconds.
2255 */
2256 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2257 } else {
2258 time_stamp->secs = 0;
2259 time_stamp->nsecs = 0;
2260 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2261 }
2262 break;
2263
2264 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2265 /*
2266 * Time stamp using the same seconds/fraction format
2267 * as NTP, but with the origin of the time stamp being
2268 * the UNIX epoch rather than the NTP epoch; little-
2269 * endian.
2270 *
2271 * Only supported for absolute times.
2272 *
2273 * The RTPS specification explicitly supports Little
2274 * Endian encoding. In one place, it states that its
2275 * Time_t representation "is the one defined by ...
2276 * RFC 1305", but in another explicitly defines it as
2277 * a struct consisting of an 32 bit unsigned seconds
2278 * field and a 32 bit unsigned fraction field, not a 64
2279 * bit fixed point, so we do that here.
2280 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2281 */
2282 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2282, "!is_relative"
))))
;
2283
2284 if (length == 8) {
2285 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2286 /*
2287 * Convert 1/2^32s of a second to nanoseconds.
2288 */
2289 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2290 } else {
2291 time_stamp->secs = 0;
2292 time_stamp->nsecs = 0;
2293 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2294 }
2295 break;
2296
2297 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2298 /*
2299 * MIP6 time stamp, big-endian.
2300 * A 64-bit unsigned integer field containing a timestamp. The
2301 * value indicates the number of seconds since January 1, 1970,
2302 * 00:00 UTC, by using a fixed point format. In this format, the
2303 * integer number of seconds is contained in the first 48 bits of
2304 * the field, and the remaining 16 bits indicate the number of
2305 * 1/65536 fractions of a second.
2306
2307 * Only supported for absolute times.
2308 */
2309 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2309, "!is_relative"
))))
;
2310
2311 if (length == 8) {
2312 /* We need a temporary variable here so the casting and fractions
2313 * of a second work correctly.
2314 */
2315 tmp64secs = tvb_get_ntoh48(tvb, start);
2316 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2317 tmpsecs <<= 16;
2318
2319 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2320 //This is "NULL" time
2321 time_stamp->secs = 0;
2322 time_stamp->nsecs = 0;
2323 } else {
2324 time_stamp->secs = (time_t)tmp64secs;
2325 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2326 }
2327 } else {
2328 time_stamp->secs = 0;
2329 time_stamp->nsecs = 0;
2330 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2331 }
2332 break;
2333
2334 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2335 /*
2336 * If the length is 16, 8-byte seconds, followed
2337 * by 8-byte fractional time in microseconds,
2338 * both big-endian.
2339 *
2340 * If the length is 12, 8-byte seconds, followed
2341 * by 4-byte fractional time in microseconds,
2342 * both big-endian.
2343 *
2344 * If the length is 8, 4-byte seconds, followed
2345 * by 4-byte fractional time in microseconds,
2346 * both big-endian.
2347 *
2348 * For absolute times, the seconds are seconds
2349 * since the UN*X epoch.
2350 */
2351 if (length == 16) {
2352 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2353 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2354 } else if (length == 12) {
2355 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2356 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2357 } else if (length == 8) {
2358 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2359 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2360 } else {
2361 time_stamp->secs = 0;
2362 time_stamp->nsecs = 0;
2363 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2364 }
2365 break;
2366
2367 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2368 /*
2369 * If the length is 16, 8-byte seconds, followed
2370 * by 8-byte fractional time in microseconds,
2371 * both little-endian.
2372 *
2373 * If the length is 12, 8-byte seconds, followed
2374 * by 4-byte fractional time in microseconds,
2375 * both little-endian.
2376 *
2377 * If the length is 8, 4-byte seconds, followed
2378 * by 4-byte fractional time in microseconds,
2379 * both little-endian.
2380 *
2381 * For absolute times, the seconds are seconds
2382 * since the UN*X epoch.
2383 */
2384 if (length == 16) {
2385 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2386 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2387 } else if (length == 12) {
2388 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2389 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2390 } else if (length == 8) {
2391 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2392 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2393 } else {
2394 time_stamp->secs = 0;
2395 time_stamp->nsecs = 0;
2396 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2397 }
2398 break;
2399
2400 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2401 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2402 /*
2403 * Seconds, 1 to 8 bytes.
2404 * For absolute times, it's seconds since the
2405 * UN*X epoch.
2406 */
2407 if (length >= 1 && length <= 8) {
2408 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2409 time_stamp->nsecs = 0;
2410 } else {
2411 time_stamp->secs = 0;
2412 time_stamp->nsecs = 0;
2413 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2414 }
2415 break;
2416
2417 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2418 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2419 /*
2420 * Milliseconds, 1 to 8 bytes.
2421 * For absolute times, it's milliseconds since the
2422 * UN*X epoch.
2423 */
2424 if (length >= 1 && length <= 8) {
2425 uint64_t msecs;
2426
2427 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2428 time_stamp->secs = (time_t)(msecs / 1000);
2429 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2430 } else {
2431 time_stamp->secs = 0;
2432 time_stamp->nsecs = 0;
2433 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2434 }
2435 break;
2436
2437 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2438 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2439 /*
2440 * Microseconds, 1 to 8 bytes.
2441 * For absolute times, it's microseconds since the
2442 * UN*X epoch.
2443 */
2444 if (length >= 1 && length <= 8) {
2445 uint64_t usecs;
2446
2447 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2448 time_stamp->secs = (time_t)(usecs / 1000000);
2449 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2450 } else {
2451 time_stamp->secs = 0;
2452 time_stamp->nsecs = 0;
2453 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2454 }
2455 break;
2456
2457 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2458 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2459 /*
2460 * nanoseconds, 1 to 8 bytes.
2461 * For absolute times, it's nanoseconds since the
2462 * UN*X epoch.
2463 */
2464
2465 if (length >= 1 && length <= 8) {
2466 uint64_t nsecs;
2467
2468 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2469 time_stamp->secs = (time_t)(nsecs / 1000000000);
2470 time_stamp->nsecs = (int)(nsecs % 1000000000);
2471 } else {
2472 time_stamp->secs = 0;
2473 time_stamp->nsecs = 0;
2474 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2475 }
2476 break;
2477
2478 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2479 /*
2480 * 1/64ths of a second since the UN*X epoch,
2481 * big-endian.
2482 *
2483 * Only supported for absolute times.
2484 */
2485 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2485, "!is_relative"
))))
;
2486
2487 if (length == 8) {
2488 /*
2489 * The upper 48 bits are seconds since the
2490 * UN*X epoch.
2491 */
2492 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2493 /*
2494 * The lower 16 bits are 1/2^16s of a second;
2495 * convert them to nanoseconds.
2496 *
2497 * XXX - this may give the impression of higher
2498 * precision than you actually get.
2499 */
2500 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2501 } else {
2502 time_stamp->secs = 0;
2503 time_stamp->nsecs = 0;
2504 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2505 }
2506 break;
2507
2508 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2509 /*
2510 * 1/64ths of a second since the UN*X epoch,
2511 * little-endian.
2512 *
2513 * Only supported for absolute times.
2514 */
2515 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2515, "!is_relative"
))))
;
2516
2517 if (length == 8) {
2518 /*
2519 * XXX - this is assuming that, if anybody
2520 * were ever to use this format - RFC 3971
2521 * doesn't, because that's an Internet
2522 * protocol, and those use network byte
2523 * order, i.e. big-endian - they'd treat it
2524 * as a 64-bit count of 1/2^16s of a second,
2525 * putting the upper 48 bits at the end.
2526 *
2527 * The lower 48 bits are seconds since the
2528 * UN*X epoch.
2529 */
2530 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2531 /*
2532 * The upper 16 bits are 1/2^16s of a second;
2533 * convert them to nanoseconds.
2534 *
2535 * XXX - this may give the impression of higher
2536 * precision than you actually get.
2537 */
2538 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2539 } else {
2540 time_stamp->secs = 0;
2541 time_stamp->nsecs = 0;
2542 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2543 }
2544 break;
2545
2546 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2547 /*
2548 * NTP time stamp, with 1-second resolution (i.e.,
2549 * seconds since the NTP epoch), big-endian.
2550 * Only supported for absolute times.
2551 */
2552 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2552, "!is_relative"
))))
;
2553
2554 if (length == 4) {
2555 /*
2556 * We need a temporary variable here so the unsigned math
2557 * works correctly (for years > 2036 according to RFC 2030
2558 * chapter 3).
2559 *
2560 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2561 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2562 * If bit 0 is not set, the time is in the range 2036-2104 and
2563 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2564 */
2565 tmpsecs = tvb_get_ntohl(tvb, start);
2566 if ((tmpsecs & 0x80000000) != 0)
2567 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2568 else
2569 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2570 time_stamp->nsecs = 0;
2571 } else {
2572 time_stamp->secs = 0;
2573 time_stamp->nsecs = 0;
2574 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2575 }
2576 break;
2577
2578 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2579 /*
2580 * NTP time stamp, with 1-second resolution (i.e.,
2581 * seconds since the NTP epoch), little-endian.
2582 * Only supported for absolute times.
2583 */
2584 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2584, "!is_relative"
))))
;
2585
2586 /*
2587 * We need a temporary variable here so the unsigned math
2588 * works correctly (for years > 2036 according to RFC 2030
2589 * chapter 3).
2590 *
2591 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2592 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2593 * If bit 0 is not set, the time is in the range 2036-2104 and
2594 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2595 */
2596 if (length == 4) {
2597 tmpsecs = tvb_get_letohl(tvb, start);
2598 if ((tmpsecs & 0x80000000) != 0)
2599 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2600 else
2601 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2602 time_stamp->nsecs = 0;
2603 } else {
2604 time_stamp->secs = 0;
2605 time_stamp->nsecs = 0;
2606 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2607 }
2608 break;
2609
2610 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2611 /*
2612 * Milliseconds, 6 to 8 bytes.
2613 * For absolute times, it's milliseconds since the
2614 * NTP epoch.
2615 *
2616 * ETSI TS 129.274 8.119 defines this as:
2617 * "a 48 bit unsigned integer in network order format
2618 * ...encoded as the number of milliseconds since
2619 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2620 * rounded value of 1000 x the value of the 64-bit
2621 * timestamp (Seconds + (Fraction / (1<<32))) defined
2622 * in clause 6 of IETF RFC 5905."
2623 *
2624 * Taken literally, the part after "i.e." would
2625 * mean that the value rolls over before reaching
2626 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2627 * when the 64 bit timestamp rolls over, and we have
2628 * to pick an NTP Era equivalence class to support
2629 * (such as 1968-01-20 to 2104-02-06).
2630 *
2631 * OTOH, the extra room might be used to store Era
2632 * information instead, in which case times until
2633 * 10819-08-03 can be represented with 6 bytes without
2634 * ambiguity. We handle both implementations, and assume
2635 * that times before 1968-01-20 are not represented.
2636 *
2637 * Only 6 bytes or more makes sense as an absolute
2638 * time. 5 bytes or fewer could express a span of
2639 * less than 35 years, either 1900-1934 or 2036-2070.
2640 */
2641 if (length >= 6 && length <= 8) {
2642 uint64_t msecs;
2643
2644 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2645 tmp64secs = (msecs / 1000);
2646 /*
2647 * Assume that times in the first half of NTP
2648 * Era 0 really represent times in the NTP
2649 * Era 1.
2650 */
2651 if (tmp64secs >= 0x80000000)
2652 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2653 else
2654 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2655 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2656 }
2657 else {
2658 time_stamp->secs = 0;
2659 time_stamp->nsecs = 0;
2660 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2661 }
2662 break;
2663
2664 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2665 /*
2666 * MP4 file time stamps, big-endian.
2667 * Only supported for absolute times.
2668 */
2669 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2669, "!is_relative"
))))
;
2670
2671 if (length == 8) {
2672 tmp64secs = tvb_get_ntoh64(tvb, start);
2673 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2674 time_stamp->nsecs = 0;
2675 } else if (length == 4) {
2676 tmpsecs = tvb_get_ntohl(tvb, start);
2677 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2678 time_stamp->nsecs = 0;
2679 } else {
2680 time_stamp->secs = 0;
2681 time_stamp->nsecs = 0;
2682 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2683 }
2684 break;
2685
2686 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2687 /*
2688 * Zigbee ZCL time stamps, big-endian.
2689 * Only supported for absolute times.
2690 */
2691 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2691, "!is_relative"
))))
;
2692
2693 if (length == 8) {
2694 tmp64secs = tvb_get_ntoh64(tvb, start);
2695 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))
) {
2696 /* There are several other possible choices for what to do
2697 * with overflow; make sure to coordinate with whatever
2698 * packet-zbee-zcl.h does. */
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 if (length == 4) {
2703 tmpsecs = tvb_get_ntohl(tvb, start);
2704 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))
) {
2705 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))))))
;
2706 }
2707 time_stamp->nsecs = 0;
2708 } else {
2709 time_stamp->secs = 0;
2710 time_stamp->nsecs = 0;
2711 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 }
2713 break;
2714
2715 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2716 /*
2717 * Zigbee ZCL time stamps, little-endian.
2718 * Only supported for absolute times.
2719 */
2720 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2720, "!is_relative"
))))
;
2721
2722 if (length == 8) {
2723 tmp64secs = tvb_get_letoh64(tvb, start);
2724 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))
) {
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 if (length == 4) {
2729 tmpsecs = tvb_get_letohl(tvb, start);
2730 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))
) {
2731 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))))))
;
2732 }
2733 time_stamp->nsecs = 0;
2734 } else {
2735 time_stamp->secs = 0;
2736 time_stamp->nsecs = 0;
2737 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2738 }
2739 break;
2740
2741 default:
2742 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2742))
;
2743 break;
2744 }
2745}
2746
2747static void
2748tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2749{
2750 const header_field_info *hfinfo = fi->hfinfo;
2751
2752 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2753 GPtrArray *ptrs = NULL((void*)0);
2754
2755 if (tree_data->interesting_hfids == NULL((void*)0)) {
2756 /* Initialize the hash because we now know that it is needed */
2757 tree_data->interesting_hfids =
2758 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2759 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2760 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2761 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2762 }
2763
2764 if (!ptrs) {
2765 /* First element triggers the creation of pointer array */
2766 ptrs = g_ptr_array_new();
2767 g_hash_table_insert(tree_data->interesting_hfids,
2768 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2769 }
2770
2771 g_ptr_array_add(ptrs, fi);
2772 }
2773}
2774
2775
2776/*
2777 * Validates that field length bytes are available starting from
2778 * start (pos/neg). Throws an exception if they aren't.
2779 */
2780static void
2781test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2782 unsigned start, int length, const unsigned encoding)
2783{
2784 int size = length;
2785
2786 if (!tvb)
2787 return;
2788
2789 if ((hfinfo->type == FT_STRINGZ) ||
2790 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2791 (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
))
))) {
2792 /* If we're fetching until the end of the TVB, only validate
2793 * that the offset is within range.
2794 */
2795 if (length == -1)
2796 size = 0;
2797 }
2798
2799 tvb_ensure_bytes_exist(tvb, start, size);
2800}
2801
2802static void
2803detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2804{
2805 bool_Bool found_stray_character = false0;
2806
2807 if (!string)
2808 return;
2809
2810 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2811 case ENC_ASCII0x00000000:
2812 case ENC_UTF_80x00000002:
2813 for (int i = (int)strlen(string); i < length; i++) {
2814 if (string[i] != '\0') {
2815 found_stray_character = true1;
2816 break;
2817 }
2818 }
2819 break;
2820
2821 default:
2822 break;
2823 }
2824
2825 if (found_stray_character) {
2826 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2827 }
2828}
2829
2830/* Add an item to a proto_tree, using the text label registered to that item;
2831 the item is extracted from the tvbuff handed to it. */
2832static proto_item *
2833proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2834 tvbuff_t *tvb, unsigned start, int length,
2835 unsigned encoding)
2836{
2837 proto_item *pi;
2838 uint32_t value, n;
2839 uint64_t value64;
2840 ws_in4_addr ipv4_value;
2841 float floatval;
2842 double doubleval;
2843 const char *stringval = NULL((void*)0);
2844 nstime_t time_stamp;
2845 bool_Bool length_error;
2846 unsigned item_length;
2847
2848 // new_fi->value is allocated from the packet-scoped pool (see
2849 // new_field_info()), so if a tvbuff accessor below throws before the
2850 // node is added to the tree the fvalue_t structure is still reclaimed
2851 // when the pool is freed; no explicit cleanup handler is needed. This
2852 // relies on the invariant that the type-specific data an fvalue owns
2853 // (byte arrays, string buffers, ...) is only allocated *after* the
2854 // throwing tvbuff read that produced it succeeds, so nothing that would
2855 // need fvalue_cleanup() is ever leaked on the exception path.
2856 switch (new_fi->hfinfo->type) {
2857 case FT_NONE:
2858 /* no value to set for FT_NONE */
2859 break;
2860
2861 case FT_PROTOCOL:
2862 /* Set the protocol_tvb via the start offset, but include
2863 * rest of the ds_tvb so that if finfo_set_len is called
2864 * later it can be lengthened as much as possible. */
2865 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);
2866 break;
2867
2868 case FT_BYTES:
2869 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2870 break;
2871
2872 case FT_UINT_BYTES:
2873 n = get_uint_value(tree, tvb, start, length, encoding);
2874 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2875
2876 /* Instead of calling proto_item_set_len(), since we don't yet
2877 * have a proto_item, we set the field_info's length ourselves. */
2878 new_fi->length = n + length;
2879 break;
2880
2881 case FT_BOOLEAN:
2882 /*
2883 * Map all non-zero values to little-endian for
2884 * backwards compatibility.
2885 */
2886 if (encoding)
2887 encoding = ENC_LITTLE_ENDIAN0x80000000;
2888 proto_tree_set_boolean(new_fi,
2889 get_uint64_value(tree, tvb, start, length, encoding));
2890 break;
2891
2892 case FT_CHAR:
2893 /* XXX - make these just FT_UINT? */
2894 case FT_UINT8:
2895 case FT_UINT16:
2896 case FT_UINT24:
2897 case FT_UINT32:
2898 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2899 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2900 value = (uint32_t)value64;
2901 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2902 new_fi->flags |= FI_VARINT0x00040000;
2903 }
2904 }
2905 else {
2906 /*
2907 * Map all non-zero values to little-endian for
2908 * backwards compatibility.
2909 */
2910 if (encoding)
2911 encoding = ENC_LITTLE_ENDIAN0x80000000;
2912
2913 value = get_uint_value(tree, tvb, start, length, encoding);
2914 }
2915 proto_tree_set_uint(new_fi, value);
2916 break;
2917
2918 case FT_UINT40:
2919 case FT_UINT48:
2920 case FT_UINT56:
2921 case FT_UINT64:
2922 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2923 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2924 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2925 new_fi->flags |= FI_VARINT0x00040000;
2926 }
2927 }
2928 else {
2929 /*
2930 * Map all other non-zero values to little-endian for
2931 * backwards compatibility.
2932 */
2933 if (encoding)
2934 encoding = ENC_LITTLE_ENDIAN0x80000000;
2935
2936 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2937 }
2938 proto_tree_set_uint64(new_fi, value64);
2939 break;
2940
2941 /* XXX - make these just FT_INT? */
2942 case FT_INT8:
2943 case FT_INT16:
2944 case FT_INT24:
2945 case FT_INT32:
2946 /*
2947 * Map all non-zero values to little-endian for
2948 * backwards compatibility.
2949 */
2950 if (encoding)
2951 encoding = ENC_LITTLE_ENDIAN0x80000000;
2952 proto_tree_set_int(new_fi,
2953 get_int_value(tree, tvb, start, length, encoding));
2954 break;
2955
2956 case FT_INT40:
2957 case FT_INT48:
2958 case FT_INT56:
2959 case FT_INT64:
2960 /*
2961 * Map all non-zero values to little-endian for
2962 * backwards compatibility.
2963 */
2964 if (encoding)
2965 encoding = ENC_LITTLE_ENDIAN0x80000000;
2966 proto_tree_set_int64(new_fi,
2967 get_int64_value(tree, tvb, start, length, encoding));
2968 break;
2969
2970 case FT_IPv4:
2971 /*
2972 * Map all non-zero values to little-endian for
2973 * backwards compatibility.
2974 */
2975 if (encoding)
2976 encoding = ENC_LITTLE_ENDIAN0x80000000;
2977 if (length != FT_IPv4_LEN4) {
2978 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2979 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2980 }
2981 ipv4_value = tvb_get_ipv4(tvb, start);
2982 /*
2983 * NOTE: to support code written when
2984 * proto_tree_add_item() took a bool as its
2985 * last argument, with false meaning "big-endian"
2986 * and true meaning "little-endian", we treat any
2987 * non-zero value of "encoding" as meaning
2988 * "little-endian".
2989 */
2990 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);
2991 break;
2992
2993 case FT_IPXNET:
2994 if (length != FT_IPXNET_LEN4) {
2995 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2996 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2997 }
2998 proto_tree_set_ipxnet(new_fi,
2999 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
3000 break;
3001
3002 case FT_IPv6:
3003 if (length != FT_IPv6_LEN16) {
3004 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
3005 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3006 }
3007 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3008 break;
3009
3010 case FT_FCWWN:
3011 if (length != FT_FCWWN_LEN8) {
3012 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3013 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3014 }
3015 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3016 break;
3017
3018 case FT_AX25:
3019 if (length != 7) {
3020 length_error = length < 7 ? true1 : false0;
3021 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3022 }
3023 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3024 break;
3025
3026 case FT_VINES:
3027 if (length != VINES_ADDR_LEN6) {
3028 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3029 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3030 }
3031 proto_tree_set_vines_tvb(new_fi, tvb, start);
3032 break;
3033
3034 case FT_ETHER:
3035 if (length != FT_ETHER_LEN6) {
3036 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3037 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3038 }
3039 proto_tree_set_ether_tvb(new_fi, tvb, start);
3040 break;
3041
3042 case FT_EUI64:
3043 /*
3044 * Map all non-zero values to little-endian for
3045 * backwards compatibility.
3046 */
3047 if (encoding)
3048 encoding = ENC_LITTLE_ENDIAN0x80000000;
3049 if (length != FT_EUI64_LEN8) {
3050 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3051 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3052 }
3053 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3054 break;
3055 case FT_GUID:
3056 /*
3057 * Map all non-zero values to little-endian for
3058 * backwards compatibility.
3059 */
3060 if (encoding)
3061 encoding = ENC_LITTLE_ENDIAN0x80000000;
3062 if (length != FT_GUID_LEN16) {
3063 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3064 report_type_length_mismatch(tree, "a GUID", length, length_error);
3065 }
3066 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3067 break;
3068
3069 case FT_OID:
3070 case FT_REL_OID:
3071 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3072 break;
3073
3074 case FT_SYSTEM_ID:
3075 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3076 break;
3077
3078 case FT_FLOAT:
3079 /*
3080 * NOTE: to support code written when
3081 * proto_tree_add_item() took a bool as its
3082 * last argument, with false meaning "big-endian"
3083 * and true meaning "little-endian", we treat any
3084 * non-zero value of "encoding" as meaning
3085 * "little-endian".
3086 *
3087 * At some point in the future, we might
3088 * support non-IEEE-binary floating-point
3089 * formats in the encoding as well
3090 * (IEEE decimal, System/3x0, VAX).
3091 */
3092 if (encoding)
3093 encoding = ENC_LITTLE_ENDIAN0x80000000;
3094 if (length != 4) {
3095 length_error = length < 4 ? true1 : false0;
3096 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3097 }
3098 if (encoding)
3099 floatval = tvb_get_letohieee_float(tvb, start);
3100 else
3101 floatval = tvb_get_ntohieee_float(tvb, start);
3102 proto_tree_set_float(new_fi, floatval);
3103 break;
3104
3105 case FT_DOUBLE:
3106 /*
3107 * NOTE: to support code written when
3108 * proto_tree_add_item() took a bool as its
3109 * last argument, with false meaning "big-endian"
3110 * and true meaning "little-endian", we treat any
3111 * non-zero value of "encoding" as meaning
3112 * "little-endian".
3113 *
3114 * At some point in the future, we might
3115 * support non-IEEE-binary floating-point
3116 * formats in the encoding as well
3117 * (IEEE decimal, System/3x0, VAX).
3118 */
3119 if (encoding == true1)
3120 encoding = ENC_LITTLE_ENDIAN0x80000000;
3121 if (length != 8) {
3122 length_error = length < 8 ? true1 : false0;
3123 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3124 }
3125 if (encoding)
3126 doubleval = tvb_get_letohieee_double(tvb, start);
3127 else
3128 doubleval = tvb_get_ntohieee_double(tvb, start);
3129 proto_tree_set_double(new_fi, doubleval);
3130 break;
3131
3132 case FT_STRING:
3133 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3134 tvb, start, length, &item_length, encoding);
3135 proto_tree_set_string(new_fi, stringval);
3136
3137 /* Instead of calling proto_item_set_len(), since we
3138 * don't yet have a proto_item, we set the
3139 * field_info's length ourselves.
3140 *
3141 * XXX - our caller can't use that length to
3142 * advance an offset unless they arrange that
3143 * there always be a protocol tree into which
3144 * we're putting this item.
3145 */
3146 new_fi->length = item_length;
3147 break;
3148
3149 case FT_STRINGZ:
3150 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3151 tree, tvb, start, length, &item_length, encoding);
3152 proto_tree_set_string(new_fi, stringval);
3153
3154 /* Instead of calling proto_item_set_len(),
3155 * since we don't yet have a proto_item, we
3156 * set the field_info's length ourselves.
3157 *
3158 * XXX - our caller can't use that length to
3159 * advance an offset unless they arrange that
3160 * there always be a protocol tree into which
3161 * we're putting this item.
3162 */
3163 new_fi->length = item_length;
3164 break;
3165
3166 case FT_UINT_STRING:
3167 /*
3168 * NOTE: to support code written when
3169 * proto_tree_add_item() took a bool as its
3170 * last argument, with false meaning "big-endian"
3171 * and true meaning "little-endian", if the
3172 * encoding value is true, treat that as
3173 * ASCII with a little-endian length.
3174 *
3175 * This won't work for code that passes
3176 * arbitrary non-zero values; that code
3177 * will need to be fixed.
3178 */
3179 if (encoding == true1)
3180 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3181 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3182 tree, tvb, start, length, &item_length, encoding);
3183 proto_tree_set_string(new_fi, stringval);
3184
3185 /* Instead of calling proto_item_set_len(), since we
3186 * don't yet have a proto_item, we set the
3187 * field_info's length ourselves.
3188 *
3189 * XXX - our caller can't use that length to
3190 * advance an offset unless they arrange that
3191 * there always be a protocol tree into which
3192 * we're putting this item.
3193 */
3194 new_fi->length = item_length;
3195 break;
3196
3197 case FT_STRINGZPAD:
3198 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3199 tvb, start, length, &item_length, encoding);
3200 proto_tree_set_string(new_fi, stringval);
3201
3202 /* Instead of calling proto_item_set_len(), since we
3203 * don't yet have a proto_item, we set the
3204 * field_info's length ourselves.
3205 *
3206 * XXX - our caller can't use that length to
3207 * advance an offset unless they arrange that
3208 * there always be a protocol tree into which
3209 * we're putting this item.
3210 */
3211 new_fi->length = item_length;
3212 break;
3213
3214 case FT_STRINGZTRUNC:
3215 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3216 tvb, start, length, &item_length, encoding);
3217 proto_tree_set_string(new_fi, stringval);
3218
3219 /* Instead of calling proto_item_set_len(), since we
3220 * don't yet have a proto_item, we set the
3221 * field_info's length ourselves.
3222 *
3223 * XXX - our caller can't use that length to
3224 * advance an offset unless they arrange that
3225 * there always be a protocol tree into which
3226 * we're putting this item.
3227 */
3228 new_fi->length = item_length;
3229 break;
3230
3231 case FT_ABSOLUTE_TIME:
3232 /*
3233 * Absolute times can be in any of a number of
3234 * formats, and they can be big-endian or
3235 * little-endian.
3236 *
3237 * Historically FT_TIMEs were only timespecs;
3238 * the only question was whether they were stored
3239 * in big- or little-endian format.
3240 *
3241 * For backwards compatibility, we interpret an
3242 * encoding of 1 as meaning "little-endian timespec",
3243 * so that passing true is interpreted as that.
3244 */
3245 if (encoding == true1)
3246 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3247
3248 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3249
3250 proto_tree_set_time(new_fi, &time_stamp);
3251 break;
3252
3253 case FT_RELATIVE_TIME:
3254 /*
3255 * Relative times can be in any of a number of
3256 * formats, and they can be big-endian or
3257 * little-endian.
3258 *
3259 * Historically FT_TIMEs were only timespecs;
3260 * the only question was whether they were stored
3261 * in big- or little-endian format.
3262 *
3263 * For backwards compatibility, we interpret an
3264 * encoding of 1 as meaning "little-endian timespec",
3265 * so that passing true is interpreted as that.
3266 */
3267 if (encoding == true1)
3268 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3269
3270 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3271
3272 proto_tree_set_time(new_fi, &time_stamp);
3273 break;
3274 case FT_IEEE_11073_SFLOAT:
3275 if (encoding)
3276 encoding = ENC_LITTLE_ENDIAN0x80000000;
3277 if (length != 2) {
3278 length_error = length < 2 ? true1 : false0;
3279 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3280 }
3281
3282 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3283
3284 break;
3285 case FT_IEEE_11073_FLOAT:
3286 if (encoding)
3287 encoding = ENC_LITTLE_ENDIAN0x80000000;
3288 if (length != 4) {
3289 length_error = length < 4 ? true1 : false0;
3290 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3291 }
3292 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3293
3294 break;
3295 default:
3296 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))
3297 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))
3298 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))
3299 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))
;
3300 break;
3301 }
3302 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)
;
3303
3304 /* Don't add new node to proto_tree until now so that any exceptions
3305 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3306 /* XXX. wouldn't be better to add this item to tree, with some special
3307 * flag (FI_EXCEPTION?) to know which item caused exception? For
3308 * strings and bytes, we would have to set new_fi->value to something
3309 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3310 * could handle NULL values. */
3311 pi = proto_tree_add_node(tree, new_fi);
3312
3313 switch (new_fi->hfinfo->type) {
3314
3315 case FT_STRING:
3316 /* XXX: trailing stray character detection should be done
3317 * _before_ conversion to UTF-8, because conversion can change
3318 * the length, or else get_string_length should return a value
3319 * for the "length in bytes of the string after conversion
3320 * including internal nulls." (Noting that we do, for other
3321 * reasons, still need the "length in bytes in the field",
3322 * especially for FT_STRINGZ.)
3323 *
3324 * This is true even for ASCII and UTF-8, because
3325 * substituting REPLACEMENT CHARACTERS for illegal characters
3326 * can also do so (and for UTF-8 possibly even make the
3327 * string _shorter_).
3328 */
3329 detect_trailing_stray_characters(encoding, stringval, item_length, pi);
3330 break;
3331
3332 default:
3333 break;
3334 }
3335
3336 return pi;
3337}
3338
3339proto_item *
3340proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3341 const unsigned start, unsigned length,
3342 const unsigned encoding, int32_t *retval)
3343{
3344 header_field_info *hfinfo;
3345 field_info *new_fi;
3346 int32_t value;
3347
3348 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", 3348, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3348,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3348, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3349
3350 switch (hfinfo->type) {
3351 case FT_INT8:
3352 case FT_INT16:
3353 case FT_INT24:
3354 case FT_INT32:
3355 break;
3356 case FT_INT64:
3357 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)
3358 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3359 default:
3360 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)
3361 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3362 }
3363
3364 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3365 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3366 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3367 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3368 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3369 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3370 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3371
3372 if (encoding & ENC_STRING0x07000000) {
3373 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3374 }
3375 /* I believe it's ok if this is called with a NULL tree */
3376 value = get_int_value(tree, tvb, start, length, encoding);
3377
3378 if (retval) {
3379 int no_of_bits;
3380 *retval = value;
3381 if (hfinfo->bitmask) {
3382 /* Mask out irrelevant portions */
3383 *retval &= (uint32_t)(hfinfo->bitmask);
3384 /* Shift bits */
3385 *retval >>= hfinfo_bitshift(hfinfo);
3386 }
3387 no_of_bits = ws_count_ones(hfinfo->bitmask);
3388 *retval = ws_sign_ext32(*retval, no_of_bits);
3389 }
3390
3391 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3392
3393 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", 3393
, __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", 3393, "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", 3393, "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", 3393, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3394
3395 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3396
3397 proto_tree_set_int(new_fi, value);
3398
3399 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3400
3401 return proto_tree_add_node(tree, new_fi);
3402}
3403
3404proto_item *
3405proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3406 const unsigned start, unsigned length,
3407 const unsigned encoding, uint32_t *retval)
3408{
3409 header_field_info *hfinfo;
3410 field_info *new_fi;
3411 uint32_t value;
3412
3413 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", 3413, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3413,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3413, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3414
3415 switch (hfinfo->type) {
3416 case FT_CHAR:
3417 case FT_UINT8:
3418 case FT_UINT16:
3419 case FT_UINT24:
3420 case FT_UINT32:
3421 break;
3422 default:
3423 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)
3424 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)
;
3425 }
3426
3427 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,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 if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3430 *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3431 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3432 return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3433 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3434 )if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
;
3435
3436 if (encoding & ENC_STRING0x07000000) {
3437 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3438 }
3439 /* I believe it's ok if this is called with a NULL tree */
3440 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3441 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3442 uint64_t temp64;
3443 tvb_get_varint(tvb, start, length, &temp64, encoding);
3444 value = (uint32_t)temp64;
3445 } else {
3446 value = get_uint_value(tree, tvb, start, length, encoding);
3447 }
3448
3449 if (retval) {
3450 *retval = value;
3451 if (hfinfo->bitmask) {
3452 /* Mask out irrelevant portions */
3453 *retval &= (uint32_t)(hfinfo->bitmask);
3454 /* Shift bits */
3455 *retval >>= hfinfo_bitshift(hfinfo);
3456 }
3457 }
3458
3459 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3460
3461 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", 3461
, __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", 3461, "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", 3461, "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", 3461, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3462
3463 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3464
3465 proto_tree_set_uint(new_fi, value);
3466
3467 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3468 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3469 new_fi->flags |= FI_VARINT0x00040000;
3470 }
3471 return proto_tree_add_node(tree, new_fi);
3472}
3473
3474proto_item *
3475proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3476 const unsigned start, unsigned length,
3477 const unsigned encoding, uint32_t *retval)
3478{
3479 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3480}
3481
3482proto_item *
3483proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3484 const unsigned start, unsigned length,
3485 const unsigned encoding, uint8_t *retval)
3486{
3487 /* TODO: further restrict by hfinfo->type ? */
3488 uint32_t val32;
3489 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3490 *retval = (uint8_t)val32;
3491 return item;
3492}
3493
3494proto_item *
3495proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3496 const unsigned start, unsigned length,
3497 const unsigned encoding, uint16_t *retval)
3498{
3499 /* TODO: further restrict by hfinfo->type ? */
3500 uint32_t val32;
3501 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3502 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3503 return item;
3504}
3505
3506
3507/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3508 * and returns proto_item* and uint value retrieved*/
3509proto_item *
3510ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3511 const unsigned encoding, uint32_t *retval)
3512{
3513 field_info *new_fi;
3514 header_field_info *hfinfo;
3515 unsigned item_length;
3516 unsigned offset;
3517 uint32_t value;
3518
3519 offset = ptvc->offset;
3520 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", 3520, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3520,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3520, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3521
3522 switch (hfinfo->type) {
3523 case FT_CHAR:
3524 case FT_UINT8:
3525 case FT_UINT16:
3526 case FT_UINT24:
3527 case FT_UINT32:
3528 break;
3529 default:
3530 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)
3531 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)
;
3532 }
3533
3534 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3535 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3536
3537 /* I believe it's ok if this is called with a NULL tree */
3538 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3539 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3540
3541 if (retval) {
3542 *retval = value;
3543 if (hfinfo->bitmask) {
3544 /* Mask out irrelevant portions */
3545 *retval &= (uint32_t)(hfinfo->bitmask);
3546 /* Shift bits */
3547 *retval >>= hfinfo_bitshift(hfinfo);
3548 }
3549 }
3550
3551 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3552
3553 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3554
3555 /* Coast clear. Try and fake it */
3556 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", 3556
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3556, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3556, "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", 3556, __func__, "Adding %s would put more than %d 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); } } }
;
3557
3558 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3559
3560 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3561 offset, length, encoding);
3562}
3563
3564/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3565 * and returns proto_item* and int value retrieved*/
3566proto_item *
3567ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3568 const unsigned encoding, int32_t *retval)
3569{
3570 field_info *new_fi;
3571 header_field_info *hfinfo;
3572 unsigned item_length;
3573 unsigned offset;
3574 uint32_t value;
3575
3576 offset = ptvc->offset;
3577 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", 3577, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3577,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3577, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3578
3579 switch (hfinfo->type) {
3580 case FT_INT8:
3581 case FT_INT16:
3582 case FT_INT24:
3583 case FT_INT32:
3584 break;
3585 default:
3586 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)
3587 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3588 }
3589
3590 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3591 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3592
3593 /* I believe it's ok if this is called with a NULL tree */
3594 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3595 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3596
3597 if (retval) {
3598 int no_of_bits;
3599 *retval = value;
3600 if (hfinfo->bitmask) {
3601 /* Mask out irrelevant portions */
3602 *retval &= (uint32_t)(hfinfo->bitmask);
3603 /* Shift bits */
3604 *retval >>= hfinfo_bitshift(hfinfo);
3605 }
3606 no_of_bits = ws_count_ones(hfinfo->bitmask);
3607 *retval = ws_sign_ext32(*retval, no_of_bits);
3608 }
3609
3610 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3611
3612 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3613
3614 /* Coast clear. Try and fake it */
3615 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", 3615
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3615, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3615, "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", 3615, __func__, "Adding %s would put more than %d 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); } } }
;
3616
3617 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3618
3619 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3620 offset, length, encoding);
3621}
3622
3623/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3624 * and returns proto_item* and string value retrieved */
3625proto_item*
3626ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3627{
3628 header_field_info *hfinfo;
3629 field_info *new_fi;
3630 const uint8_t *value;
3631 unsigned item_length;
3632 unsigned offset;
3633
3634 offset = ptvc->offset;
3635
3636 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", 3636
, __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", 3636, "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", 3636, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3637
3638 switch (hfinfo->type) {
3639 case FT_STRING:
3640 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3641 break;
3642 case FT_STRINGZ:
3643 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3644 break;
3645 case FT_UINT_STRING:
3646 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3647 break;
3648 case FT_STRINGZPAD:
3649 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3650 break;
3651 case FT_STRINGZTRUNC:
3652 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3653 break;
3654 default:
3655 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)
3656 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)
;
3657 }
3658
3659 if (retval)
3660 *retval = value;
3661
3662 ptvcursor_advance(ptvc, item_length);
3663
3664 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3665
3666 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", 3666, __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", 3666,
"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", 3666, "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", 3666
, __func__, "Adding %s would put more than %d 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); } } }
;
3667
3668 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3669
3670 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3671 offset, length, encoding);
3672}
3673
3674/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3675 * and returns proto_item* and boolean value retrieved */
3676proto_item*
3677ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3678{
3679 header_field_info *hfinfo;
3680 field_info *new_fi;
3681 unsigned item_length;
3682 unsigned offset;
3683 uint64_t value, bitval;
3684
3685 offset = ptvc->offset;
3686 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", 3686, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3686,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3686, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3687
3688 if (hfinfo->type != FT_BOOLEAN) {
3689 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)
3690 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3691 }
3692
3693 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3694 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3695 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3696 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3697 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3698 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3699 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3700
3701 if (encoding & ENC_STRING0x07000000) {
3702 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3703 }
3704
3705 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3706 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3707
3708 /* I believe it's ok if this is called with a NULL tree */
3709 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3710
3711 if (retval) {
3712 bitval = value;
3713 if (hfinfo->bitmask) {
3714 /* Mask out irrelevant portions */
3715 bitval &= hfinfo->bitmask;
3716 }
3717 *retval = (bitval != 0);
3718 }
3719
3720 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3721
3722 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3723
3724 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", 3724, __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", 3724,
"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", 3724, "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", 3724
, __func__, "Adding %s would put more than %d 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); } } }
;
3725
3726 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3727
3728 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3729 offset, length, encoding);
3730}
3731
3732proto_item *
3733proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3734 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3735{
3736 header_field_info *hfinfo;
3737 field_info *new_fi;
3738 uint64_t value;
3739
3740 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", 3740, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3740,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3740, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3741
3742 switch (hfinfo->type) {
3743 case FT_UINT40:
3744 case FT_UINT48:
3745 case FT_UINT56:
3746 case FT_UINT64:
3747 break;
3748 default:
3749 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)
3750 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3751 }
3752
3753 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3754 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3755 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3756 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3757 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3758 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3759 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3760
3761 if (encoding & ENC_STRING0x07000000) {
3762 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3763 }
3764 /* I believe it's ok if this is called with a NULL tree */
3765 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3766 tvb_get_varint(tvb, start, length, &value, encoding);
3767 } else {
3768 value = get_uint64_value(tree, tvb, start, length, encoding);
3769 }
3770
3771 if (retval) {
3772 *retval = value;
3773 if (hfinfo->bitmask) {
3774 /* Mask out irrelevant portions */
3775 *retval &= hfinfo->bitmask;
3776 /* Shift bits */
3777 *retval >>= hfinfo_bitshift(hfinfo);
3778 }
3779 }
3780
3781 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3782
3783 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", 3783
, __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", 3783, "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", 3783, "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", 3783, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3784
3785 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3786
3787 proto_tree_set_uint64(new_fi, value);
3788
3789 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3790 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3791 new_fi->flags |= FI_VARINT0x00040000;
3792 }
3793
3794 return proto_tree_add_node(tree, new_fi);
3795}
3796
3797proto_item *
3798proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3799 const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3800{
3801 header_field_info *hfinfo;
3802 field_info *new_fi;
3803 int64_t value;
3804
3805 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", 3805, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3805,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3805, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3806
3807 switch (hfinfo->type) {
3808 case FT_INT40:
3809 case FT_INT48:
3810 case FT_INT56:
3811 case FT_INT64:
3812 break;
3813 default:
3814 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)
3815 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3816 }
3817
3818 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3819 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3820 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3821 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3822 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3823 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3824 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3825
3826 if (encoding & ENC_STRING0x07000000) {
3827 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3828 }
3829 /* I believe it's ok if this is called with a NULL tree */
3830 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3831 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3832 }
3833 else {
3834 value = get_int64_value(tree, tvb, start, length, encoding);
3835 }
3836
3837 if (retval) {
3838 *retval = value;
3839 }
3840
3841 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3842
3843 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", 3843
, __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", 3843, "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", 3843, "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", 3843, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3844
3845 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3846
3847 proto_tree_set_int64(new_fi, value);
3848
3849 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3850 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3851 new_fi->flags |= FI_VARINT0x00040000;
3852 }
3853
3854 return proto_tree_add_node(tree, new_fi);
3855}
3856
3857proto_item *
3858proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3859 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3860{
3861 header_field_info *hfinfo;
3862 field_info *new_fi;
3863 uint64_t value;
3864
3865 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", 3865, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3865,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3865, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3866
3867 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
))
)) {
3868 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)
3869 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3870 }
3871
3872 if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3873 REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3874 }
3875
3876 if (encoding & ENC_STRING0x07000000) {
3877 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3878 }
3879
3880 /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3881 * It also handles length 0, setting both return values to 0.
3882 * XXX - Should the max length be affected by the field type and/or
3883 * encoding, e.g. 5 for FT_[U]INT32?
3884 * XXX - Should there be separate _varint and _varuint versions to
3885 * avoid the changing the sign when casting the return value?
3886 * XXX - Do we even need the length parameter? Every user of this
3887 * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3888 * separate function, but unlike some field types, variable length
3889 * is the typical case here, not the exception, and the typical
3890 * case should have the shorter, more convenient function name.
3891 * Having the length makes the signature more similar to other
3892 * functions, though. */
3893 length = tvb_get_varint(tvb, start, length, &value, encoding);
3894
3895 if (length == 0) {
3896 expert_add_info(NULL((void*)0), tree, &ei_varint_decoding_failed_error);
3897 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3898 }
3899
3900 if (retval) {
3901 *retval = value;
3902 if (hfinfo->bitmask) {
3903 /* Mask out irrelevant portions */
3904 *retval &= hfinfo->bitmask;
3905 /* Shift bits */
3906 *retval >>= hfinfo_bitshift(hfinfo);
3907 }
3908 }
3909
3910 if (lenretval) {
3911 *lenretval = length;
3912 }
3913
3914 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3915
3916 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", 3916
, __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", 3916, "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", 3916, "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", 3916, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3917
3918 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3919
3920 proto_tree_set_uint64(new_fi, value);
3921
3922 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3923 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3924 new_fi->flags |= FI_VARINT0x00040000;
3925 }
3926
3927 return proto_tree_add_node(tree, new_fi);
3928
3929}
3930
3931proto_item *
3932proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3933 const unsigned start, unsigned length,
3934 const unsigned encoding, bool_Bool *retval)
3935{
3936 header_field_info *hfinfo;
3937 field_info *new_fi;
3938 uint64_t value, bitval;
3939
3940 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", 3940, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3940,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3940, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3941
3942 if (hfinfo->type != FT_BOOLEAN) {
3943 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)
3944 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3945 }
3946
3947 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3948 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3949 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3950 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3951 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3952 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3953 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3954
3955 if (encoding & ENC_STRING0x07000000) {
3956 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3957 }
3958 /* I believe it's ok if this is called with a NULL tree */
3959 value = get_uint64_value(tree, tvb, start, length, encoding);
3960
3961 if (retval) {
3962 bitval = value;
3963 if (hfinfo->bitmask) {
3964 /* Mask out irrelevant portions */
3965 bitval &= hfinfo->bitmask;
3966 }
3967 *retval = (bitval != 0);
3968 }
3969
3970 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3971
3972 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", 3972
, __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", 3972, "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", 3972, "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", 3972, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3973
3974 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3975
3976 proto_tree_set_boolean(new_fi, value);
3977
3978 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3979
3980 return proto_tree_add_node(tree, new_fi);
3981}
3982
3983proto_item *
3984proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3985 const unsigned start, unsigned length,
3986 const unsigned encoding, float *retval)
3987{
3988 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3989 field_info *new_fi;
3990 float value;
3991
3992 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", 3992,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3993
3994 if (hfinfo->type != FT_FLOAT) {
3995 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)
;
3996 }
3997
3998 if (length != 4) {
3999 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
4000 }
4001
4002 /* treat any nonzero encoding as little endian for backwards compatibility */
4003 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
4004 if (retval) {
4005 *retval = value;
4006 }
4007
4008 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4009
4010 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", 4010
, __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", 4010, "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", 4010, "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", 4010, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4011
4012 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4013 if (encoding) {
4014 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4015 }
4016
4017 proto_tree_set_float(new_fi, value);
4018
4019 return proto_tree_add_node(tree, new_fi);
4020}
4021
4022proto_item *
4023proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4024 const unsigned start, unsigned length,
4025 const unsigned encoding, double *retval)
4026{
4027 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4028 field_info *new_fi;
4029 double value;
4030
4031 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", 4031,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4032
4033 if (hfinfo->type != FT_DOUBLE) {
4034 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)
;
4035 }
4036
4037 if (length != 8) {
4038 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4039 }
4040
4041 /* treat any nonzero encoding as little endian for backwards compatibility */
4042 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4043 if (retval) {
4044 *retval = value;
4045 }
4046
4047 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4048
4049 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", 4049
, __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", 4049, "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", 4049, "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", 4049, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4050
4051 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4052 if (encoding) {
4053 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4054 }
4055
4056 proto_tree_set_double(new_fi, value);
4057
4058 return proto_tree_add_node(tree, new_fi);
4059}
4060
4061proto_item *
4062proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4063 const unsigned start, unsigned length,
4064 const unsigned encoding, ws_in4_addr *retval)
4065{
4066 header_field_info *hfinfo;
4067 field_info *new_fi;
4068 ws_in4_addr value;
4069
4070 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", 4070, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4070,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4070, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4071
4072 switch (hfinfo->type) {
4073 case FT_IPv4:
4074 break;
4075 default:
4076 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)
4077 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4078 }
4079
4080 if (length != FT_IPv4_LEN4)
4081 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)
4082 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4083
4084 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4085 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4086 }
4087
4088 /*
4089 * NOTE: to support code written when proto_tree_add_item() took
4090 * a bool as its last argument, with false meaning "big-endian"
4091 * and true meaning "little-endian", we treat any non-zero value
4092 * of "encoding" as meaning "little-endian".
4093 */
4094 value = tvb_get_ipv4(tvb, start);
4095 if (encoding)
4096 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))))
;
4097
4098 if (retval) {
4099 *retval = value;
4100 }
4101
4102 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4103
4104 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", 4104
, __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", 4104, "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", 4104, "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", 4104, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4105
4106 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4107
4108 proto_tree_set_ipv4(new_fi, value);
4109
4110 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4111 return proto_tree_add_node(tree, new_fi);
4112}
4113
4114proto_item *
4115proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4116 const unsigned start, unsigned length,
4117 const unsigned encoding, ws_in6_addr *addr)
4118{
4119 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4120 field_info *new_fi;
4121
4122 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", 4122,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4123
4124 switch (hfinfo->type) {
4125 case FT_IPv6:
4126 break;
4127 default:
4128 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)
4129 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4130 }
4131
4132 if (length != FT_IPv6_LEN16)
4133 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)
4134 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4135
4136 if (encoding) {
4137 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"
)
;
4138 }
4139
4140 tvb_get_ipv6(tvb, start, addr);
4141
4142 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4143
4144 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", 4144
, __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", 4144, "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", 4144, "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", 4144, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4145
4146 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4147
4148 proto_tree_set_ipv6(new_fi, addr);
4149
4150 return proto_tree_add_node(tree, new_fi);
4151}
4152
4153proto_item *
4154proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4155 const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4156
4157 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4158 field_info *new_fi;
4159
4160 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", 4160,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4161
4162 switch (hfinfo->type) {
4163 case FT_ETHER:
4164 break;
4165 default:
4166 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)
4167 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4168 }
4169
4170 if (length != FT_ETHER_LEN6)
4171 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)
4172 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4173
4174 if (encoding) {
4175 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"
)
;
4176 }
4177
4178 tvb_memcpy(tvb, retval, start, length);
4179
4180 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4181
4182 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", 4182
, __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", 4182, "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", 4182, "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", 4182, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4183
4184 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4185
4186 proto_tree_set_ether(new_fi, retval);
4187
4188 return proto_tree_add_node(tree, new_fi);
4189}
4190
4191
4192proto_item *
4193proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4194 tvbuff_t *tvb,
4195 const unsigned start, int length,
4196 const unsigned encoding,
4197 wmem_allocator_t *scope,
4198 const uint8_t **retval,
4199 unsigned *lenretval)
4200{
4201 proto_item *pi;
4202 header_field_info *hfinfo;
4203 field_info *new_fi;
4204 const uint8_t *value;
4205
4206 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", 4206, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4206,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4206, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4207
4208 switch (hfinfo->type) {
4209 case FT_STRING:
4210 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4211 break;
4212 case FT_STRINGZ:
4213 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4214 break;
4215 case FT_UINT_STRING:
4216 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4217 break;
4218 case FT_STRINGZPAD:
4219 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4220 break;
4221 case FT_STRINGZTRUNC:
4222 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4223 break;
4224 default:
4225 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)
4226 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)
;
4227 }
4228
4229 if (retval)
4230 *retval = value;
4231
4232 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4233
4234 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", 4234
, __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", 4234, "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", 4234, "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", 4234, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4235
4236 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4237
4238 proto_tree_set_string(new_fi, (const char*)value);
4239
4240 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4241
4242 pi = proto_tree_add_node(tree, new_fi);
4243
4244 switch (hfinfo->type) {
4245
4246 case FT_STRINGZ:
4247 case FT_STRINGZPAD:
4248 case FT_STRINGZTRUNC:
4249 case FT_UINT_STRING:
4250 break;
4251
4252 case FT_STRING:
4253 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4254 break;
4255
4256 default:
4257 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4257
, __func__, "assertion \"not reached\" failed")
;
4258 }
4259
4260 return pi;
4261}
4262
4263proto_item *
4264proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4265 const unsigned start, int length,
4266 const unsigned encoding, wmem_allocator_t *scope,
4267 const uint8_t **retval)
4268{
4269 unsigned item_length; // Param cannot be NULL in function below
4270 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4271 tvb, start, length, encoding, scope, retval, &item_length);
4272}
4273
4274proto_item *
4275proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4276 tvbuff_t *tvb,
4277 const unsigned start, int length,
4278 const unsigned encoding,
4279 wmem_allocator_t *scope,
4280 char **retval,
4281 unsigned *lenretval)
4282{
4283 proto_item *pi;
4284 header_field_info *hfinfo;
4285 field_info *new_fi;
4286 const uint8_t *value;
4287 uint32_t n = 0;
4288
4289 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", 4289, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4289,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4289, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4290
4291 switch (hfinfo->type) {
4292 case FT_STRING:
4293 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4294 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4295 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4296 break;
4297 case FT_STRINGZ:
4298 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4299 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4300 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4301 break;
4302 case FT_UINT_STRING:
4303 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4304 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4305 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4306 break;
4307 case FT_STRINGZPAD:
4308 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4309 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4310 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4311 break;
4312 case FT_STRINGZTRUNC:
4313 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4314 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4315 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4316 break;
4317 case FT_BYTES:
4318 tvb_ensure_bytes_exist(tvb, start, length);
4319 value = tvb_get_ptr(tvb, start, length);
4320 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4321 *lenretval = length;
4322 break;
4323 case FT_UINT_BYTES:
4324 n = get_uint_value(tree, tvb, start, length, encoding);
4325 tvb_ensure_bytes_exist(tvb, start + length, n);
4326 value = tvb_get_ptr(tvb, start + length, n);
4327 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4328 *lenretval = length + n;
4329 break;
4330 default:
4331 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)
4332 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)
;
4333 }
4334
4335 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4336
4337 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", 4337
, __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", 4337, "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", 4337, "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", 4337, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4338
4339 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4340
4341 switch (hfinfo->type) {
4342
4343 case FT_STRING:
4344 case FT_STRINGZ:
4345 case FT_UINT_STRING:
4346 case FT_STRINGZPAD:
4347 case FT_STRINGZTRUNC:
4348 proto_tree_set_string(new_fi, (const char*)value);
4349 break;
4350
4351 case FT_BYTES:
4352 proto_tree_set_bytes(new_fi, value, length);
4353 break;
4354
4355 case FT_UINT_BYTES:
4356 proto_tree_set_bytes(new_fi, value, n);
4357 break;
4358
4359 default:
4360 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4360
, __func__, "assertion \"not reached\" failed")
;
4361 }
4362
4363 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4364
4365 pi = proto_tree_add_node(tree, new_fi);
4366
4367 switch (hfinfo->type) {
4368
4369 case FT_STRINGZ:
4370 case FT_STRINGZPAD:
4371 case FT_STRINGZTRUNC:
4372 case FT_UINT_STRING:
4373 break;
4374
4375 case FT_STRING:
4376 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4377 break;
4378
4379 case FT_BYTES:
4380 case FT_UINT_BYTES:
4381 break;
4382
4383 default:
4384 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4384
, __func__, "assertion \"not reached\" failed")
;
4385 }
4386
4387 return pi;
4388}
4389
4390proto_item *
4391proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4392 tvbuff_t *tvb,
4393 const unsigned start, int length,
4394 const unsigned encoding,
4395 wmem_allocator_t *scope,
4396 char **retval)
4397{
4398 unsigned item_length; // Param cannot be NULL in function below
4399 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4400 tvb, start, length, encoding, scope, retval, &item_length);
4401}
4402
4403proto_item *
4404proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4405 tvbuff_t *tvb,
4406 const unsigned start, int length, const unsigned encoding,
4407 wmem_allocator_t *scope, char **retval)
4408{
4409 header_field_info *hfinfo;
4410 field_info *new_fi;
4411 nstime_t time_stamp;
4412 int flags;
4413
4414 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", 4414, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4414,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4414, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4415
4416 switch (hfinfo->type) {
4417 case FT_ABSOLUTE_TIME:
4418 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4419 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4420 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4421 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4422 }
4423 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4424 break;
4425 case FT_RELATIVE_TIME:
4426 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4427 *retval = rel_time_to_secs_str(scope, &time_stamp);
4428 break;
4429 default:
4430 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)
4431 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4432 }
4433
4434 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4435
4436 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", 4436
, __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", 4436, "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", 4436, "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", 4436, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4437
4438 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4439
4440 switch (hfinfo->type) {
4441
4442 case FT_ABSOLUTE_TIME:
4443 case FT_RELATIVE_TIME:
4444 proto_tree_set_time(new_fi, &time_stamp);
4445 break;
4446 default:
4447 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4447
, __func__, "assertion \"not reached\" failed")
;
4448 }
4449
4450 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4451
4452 return proto_tree_add_node(tree, new_fi);
4453}
4454
4455/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4456 and returns proto_item* */
4457proto_item *
4458ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4459 const unsigned encoding)
4460{
4461 field_info *new_fi;
4462 header_field_info *hfinfo;
4463 int item_length;
4464 unsigned offset;
4465
4466 offset = ptvc->offset;
4467 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", 4467, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4467,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4467, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4468 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4469 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4470
4471 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4472
4473 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4474
4475 /* Coast clear. Try and fake it */
4476 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", 4476
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4476, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4476, "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", 4476, __func__, "Adding %s would put more than %d 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); } } }
;
4477
4478 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4479
4480 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4481 offset, length, encoding);
4482}
4483
4484/* Add an item to a proto_tree, using the text label registered to that item;
4485 the item is extracted from the tvbuff handed to it. */
4486proto_item *
4487proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4488 const unsigned start, int length, const unsigned encoding)
4489{
4490 field_info *new_fi;
4491 int item_length;
4492
4493 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", 4493,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4494
4495 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4496 test_length(hfinfo, tvb, start, item_length, encoding);
4497
4498 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4499
4500 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", 4500
, __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", 4500, "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", 4500, "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", 4500, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4501
4502 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4503
4504 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4505}
4506
4507proto_item *
4508proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4509 const unsigned start, int length, const unsigned encoding)
4510{
4511 register header_field_info *hfinfo;
4512
4513 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", 4513, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4513,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4513, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4514 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4515}
4516
4517/* Add an item to a proto_tree, using the text label registered to that item;
4518 the item is extracted from the tvbuff handed to it.
4519
4520 Return the length of the item through the pointer. */
4521proto_item *
4522proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4523 tvbuff_t *tvb, const unsigned start,
4524 int length, const unsigned encoding,
4525 unsigned *lenretval)
4526{
4527 field_info *new_fi;
4528 int item_length;
4529 proto_item *item;
4530
4531 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", 4531,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4532
4533 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4534 test_length(hfinfo, tvb, start, item_length, encoding);
4535
4536 if (!tree) {
4537 /*
4538 * We need to get the correct item length here.
4539 * That's normally done by proto_tree_new_item(),
4540 * but we won't be calling it.
4541 */
4542 *lenretval = get_full_length(hfinfo, tvb, start, length,
4543 item_length, encoding);
4544 return NULL((void*)0);
4545 }
4546
4547 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", 4554
, __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", 4554, "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", 4554, "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", 4554
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4548 /*((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", 4554
, __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", 4554, "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", 4554, "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", 4554
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4549 * 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", 4554
, __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", 4554, "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", 4554, "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", 4554
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4550 * 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", 4554
, __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", 4554, "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", 4554, "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", 4554
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4551 */((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", 4554
, __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", 4554, "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", 4554, "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", 4554
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4552 *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", 4554
, __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", 4554, "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", 4554, "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", 4554
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4553 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", 4554
, __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", 4554, "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", 4554, "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", 4554
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4554 })((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", 4554
, __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", 4554, "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", 4554, "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", 4554
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4555
4556 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4557
4558 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4559 *lenretval = new_fi->length;
4560 return item;
4561}
4562
4563proto_item *
4564proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4565 const unsigned start, int length,
4566 const unsigned encoding, unsigned *lenretval)
4567{
4568 register header_field_info *hfinfo;
4569
4570 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", 4570, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4570,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4570, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4571 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4572}
4573
4574/* which FT_ types can use proto_tree_add_bytes_item() */
4575static inline bool_Bool
4576validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4577{
4578 return (type == FT_BYTES ||
4579 type == FT_UINT_BYTES ||
4580 type == FT_OID ||
4581 type == FT_REL_OID ||
4582 type == FT_SYSTEM_ID );
4583}
4584
4585/* Note: this does no validation that the byte array of an FT_OID or
4586 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4587 so I think it's ok to continue not validating it?
4588 */
4589proto_item *
4590proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4591 const unsigned start, unsigned length,
4592 const unsigned encoding,
4593 GByteArray *retval, unsigned *endoff, int *err)
4594{
4595 field_info *new_fi;
4596 GByteArray *bytes = retval;
4597 GByteArray *created_bytes = NULL((void*)0);
4598 bool_Bool failed = false0;
4599 uint32_t n = 0;
4600 header_field_info *hfinfo;
4601 bool_Bool generate = (bytes || tree) ? true1 : false0;
4602
4603 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", 4603, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4603,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4603, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4604
4605 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", 4605,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4606
4607 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", 4608, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4608 "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", 4608, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4609
4610 if (length == 0) {
4611 return NULL((void*)0);
4612 }
4613
4614 if (encoding & ENC_STR_NUM0x01000000) {
4615 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"
)
;
4616 }
4617
4618 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4619 if (hfinfo->type == FT_UINT_BYTES) {
4620 /* can't decode FT_UINT_BYTES from strings */
4621 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")
4622 "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")
;
4623 }
4624
4625 unsigned hex_encoding = encoding;
4626 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4627 /* If none of the separator values are used,
4628 * assume no separator (the common case). */
4629 hex_encoding |= ENC_SEP_NONE0x00010000;
4630#if 0
4631 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")
4632 "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")
;
4633#endif
4634 }
4635
4636 if (!bytes) {
4637 /* caller doesn't care about return value, but we need it to
4638 call tvb_get_string_bytes() and set the tree later */
4639 bytes = created_bytes = g_byte_array_new();
4640 }
4641
4642 /*
4643 * bytes might be NULL after this, but can't add expert
4644 * error until later; if it's NULL, just note that
4645 * it failed.
4646 */
4647 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4648 if (bytes == NULL((void*)0))
4649 failed = true1;
4650 }
4651 else if (generate) {
4652 tvb_ensure_bytes_exist(tvb, start, length);
4653
4654 if (hfinfo->type == FT_UINT_BYTES) {
4655 n = length; /* n is now the "header" length */
4656 length = get_uint_value(tree, tvb, start, n, encoding);
4657 /* length is now the value's length; only store the value in the array */
4658 tvb_ensure_bytes_exist(tvb, start + n, length);
4659 if (!bytes) {
4660 /* caller doesn't care about return value, but
4661 * we may need it to set the tree later */
4662 bytes = created_bytes = g_byte_array_new();
4663 }
4664 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4665 }
4666 else if (length > 0) {
4667 if (!bytes) {
4668 /* caller doesn't care about return value, but
4669 * we may need it to set the tree later */
4670 bytes = created_bytes = g_byte_array_new();
4671 }
4672 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4673 }
4674
4675 if (endoff)
4676 *endoff = start + n + length;
4677 }
4678
4679 if (err)
4680 *err = failed ? EINVAL22 : 0;
4681
4682 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); }
4683 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4684 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); }
4685 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); }
4686 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); }
4687 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4688 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4689
4690 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", 4696
, __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", 4696, "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", 4696, "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", 4696
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4691 {((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", 4696
, __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", 4696, "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", 4696, "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", 4696
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4692 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", 4696
, __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", 4696, "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", 4696, "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", 4696
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4693 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", 4696
, __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", 4696, "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", 4696, "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", 4696
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4694 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", 4696
, __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", 4696, "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", 4696, "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", 4696
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4695 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", 4696
, __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", 4696, "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", 4696, "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", 4696
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4696 } )((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", 4696
, __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", 4696, "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", 4696, "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", 4696
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4697
4698 /* n will be zero except when it's a FT_UINT_BYTES */
4699 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4700
4701 if (encoding & ENC_STRING0x07000000) {
4702 if (failed)
4703 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4704
4705 if (bytes)
4706 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4707 else
4708 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4709
4710 if (created_bytes)
4711 g_byte_array_free(created_bytes, true1);
4712 }
4713 else {
4714 /* n will be zero except when it's a FT_UINT_BYTES */
4715 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4716
4717 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4718 * use the byte array created above in this case.
4719 */
4720 if (created_bytes)
4721 g_byte_array_free(created_bytes, true1);
4722
4723 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4724 (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)
;
4725 }
4726
4727 return proto_tree_add_node(tree, new_fi);
4728}
4729
4730
4731proto_item *
4732proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4733 const unsigned start, const unsigned length,
4734 const unsigned encoding,
4735 nstime_t *retval, unsigned *endoff, int *err)
4736{
4737 field_info *new_fi;
4738 nstime_t time_stamp;
4739 int saved_err = 0;
4740 header_field_info *hfinfo;
4741
4742 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", 4742, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4742,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4742, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4743
4744 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", 4744,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4745
4746 if (length == 0) {
4747 if(retval) {
4748 nstime_set_zero(retval);
4749 }
4750 return NULL((void*)0);
4751 }
4752
4753 nstime_set_zero(&time_stamp);
4754
4755 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4756 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", 4756, ((hfinfo))->abbrev))))
;
4757 /* The only string format that could be a relative time is
4758 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4759 * relative to "now" currently.
4760 */
4761 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4762 saved_err = EINVAL22;
4763 }
4764 else {
4765 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", 4765, ((hfinfo))->abbrev))))
;
4766 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4767
4768 tvb_ensure_bytes_exist(tvb, start, length);
4769 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4770 if (endoff) *endoff = start + length;
4771 }
4772
4773 if (err) *err = saved_err;
4774
4775 if (retval) {
4776 retval->secs = time_stamp.secs;
4777 retval->nsecs = time_stamp.nsecs;
4778 }
4779
4780 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4781
4782 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", 4782
, __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", 4782, "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", 4782, "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", 4782, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4783
4784 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4785
4786 proto_tree_set_time(new_fi, &time_stamp);
4787
4788 if (encoding & ENC_STRING0x07000000) {
4789 if (saved_err)
4790 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4791 }
4792 else {
4793 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4794 (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)
;
4795 }
4796
4797 return proto_tree_add_node(tree, new_fi);
4798}
4799
4800/* Add a FT_NONE to a proto_tree */
4801proto_item *
4802proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4803 const unsigned start, int length, const char *format,
4804 ...)
4805{
4806 proto_item *pi;
4807 va_list ap;
4808 header_field_info *hfinfo;
4809
4810 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4811
4812 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", 4812
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4812, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4812, "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", 4812, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4813
4814 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", 4814
, ((hfinfo))->abbrev))))
;
4815
4816 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4817
4818 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4818, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4819
4820 va_start(ap, format)__builtin_va_start(ap, format);
4821 proto_tree_set_representation(pi, format, ap);
4822 va_end(ap)__builtin_va_end(ap);
4823
4824 /* no value to set for FT_NONE */
4825 return pi;
4826}
4827
4828/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4829 * offset, and returns proto_item* */
4830proto_item *
4831ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4832 const unsigned encoding)
4833{
4834 proto_item *item;
4835
4836 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4837 length, encoding);
4838
4839 return item;
4840}
4841
4842/* Advance the ptvcursor's offset within its tvbuff without
4843 * adding anything to the proto_tree. */
4844void
4845ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4846{
4847 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4848 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4849 }
4850}
4851
4852
4853static void
4854proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4855{
4856 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4856, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4857 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4858}
4859
4860/* Add a FT_PROTOCOL to a proto_tree */
4861proto_item *
4862proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4863 unsigned start, int length, const char *format, ...)
4864{
4865 proto_item *pi;
4866 field_info *new_fi;
4867 tvbuff_t *protocol_tvb;
4868 va_list ap;
4869 header_field_info *hfinfo;
4870 char* protocol_rep;
4871
4872 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4873
4874 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", 4874
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4874, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4874, "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", 4874, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4875
4876 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"
, 4876, ((hfinfo))->abbrev))))
;
4877
4878 /*
4879 * This can throw an exception when it calls get_hfi_length before
4880 * it allocates anything, if length is nonzero and start is past
4881 * the end of the tvb. Afterwards it can't throw an exception,
4882 * as length is clamped to the captured length remaining.
4883 */
4884 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4885 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4886 /* Start the protocol_tvb at the correct start offset, but allow it
4887 * to be lengthened later via finfo_set_len. */
4888 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4889
4890 va_start(ap, format)__builtin_va_start(ap, format);
4891 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4892 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4893 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)
;
4894 va_end(ap)__builtin_va_end(ap);
4895
4896 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4896, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4897
4898 va_start(ap, format)__builtin_va_start(ap, format);
4899 proto_tree_set_representation(pi, format, ap);
4900 va_end(ap)__builtin_va_end(ap);
4901
4902 return pi;
4903}
4904
4905/* Add a FT_BYTES to a proto_tree */
4906proto_item *
4907proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4908 int length, const uint8_t *start_ptr)
4909{
4910 proto_item *pi;
4911 header_field_info *hfinfo;
4912 int item_length;
4913
4914 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", 4914, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4914,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4914, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4915 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4916 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4917
4918 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4919
4920 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", 4920
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4920, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4920, "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", 4920, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4921
4922 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",
4922, ((hfinfo))->abbrev))))
;
4923
4924 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4925 start_ptr = tvb_get_ptr(tvb, start, length);
4926
4927 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4928 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4929
4930 return pi;
4931}
4932
4933/* Add a FT_BYTES to a proto_tree */
4934proto_item *
4935proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4936 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4937{
4938 proto_item *pi;
4939 header_field_info *hfinfo;
4940 int item_length;
4941
4942 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", 4942, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4942,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4942, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4943 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4944 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4945
4946 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4947
4948 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", 4948
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4948, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4948, "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", 4948, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4949
4950 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",
4950, ((hfinfo))->abbrev))))
;
4951
4952 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4953 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4954
4955 return pi;
4956}
4957
4958proto_item *
4959proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4960 unsigned start, int length,
4961 const uint8_t *start_ptr,
4962 const char *format, ...)
4963{
4964 proto_item *pi;
4965 va_list ap;
4966
4967 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4968
4969 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; }
;
4970
4971 va_start(ap, format)__builtin_va_start(ap, format);
4972 proto_tree_set_representation_value(pi, format, ap);
4973 va_end(ap)__builtin_va_end(ap);
4974
4975 return pi;
4976}
4977
4978proto_item *
4979proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4980 unsigned start, int length, const uint8_t *start_ptr,
4981 const char *format, ...)
4982{
4983 proto_item *pi;
4984 va_list ap;
4985
4986 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4987
4988 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; }
;
4989
4990 va_start(ap, format)__builtin_va_start(ap, format);
4991 proto_tree_set_representation(pi, format, ap);
4992 va_end(ap)__builtin_va_end(ap);
4993
4994 return pi;
4995}
4996
4997static void
4998proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4999{
5000 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5000, "length >= 0"
))))
;
5001 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", 5001, "start_ptr != ((void*)0) || length == 0"
))))
;
5002
5003 fvalue_set_bytes_data(fi->value, start_ptr, length);
5004}
5005
5006
5007static void
5008proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5009{
5010 tvb_ensure_bytes_exist(tvb, offset, length);
5011 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5012}
5013
5014static void
5015proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5016{
5017 GByteArray *bytes;
5018
5019 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5019, "value != ((void*)0)"
))))
;
5020
5021 bytes = byte_array_dup(value);
5022
5023 fvalue_set_byte_array(fi->value, bytes);
5024}
5025
5026/* Add a FT_*TIME to a proto_tree */
5027proto_item *
5028proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5029 unsigned length, const nstime_t *value_ptr)
5030{
5031 proto_item *pi;
5032 header_field_info *hfinfo;
5033
5034 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5035
5036 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", 5036
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5036, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5036, "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", 5036, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5037
5038 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", 5038, ((hfinfo))->abbrev))))
;
5039
5040 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5041 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5042
5043 return pi;
5044}
5045
5046proto_item *
5047proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5048 unsigned start, unsigned length, nstime_t *value_ptr,
5049 const char *format, ...)
5050{
5051 proto_item *pi;
5052 va_list ap;
5053
5054 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5055 if (pi != tree) {
5056 va_start(ap, format)__builtin_va_start(ap, format);
5057 proto_tree_set_representation_value(pi, format, ap);
5058 va_end(ap)__builtin_va_end(ap);
5059 }
5060
5061 return pi;
5062}
5063
5064proto_item *
5065proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5066 unsigned start, unsigned length, nstime_t *value_ptr,
5067 const char *format, ...)
5068{
5069 proto_item *pi;
5070 va_list ap;
5071
5072 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5073 if (pi != tree) {
5074 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5074, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5075
5076 va_start(ap, format)__builtin_va_start(ap, format);
5077 proto_tree_set_representation(pi, format, ap);
5078 va_end(ap)__builtin_va_end(ap);
5079 }
5080
5081 return pi;
5082}
5083
5084/* Set the FT_*TIME value */
5085static void
5086proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5087{
5088 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5088, "value_ptr != ((void*)0)"
))))
;
5089
5090 fvalue_set_time(fi->value, value_ptr);
5091}
5092
5093/* Add a FT_IPXNET to a proto_tree */
5094proto_item *
5095proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5096 unsigned length, uint32_t value)
5097{
5098 proto_item *pi;
5099 header_field_info *hfinfo;
5100
5101 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5102
5103 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", 5103
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5103, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5103, "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", 5103, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5104
5105 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"
, 5105, ((hfinfo))->abbrev))))
;
5106
5107 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5108 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5109
5110 return pi;
5111}
5112
5113proto_item *
5114proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5115 unsigned start, unsigned length, uint32_t value,
5116 const char *format, ...)
5117{
5118 proto_item *pi;
5119 va_list ap;
5120
5121 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5122 if (pi != tree) {
5123 va_start(ap, format)__builtin_va_start(ap, format);
5124 proto_tree_set_representation_value(pi, format, ap);
5125 va_end(ap)__builtin_va_end(ap);
5126 }
5127
5128 return pi;
5129}
5130
5131proto_item *
5132proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5133 unsigned start, unsigned length, uint32_t value,
5134 const char *format, ...)
5135{
5136 proto_item *pi;
5137 va_list ap;
5138
5139 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5140 if (pi != tree) {
5141 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5141, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5142
5143 va_start(ap, format)__builtin_va_start(ap, format);
5144 proto_tree_set_representation(pi, format, ap);
5145 va_end(ap)__builtin_va_end(ap);
5146 }
5147
5148 return pi;
5149}
5150
5151/* Set the FT_IPXNET value */
5152static void
5153proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5154{
5155 fvalue_set_uinteger(fi->value, value);
5156}
5157
5158/* Add a FT_IPv4 to a proto_tree */
5159proto_item *
5160proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5161 unsigned length, ws_in4_addr value)
5162{
5163 proto_item *pi;
5164 header_field_info *hfinfo;
5165
5166 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5167
5168 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", 5168
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5168, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5168, "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", 5168, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5169
5170 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", 5170
, ((hfinfo))->abbrev))))
;
5171
5172 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5173 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5174
5175 return pi;
5176}
5177
5178proto_item *
5179proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5180 unsigned start, unsigned length, ws_in4_addr value,
5181 const char *format, ...)
5182{
5183 proto_item *pi;
5184 va_list ap;
5185
5186 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5187 if (pi != tree) {
5188 va_start(ap, format)__builtin_va_start(ap, format);
5189 proto_tree_set_representation_value(pi, format, ap);
5190 va_end(ap)__builtin_va_end(ap);
5191 }
5192
5193 return pi;
5194}
5195
5196proto_item *
5197proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5198 unsigned start, unsigned length, ws_in4_addr value,
5199 const char *format, ...)
5200{
5201 proto_item *pi;
5202 va_list ap;
5203
5204 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5205 if (pi != tree) {
5206 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5206, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5207
5208 va_start(ap, format)__builtin_va_start(ap, format);
5209 proto_tree_set_representation(pi, format, ap);
5210 va_end(ap)__builtin_va_end(ap);
5211 }
5212
5213 return pi;
5214}
5215
5216/* Set the FT_IPv4 value */
5217static void
5218proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5219{
5220 ipv4_addr_and_mask ipv4;
5221 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5222 fvalue_set_ipv4(fi->value, &ipv4);
5223}
5224
5225/* Add a FT_IPv6 to a proto_tree */
5226proto_item *
5227proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5228 unsigned length, const ws_in6_addr *value)
5229{
5230 proto_item *pi;
5231 header_field_info *hfinfo;
5232
5233 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5234
5235 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", 5235
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5235, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5235, "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", 5235, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5236
5237 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", 5237
, ((hfinfo))->abbrev))))
;
5238
5239 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5240 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5241
5242 return pi;
5243}
5244
5245proto_item *
5246proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5247 unsigned start, unsigned length,
5248 const ws_in6_addr *value_ptr,
5249 const char *format, ...)
5250{
5251 proto_item *pi;
5252 va_list ap;
5253
5254 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5255 if (pi != tree) {
5256 va_start(ap, format)__builtin_va_start(ap, format);
5257 proto_tree_set_representation_value(pi, format, ap);
5258 va_end(ap)__builtin_va_end(ap);
5259 }
5260
5261 return pi;
5262}
5263
5264proto_item *
5265proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5266 unsigned start, unsigned length,
5267 const ws_in6_addr *value_ptr,
5268 const char *format, ...)
5269{
5270 proto_item *pi;
5271 va_list ap;
5272
5273 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5274 if (pi != tree) {
5275 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5275, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5276
5277 va_start(ap, format)__builtin_va_start(ap, format);
5278 proto_tree_set_representation(pi, format, ap);
5279 va_end(ap)__builtin_va_end(ap);
5280 }
5281
5282 return pi;
5283}
5284
5285/* Set the FT_IPv6 value */
5286static void
5287proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5288{
5289 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5289, "value != ((void*)0)"
))))
;
5290 ipv6_addr_and_prefix ipv6;
5291 ipv6.addr = *value;
5292 ipv6.prefix = 128;
5293 fvalue_set_ipv6(fi->value, &ipv6);
5294}
5295
5296static void
5297proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5298{
5299 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5300}
5301
5302/* Set the FT_FCWWN value */
5303static void
5304proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5305{
5306 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5306, "value_ptr != ((void*)0)"
))))
;
5307 fvalue_set_fcwwn(fi->value, value_ptr);
5308}
5309
5310static void
5311proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5312{
5313 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5314}
5315
5316/* Add a FT_GUID to a proto_tree */
5317proto_item *
5318proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5319 unsigned length, const e_guid_t *value_ptr)
5320{
5321 proto_item *pi;
5322 header_field_info *hfinfo;
5323
5324 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5325
5326 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", 5326
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5326, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5326, "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", 5326, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5327
5328 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", 5328
, ((hfinfo))->abbrev))))
;
5329
5330 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5331 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5332
5333 return pi;
5334}
5335
5336proto_item *
5337proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5338 unsigned start, unsigned length,
5339 const e_guid_t *value_ptr,
5340 const char *format, ...)
5341{
5342 proto_item *pi;
5343 va_list ap;
5344
5345 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5346 if (pi != tree) {
5347 va_start(ap, format)__builtin_va_start(ap, format);
5348 proto_tree_set_representation_value(pi, format, ap);
5349 va_end(ap)__builtin_va_end(ap);
5350 }
5351
5352 return pi;
5353}
5354
5355proto_item *
5356proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5357 unsigned start, unsigned length, const e_guid_t *value_ptr,
5358 const char *format, ...)
5359{
5360 proto_item *pi;
5361 va_list ap;
5362
5363 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5364 if (pi != tree) {
5365 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5365, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5366
5367 va_start(ap, format)__builtin_va_start(ap, format);
5368 proto_tree_set_representation(pi, format, ap);
5369 va_end(ap)__builtin_va_end(ap);
5370 }
5371
5372 return pi;
5373}
5374
5375/* Set the FT_GUID value */
5376static void
5377proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5378{
5379 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5379, "value_ptr != ((void*)0)"
))))
;
5380 fvalue_set_guid(fi->value, value_ptr);
5381}
5382
5383static void
5384proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5385 const unsigned encoding)
5386{
5387 e_guid_t guid;
5388
5389 tvb_get_guid(tvb, start, &guid, encoding);
5390 proto_tree_set_guid(fi, &guid);
5391}
5392
5393/* Add a FT_OID to a proto_tree */
5394proto_item *
5395proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5396 unsigned length, const uint8_t* value_ptr)
5397{
5398 proto_item *pi;
5399 header_field_info *hfinfo;
5400
5401 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5402
5403 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", 5403
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5403, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5403, "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", 5403, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5404
5405 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", 5405
, ((hfinfo))->abbrev))))
;
5406
5407 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5408 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5409
5410 return pi;
5411}
5412
5413proto_item *
5414proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5415 unsigned start, unsigned length,
5416 const uint8_t* value_ptr,
5417 const char *format, ...)
5418{
5419 proto_item *pi;
5420 va_list ap;
5421
5422 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5423 if (pi != tree) {
5424 va_start(ap, format)__builtin_va_start(ap, format);
5425 proto_tree_set_representation_value(pi, format, ap);
5426 va_end(ap)__builtin_va_end(ap);
5427 }
5428
5429 return pi;
5430}
5431
5432proto_item *
5433proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5434 unsigned start, unsigned length, const uint8_t* value_ptr,
5435 const char *format, ...)
5436{
5437 proto_item *pi;
5438 va_list ap;
5439
5440 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5441 if (pi != tree) {
5442 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5442, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5443
5444 va_start(ap, format)__builtin_va_start(ap, format);
5445 proto_tree_set_representation(pi, format, ap);
5446 va_end(ap)__builtin_va_end(ap);
5447 }
5448
5449 return pi;
5450}
5451
5452/* Set the FT_OID value */
5453static void
5454proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5455{
5456 GByteArray *bytes;
5457
5458 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", 5458, "value_ptr != ((void*)0) || length == 0"
))))
;
5459
5460 bytes = g_byte_array_new();
5461 if (length > 0) {
5462 g_byte_array_append(bytes, value_ptr, length);
5463 }
5464 fvalue_set_byte_array(fi->value, bytes);
5465}
5466
5467static void
5468proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5469{
5470 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5471}
5472
5473/* Set the FT_SYSTEM_ID value */
5474static void
5475proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5476{
5477 GByteArray *bytes;
5478
5479 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", 5479, "value_ptr != ((void*)0) || length == 0"
))))
;
5480
5481 bytes = g_byte_array_new();
5482 if (length > 0) {
5483 g_byte_array_append(bytes, value_ptr, length);
5484 }
5485 fvalue_set_byte_array(fi->value, bytes);
5486}
5487
5488static void
5489proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5490{
5491 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5492}
5493
5494/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5495 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5496 * is destroyed. */
5497proto_item *
5498proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5499 int length, const char* value)
5500{
5501 proto_item *pi;
5502 header_field_info *hfinfo;
5503 int item_length;
5504
5505 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", 5505, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5505,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5505, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5506 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5507 /*
5508 * Special case - if the length is 0, skip the test, so that
5509 * we can have an empty string right after the end of the
5510 * packet. (This handles URL-encoded forms where the last field
5511 * has no value so the form ends right after the =.)
5512 *
5513 * XXX - length zero makes sense for FT_STRING, and more or less
5514 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5515 * for FT_STRINGZ (except that a number of fields that should be
5516 * one of the others are actually registered as FT_STRINGZ.)
5517 */
5518 if (item_length != 0)
5519 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5520
5521 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5522
5523 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", 5523
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5523, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5523, "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", 5523, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5524
5525 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", 5525, ((hfinfo))->abbrev))))
;
5526
5527 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5528 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5528, "length >= 0"
))))
;
5529
5530 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", 5530, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5531 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5532
5533 return pi;
5534}
5535
5536proto_item *
5537proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5538 unsigned start, int length, const char* value,
5539 const char *format,
5540 ...)
5541{
5542 proto_item *pi;
5543 va_list ap;
5544
5545 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5546 if (pi != tree) {
5547 va_start(ap, format)__builtin_va_start(ap, format);
5548 proto_tree_set_representation_value(pi, format, ap);
5549 va_end(ap)__builtin_va_end(ap);
5550 }
5551
5552 return pi;
5553}
5554
5555proto_item *
5556proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5557 unsigned start, int length, const char* value,
5558 const char *format, ...)
5559{
5560 proto_item *pi;
5561 va_list ap;
5562
5563 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5564 if (pi != tree) {
5565 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5565, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5566
5567 va_start(ap, format)__builtin_va_start(ap, format);
5568 proto_tree_set_representation(pi, format, ap);
5569 va_end(ap)__builtin_va_end(ap);
5570 }
5571
5572 return pi;
5573}
5574
5575/* Set the FT_STRING value */
5576static void
5577proto_tree_set_string(field_info *fi, const char* value)
5578{
5579 if (value) {
5580 fvalue_set_string(fi->value, value);
5581 } else {
5582 /*
5583 * XXX - why is a null value for a string field
5584 * considered valid?
5585 */
5586 fvalue_set_string(fi->value, "[ Null ]");
5587 }
5588}
5589
5590/* Set the FT_AX25 value */
5591static void
5592proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5593{
5594 fvalue_set_ax25(fi->value, value);
5595}
5596
5597static void
5598proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5599{
5600 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5601}
5602
5603/* Set the FT_VINES value */
5604static void
5605proto_tree_set_vines(field_info *fi, const uint8_t* value)
5606{
5607 fvalue_set_vines(fi->value, value);
5608}
5609
5610static void
5611proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5612{
5613 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5614}
5615
5616/* Add a FT_ETHER to a proto_tree */
5617proto_item *
5618proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5619 unsigned length, const uint8_t* value)
5620{
5621 proto_item *pi;
5622 header_field_info *hfinfo;
5623
5624 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5625
5626 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", 5626
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5626, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5626, "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", 5626, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5627
5628 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",
5628, ((hfinfo))->abbrev))))
;
5629
5630 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5631 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5632
5633 return pi;
5634}
5635
5636proto_item *
5637proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5638 unsigned start, unsigned length, const uint8_t* value,
5639 const char *format, ...)
5640{
5641 proto_item *pi;
5642 va_list ap;
5643
5644 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5645 if (pi != tree) {
5646 va_start(ap, format)__builtin_va_start(ap, format);
5647 proto_tree_set_representation_value(pi, format, ap);
5648 va_end(ap)__builtin_va_end(ap);
5649 }
5650
5651 return pi;
5652}
5653
5654proto_item *
5655proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5656 unsigned start, unsigned length, const uint8_t* value,
5657 const char *format, ...)
5658{
5659 proto_item *pi;
5660 va_list ap;
5661
5662 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5663 if (pi != tree) {
5664 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5664, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5665
5666 va_start(ap, format)__builtin_va_start(ap, format);
5667 proto_tree_set_representation(pi, format, ap);
5668 va_end(ap)__builtin_va_end(ap);
5669 }
5670
5671 return pi;
5672}
5673
5674/* Set the FT_ETHER value */
5675static void
5676proto_tree_set_ether(field_info *fi, const uint8_t* value)
5677{
5678 fvalue_set_ether(fi->value, value);
5679}
5680
5681static void
5682proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5683{
5684 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5685}
5686
5687/* Add a FT_BOOLEAN to a proto_tree */
5688proto_item *
5689proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5690 unsigned length, uint64_t value)
5691{
5692 proto_item *pi;
5693 header_field_info *hfinfo;
5694
5695 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5696
5697 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", 5697
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5697, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5697, "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", 5697, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5698
5699 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"
, 5699, ((hfinfo))->abbrev))))
;
5700
5701 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5702 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5703
5704 return pi;
5705}
5706
5707proto_item *
5708proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5709 tvbuff_t *tvb, unsigned start, unsigned length,
5710 uint64_t value, const char *format, ...)
5711{
5712 proto_item *pi;
5713 va_list ap;
5714
5715 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5716 if (pi != tree) {
5717 va_start(ap, format)__builtin_va_start(ap, format);
5718 proto_tree_set_representation_value(pi, format, ap);
5719 va_end(ap)__builtin_va_end(ap);
5720 }
5721
5722 return pi;
5723}
5724
5725proto_item *
5726proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5727 unsigned start, unsigned length, uint64_t value,
5728 const char *format, ...)
5729{
5730 proto_item *pi;
5731 va_list ap;
5732
5733 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5734 if (pi != tree) {
5735 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5735, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5736
5737 va_start(ap, format)__builtin_va_start(ap, format);
5738 proto_tree_set_representation(pi, format, ap);
5739 va_end(ap)__builtin_va_end(ap);
5740 }
5741
5742 return pi;
5743}
5744
5745/* Set the FT_BOOLEAN value */
5746static void
5747proto_tree_set_boolean(field_info *fi, uint64_t value)
5748{
5749 proto_tree_set_uint64(fi, value);
5750}
5751
5752/* Generate, into "buf", a string showing the bits of a bitfield.
5753 Return a pointer to the character after that string. */
5754static char *
5755other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5756{
5757 int i = 0;
5758 uint64_t bit;
5759 char *p;
5760
5761 p = buf;
5762
5763 /* This is a devel error. It is safer to stop here. */
5764 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5764, "width >= 1"
))))
;
5765
5766 bit = UINT64_C(1)1UL << (width - 1);
5767 for (;;) {
5768 if (mask & bit) {
5769 /* This bit is part of the field. Show its value. */
5770 if (val & bit)
5771 *p++ = '1';
5772 else
5773 *p++ = '0';
5774 } else {
5775 /* This bit is not part of the field. */
5776 *p++ = '.';
5777 }
5778 bit >>= 1;
5779 i++;
5780 if (i >= width)
5781 break;
5782 if (i % 4 == 0)
5783 *p++ = ' ';
5784 }
5785 *p = '\0';
5786 return p;
5787}
5788
5789static char *
5790decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5791{
5792 char *p;
5793
5794 p = other_decode_bitfield_value(buf, val, mask, width);
5795 p = g_stpcpy(p, " = ");
5796
5797 return p;
5798}
5799
5800static char *
5801other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5802{
5803 int i = 0;
5804 uint64_t bit;
5805 char *p;
5806
5807 p = buf;
5808
5809 /* This is a devel error. It is safer to stop here. */
5810 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5810, "width >= 1"
))))
;
5811
5812 bit = UINT64_C(1)1UL << (width - 1);
5813 for (;;) {
5814 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5815 (mask & bit)) {
5816 /* This bit is part of the field. Show its value. */
5817 if (val & bit)
5818 *p++ = '1';
5819 else
5820 *p++ = '0';
5821 } else {
5822 /* This bit is not part of the field. */
5823 *p++ = '.';
5824 }
5825 bit >>= 1;
5826 i++;
5827 if (i >= width)
5828 break;
5829 if (i % 4 == 0)
5830 *p++ = ' ';
5831 }
5832
5833 *p = '\0';
5834 return p;
5835}
5836
5837static char *
5838decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5839{
5840 char *p;
5841
5842 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5843 p = g_stpcpy(p, " = ");
5844
5845 return p;
5846}
5847
5848/* Add a FT_FLOAT to a proto_tree */
5849proto_item *
5850proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5851 unsigned length, float value)
5852{
5853 proto_item *pi;
5854 header_field_info *hfinfo;
5855
5856 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5857
5858 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", 5858
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5858, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5858, "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", 5858, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5859
5860 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",
5860, ((hfinfo))->abbrev))))
;
5861
5862 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5863 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5864
5865 return pi;
5866}
5867
5868proto_item *
5869proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5870 unsigned start, unsigned length, float value,
5871 const char *format, ...)
5872{
5873 proto_item *pi;
5874 va_list ap;
5875
5876 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5877 if (pi != tree) {
5878 va_start(ap, format)__builtin_va_start(ap, format);
5879 proto_tree_set_representation_value(pi, format, ap);
5880 va_end(ap)__builtin_va_end(ap);
5881 }
5882
5883 return pi;
5884}
5885
5886proto_item *
5887proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5888 unsigned start, unsigned length, float value,
5889 const char *format, ...)
5890{
5891 proto_item *pi;
5892 va_list ap;
5893
5894 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5895 if (pi != tree) {
5896 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5896, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5897
5898 va_start(ap, format)__builtin_va_start(ap, format);
5899 proto_tree_set_representation(pi, format, ap);
5900 va_end(ap)__builtin_va_end(ap);
5901 }
5902
5903 return pi;
5904}
5905
5906/* Set the FT_FLOAT value */
5907static void
5908proto_tree_set_float(field_info *fi, float value)
5909{
5910 fvalue_set_floating(fi->value, value);
5911}
5912
5913/* Add a FT_DOUBLE to a proto_tree */
5914proto_item *
5915proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5916 unsigned length, double value)
5917{
5918 proto_item *pi;
5919 header_field_info *hfinfo;
5920
5921 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5922
5923 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", 5923
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5923, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5923, "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", 5923, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5924
5925 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"
, 5925, ((hfinfo))->abbrev))))
;
5926
5927 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5928 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5929
5930 return pi;
5931}
5932
5933proto_item *
5934proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5935 unsigned start, unsigned length, double value,
5936 const char *format, ...)
5937{
5938 proto_item *pi;
5939 va_list ap;
5940
5941 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5942 if (pi != tree) {
5943 va_start(ap, format)__builtin_va_start(ap, format);
5944 proto_tree_set_representation_value(pi, format, ap);
5945 va_end(ap)__builtin_va_end(ap);
5946 }
5947
5948 return pi;
5949}
5950
5951proto_item *
5952proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5953 unsigned start, unsigned length, double value,
5954 const char *format, ...)
5955{
5956 proto_item *pi;
5957 va_list ap;
5958
5959 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5960 if (pi != tree) {
5961 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5961, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5962
5963 va_start(ap, format)__builtin_va_start(ap, format);
5964 proto_tree_set_representation(pi, format, ap);
5965 va_end(ap)__builtin_va_end(ap);
5966 }
5967
5968 return pi;
5969}
5970
5971/* Set the FT_DOUBLE value */
5972static void
5973proto_tree_set_double(field_info *fi, double value)
5974{
5975 fvalue_set_floating(fi->value, value);
5976}
5977
5978/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5979proto_item *
5980proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5981 unsigned length, uint32_t value)
5982{
5983 proto_item *pi = NULL((void*)0);
5984 header_field_info *hfinfo;
5985
5986 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5987
5988 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", 5988
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5988, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5988, "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", 5988, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5989
5990 switch (hfinfo->type) {
5991 case FT_CHAR:
5992 case FT_UINT8:
5993 case FT_UINT16:
5994 case FT_UINT24:
5995 case FT_UINT32:
5996 case FT_FRAMENUM:
5997 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5998 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5999 break;
6000
6001 default:
6002 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)
6003 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)
;
6004 }
6005
6006 return pi;
6007}
6008
6009proto_item *
6010proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6011 unsigned start, unsigned length, uint32_t value,
6012 const char *format, ...)
6013{
6014 proto_item *pi;
6015 va_list ap;
6016
6017 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6018 if (pi != tree) {
6019 va_start(ap, format)__builtin_va_start(ap, format);
6020 proto_tree_set_representation_value(pi, format, ap);
6021 va_end(ap)__builtin_va_end(ap);
6022 }
6023
6024 return pi;
6025}
6026
6027proto_item *
6028proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6029 unsigned start, unsigned length, uint32_t value,
6030 const char *format, ...)
6031{
6032 proto_item *pi;
6033 va_list ap;
6034
6035 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6036 if (pi != tree) {
6037 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6037, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6038
6039 va_start(ap, format)__builtin_va_start(ap, format);
6040 proto_tree_set_representation(pi, format, ap);
6041 va_end(ap)__builtin_va_end(ap);
6042 }
6043
6044 return pi;
6045}
6046
6047/* Set the FT_UINT{8,16,24,32} value */
6048static void
6049proto_tree_set_uint(field_info *fi, uint32_t value)
6050{
6051 const header_field_info *hfinfo;
6052 uint32_t integer;
6053
6054 hfinfo = fi->hfinfo;
6055 integer = value;
6056
6057 if (hfinfo->bitmask) {
6058 /* Mask out irrelevant portions */
6059 integer &= (uint32_t)(hfinfo->bitmask);
6060
6061 /* Shift bits */
6062 integer >>= hfinfo_bitshift(hfinfo);
6063
6064 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6065 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)
;
6066 }
6067
6068 fvalue_set_uinteger(fi->value, integer);
6069}
6070
6071/* Add FT_UINT{40,48,56,64} to a proto_tree */
6072proto_item *
6073proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6074 unsigned length, uint64_t value)
6075{
6076 proto_item *pi = NULL((void*)0);
6077 header_field_info *hfinfo;
6078
6079 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6080
6081 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", 6081
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6081, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6081, "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", 6081, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6082
6083 switch (hfinfo->type) {
6084 case FT_UINT40:
6085 case FT_UINT48:
6086 case FT_UINT56:
6087 case FT_UINT64:
6088 case FT_FRAMENUM:
6089 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6090 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6091 break;
6092
6093 default:
6094 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)
6095 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)
;
6096 }
6097
6098 return pi;
6099}
6100
6101proto_item *
6102proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6103 unsigned start, unsigned length, uint64_t value,
6104 const char *format, ...)
6105{
6106 proto_item *pi;
6107 va_list ap;
6108
6109 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6110 if (pi != tree) {
6111 va_start(ap, format)__builtin_va_start(ap, format);
6112 proto_tree_set_representation_value(pi, format, ap);
6113 va_end(ap)__builtin_va_end(ap);
6114 }
6115
6116 return pi;
6117}
6118
6119proto_item *
6120proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6121 unsigned start, unsigned length, uint64_t value,
6122 const char *format, ...)
6123{
6124 proto_item *pi;
6125 va_list ap;
6126
6127 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6128 if (pi != tree) {
6129 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6129, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6130
6131 va_start(ap, format)__builtin_va_start(ap, format);
6132 proto_tree_set_representation(pi, format, ap);
6133 va_end(ap)__builtin_va_end(ap);
6134 }
6135
6136 return pi;
6137}
6138
6139/* Set the FT_UINT{40,48,56,64} value */
6140static void
6141proto_tree_set_uint64(field_info *fi, uint64_t value)
6142{
6143 const header_field_info *hfinfo;
6144 uint64_t integer;
6145
6146 hfinfo = fi->hfinfo;
6147 integer = value;
6148
6149 if (hfinfo->bitmask) {
6150 /* Mask out irrelevant portions */
6151 integer &= hfinfo->bitmask;
6152
6153 /* Shift bits */
6154 integer >>= hfinfo_bitshift(hfinfo);
6155
6156 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6157 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)
;
6158 }
6159
6160 fvalue_set_uinteger64(fi->value, integer);
6161}
6162
6163/* Add FT_INT{8,16,24,32} to a proto_tree */
6164proto_item *
6165proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6166 unsigned length, int32_t value)
6167{
6168 proto_item *pi = NULL((void*)0);
6169 header_field_info *hfinfo;
6170
6171 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6172
6173 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", 6173
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6173, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6173, "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", 6173, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6174
6175 switch (hfinfo->type) {
6176 case FT_INT8:
6177 case FT_INT16:
6178 case FT_INT24:
6179 case FT_INT32:
6180 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6181 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6182 break;
6183
6184 default:
6185 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)
6186 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6187 }
6188
6189 return pi;
6190}
6191
6192proto_item *
6193proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6194 unsigned start, unsigned length, int32_t value,
6195 const char *format, ...)
6196{
6197 proto_item *pi;
6198 va_list ap;
6199
6200 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6201 if (pi != tree) {
6202 va_start(ap, format)__builtin_va_start(ap, format);
6203 proto_tree_set_representation_value(pi, format, ap);
6204 va_end(ap)__builtin_va_end(ap);
6205 }
6206
6207 return pi;
6208}
6209
6210proto_item *
6211proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6212 unsigned start, unsigned length, int32_t value,
6213 const char *format, ...)
6214{
6215 proto_item *pi;
6216 va_list ap;
6217
6218 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6219 if (pi != tree) {
6220 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6220, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6221
6222 va_start(ap, format)__builtin_va_start(ap, format);
6223 proto_tree_set_representation(pi, format, ap);
6224 va_end(ap)__builtin_va_end(ap);
6225 }
6226
6227 return pi;
6228}
6229
6230/* Set the FT_INT{8,16,24,32} value */
6231static void
6232proto_tree_set_int(field_info *fi, int32_t value)
6233{
6234 const header_field_info *hfinfo;
6235 uint32_t integer;
6236 int no_of_bits;
6237
6238 hfinfo = fi->hfinfo;
6239 integer = (uint32_t) value;
6240
6241 if (hfinfo->bitmask) {
6242 /* Mask out irrelevant portions */
6243 integer &= (uint32_t)(hfinfo->bitmask);
6244
6245 /* Shift bits */
6246 integer >>= hfinfo_bitshift(hfinfo);
6247
6248 no_of_bits = ws_count_ones(hfinfo->bitmask);
6249 integer = ws_sign_ext32(integer, no_of_bits);
6250
6251 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6252 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)
;
6253 }
6254
6255 fvalue_set_sinteger(fi->value, integer);
6256}
6257
6258/* Add FT_INT{40,48,56,64} to a proto_tree */
6259proto_item *
6260proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6261 unsigned length, int64_t value)
6262{
6263 proto_item *pi = NULL((void*)0);
6264 header_field_info *hfinfo;
6265
6266 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6267
6268 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", 6268
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6268, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6268, "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", 6268, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6269
6270 switch (hfinfo->type) {
6271 case FT_INT40:
6272 case FT_INT48:
6273 case FT_INT56:
6274 case FT_INT64:
6275 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6276 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6277 break;
6278
6279 default:
6280 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)
6281 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6282 }
6283
6284 return pi;
6285}
6286
6287proto_item *
6288proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6289 unsigned start, unsigned length, int64_t value,
6290 const char *format, ...)
6291{
6292 proto_item *pi;
6293 va_list ap;
6294
6295 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6296 if (pi != tree) {
6297 va_start(ap, format)__builtin_va_start(ap, format);
6298 proto_tree_set_representation_value(pi, format, ap);
6299 va_end(ap)__builtin_va_end(ap);
6300 }
6301
6302 return pi;
6303}
6304
6305/* Set the FT_INT{40,48,56,64} value */
6306static void
6307proto_tree_set_int64(field_info *fi, int64_t value)
6308{
6309 const header_field_info *hfinfo;
6310 uint64_t integer;
6311 int no_of_bits;
6312
6313 hfinfo = fi->hfinfo;
6314 integer = value;
6315
6316 if (hfinfo->bitmask) {
6317 /* Mask out irrelevant portions */
6318 integer &= hfinfo->bitmask;
6319
6320 /* Shift bits */
6321 integer >>= hfinfo_bitshift(hfinfo);
6322
6323 no_of_bits = ws_count_ones(hfinfo->bitmask);
6324 integer = ws_sign_ext64(integer, no_of_bits);
6325
6326 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6327 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)
;
6328 }
6329
6330 fvalue_set_sinteger64(fi->value, integer);
6331}
6332
6333proto_item *
6334proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6335 unsigned start, unsigned length, int64_t value,
6336 const char *format, ...)
6337{
6338 proto_item *pi;
6339 va_list ap;
6340
6341 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6342 if (pi != tree) {
6343 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6343, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6344
6345 va_start(ap, format)__builtin_va_start(ap, format);
6346 proto_tree_set_representation(pi, format, ap);
6347 va_end(ap)__builtin_va_end(ap);
6348 }
6349
6350 return pi;
6351}
6352
6353/* Add a FT_EUI64 to a proto_tree */
6354proto_item *
6355proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6356 unsigned length, const uint64_t value)
6357{
6358 proto_item *pi;
6359 header_field_info *hfinfo;
6360
6361 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6362
6363 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", 6363
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6363, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6363, "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", 6363, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6364
6365 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",
6365, ((hfinfo))->abbrev))))
;
6366
6367 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6368 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6369
6370 return pi;
6371}
6372
6373proto_item *
6374proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6375 unsigned start, unsigned length, const uint64_t value,
6376 const char *format, ...)
6377{
6378 proto_item *pi;
6379 va_list ap;
6380
6381 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6382 if (pi != tree) {
6383 va_start(ap, format)__builtin_va_start(ap, format);
6384 proto_tree_set_representation_value(pi, format, ap);
6385 va_end(ap)__builtin_va_end(ap);
6386 }
6387
6388 return pi;
6389}
6390
6391proto_item *
6392proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6393 unsigned start, unsigned length, const uint64_t value,
6394 const char *format, ...)
6395{
6396 proto_item *pi;
6397 va_list ap;
6398
6399 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6400 if (pi != tree) {
6401 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6401, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6402
6403 va_start(ap, format)__builtin_va_start(ap, format);
6404 proto_tree_set_representation(pi, format, ap);
6405 va_end(ap)__builtin_va_end(ap);
6406 }
6407
6408 return pi;
6409}
6410
6411/* Set the FT_EUI64 value */
6412static void
6413proto_tree_set_eui64(field_info *fi, const uint64_t value)
6414{
6415 uint8_t v[FT_EUI64_LEN8];
6416 phtonu64(v, value);
6417 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6418}
6419
6420static void
6421proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6422{
6423 if (encoding)
6424 {
6425 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6426 } else {
6427 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6428 }
6429}
6430
6431proto_item *
6432proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6433 const mac_hf_list_t *list_generic,
6434 int idx, tvbuff_t *tvb,
6435 proto_tree *tree, unsigned offset)
6436{
6437 uint8_t addr[6];
6438 const char *addr_name = NULL((void*)0);
6439 const char *oui_name = NULL((void*)0);
6440 proto_item *addr_item = NULL((void*)0);
6441 proto_tree *addr_tree = NULL((void*)0);
6442 proto_item *ret_val = NULL((void*)0);
6443
6444 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6445 return NULL((void*)0);
6446 }
6447
6448 /* Resolve what we can of the address */
6449 tvb_memcpy(tvb, addr, offset, sizeof addr);
6450 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6451 addr_name = get_ether_name(addr);
6452 }
6453 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6454 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6455 }
6456
6457 /* Add the item for the specific address type */
6458 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6459 if (idx >= 0) {
6460 addr_tree = proto_item_add_subtree(ret_val, idx);
6461 }
6462 else {
6463 addr_tree = tree;
6464 }
6465
6466 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6467 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6468 tvb, offset, 6, addr_name);
6469 proto_item_set_generated(addr_item);
6470 proto_item_set_hidden(addr_item);
6471 }
6472
6473 if (list_specific->hf_oui != NULL((void*)0)) {
6474 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6475 proto_item_set_generated(addr_item);
6476 proto_item_set_hidden(addr_item);
6477
6478 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6479 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6480 proto_item_set_generated(addr_item);
6481 proto_item_set_hidden(addr_item);
6482 }
6483 }
6484
6485 if (list_specific->hf_lg != NULL((void*)0)) {
6486 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6487 }
6488 if (list_specific->hf_ig != NULL((void*)0)) {
6489 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6490 }
6491
6492 /* Were we given a list for generic address fields? If not, stop here */
6493 if (list_generic == NULL((void*)0)) {
6494 return ret_val;
6495 }
6496
6497 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6498 proto_item_set_hidden(addr_item);
6499
6500 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6501 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6502 tvb, offset, 6, addr_name);
6503 proto_item_set_generated(addr_item);
6504 proto_item_set_hidden(addr_item);
6505 }
6506
6507 if (list_generic->hf_oui != NULL((void*)0)) {
6508 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6509 proto_item_set_generated(addr_item);
6510 proto_item_set_hidden(addr_item);
6511
6512 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6513 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6514 proto_item_set_generated(addr_item);
6515 proto_item_set_hidden(addr_item);
6516 }
6517 }
6518
6519 if (list_generic->hf_lg != NULL((void*)0)) {
6520 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6521 proto_item_set_hidden(addr_item);
6522 }
6523 if (list_generic->hf_ig != NULL((void*)0)) {
6524 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6525 proto_item_set_hidden(addr_item);
6526 }
6527 return ret_val;
6528}
6529
6530static proto_item *
6531proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6532{
6533 proto_node *pnode, *tnode, *sibling;
6534 field_info *tfi;
6535 unsigned depth = 1;
6536
6537 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6537, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6538
6539 /*
6540 * Restrict our depth. proto_tree_traverse_pre_order and
6541 * proto_tree_traverse_post_order (and possibly others) are recursive
6542 * so we need to be mindful of our stack size.
6543 */
6544 if (tree->first_child == NULL((void*)0)) {
6545 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6546 depth++;
6547 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6548 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__)), 6551)))
6549 "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__)), 6551)))
6550 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__)), 6551)))
6551 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__)), 6551)))
;
6552 }
6553 }
6554 }
6555
6556 /*
6557 * Make sure "tree" is ready to have subtrees under it, by
6558 * checking whether it's been given an ett_ value.
6559 *
6560 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6561 * node of the protocol tree. That node is not displayed,
6562 * so it doesn't need an ett_ value to remember whether it
6563 * was expanded.
6564 */
6565 tnode = tree;
6566 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6567 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6568 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"
, 6569)
6569 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"
, 6569)
;
6570 /* XXX - is it safe to continue here? */
6571 }
6572
6573 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6574 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6575 pnode->parent = tnode;
6576 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6577 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6578 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6579
6580 if (tnode->last_child != NULL((void*)0)) {
6581 sibling = tnode->last_child;
6582 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6582, "sibling->next == ((void*)0)"
))))
;
6583 sibling->next = pnode;
6584 } else
6585 tnode->first_child = pnode;
6586 tnode->last_child = pnode;
6587
6588 /* We should not be adding a fake node for an interesting field */
6589 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", 6589, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6590
6591 /* XXX - Should the proto_item have a header_field_info member, at least
6592 * for faked items, to know what hfi was faked? (Some dissectors look at
6593 * the tree items directly.)
6594 */
6595 return (proto_item *)pnode;
6596}
6597
6598/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6599static proto_item *
6600proto_tree_add_node(proto_tree *tree, field_info *fi)
6601{
6602 proto_node *pnode, *tnode, *sibling;
6603 field_info *tfi;
6604 unsigned depth = 1;
6605
6606 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6606, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6607
6608 /*
6609 * Restrict our depth. proto_tree_traverse_pre_order and
6610 * proto_tree_traverse_post_order (and possibly others) are recursive
6611 * so we need to be mindful of our stack size.
6612 */
6613 if (tree->first_child == NULL((void*)0)) {
6614 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6615 depth++;
6616 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6617 /* The fvalue_t is pool-allocated; just release the
6618 * type-specific data it owns (see new_field_info()). */
6619 fvalue_cleanup(fi->value);
6620 fi->value = NULL((void*)0);
6621 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__)), 6624)))
6622 "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__)), 6624)))
6623 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__)), 6624)))
6624 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__)), 6624)))
;
6625 }
6626 }
6627 }
6628
6629 /*
6630 * Make sure "tree" is ready to have subtrees under it, by
6631 * checking whether it's been given an ett_ value.
6632 *
6633 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6634 * node of the protocol tree. That node is not displayed,
6635 * so it doesn't need an ett_ value to remember whether it
6636 * was expanded.
6637 */
6638 tnode = tree;
6639 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6640 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6641 /* Since we are not adding fi to a node, its fvalue won't get
6642 * cleaned up by proto_tree_free_node(), so release the
6643 * type-specific data it owns now. The fvalue_t structure itself
6644 * is pool-allocated (see new_field_info()).
6645 */
6646 fvalue_cleanup(fi->value);
6647 fi->value = NULL((void*)0);
6648 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", 6649)
6649 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", 6649)
;
6650 /* XXX - is it safe to continue here? */
6651 }
6652
6653 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6654 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6655 pnode->parent = tnode;
6656 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6657 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6658 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6659
6660 if (tnode->last_child != NULL((void*)0)) {
6661 sibling = tnode->last_child;
6662 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6662, "sibling->next == ((void*)0)"
))))
;
6663 sibling->next = pnode;
6664 } else
6665 tnode->first_child = pnode;
6666 tnode->last_child = pnode;
6667
6668 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6669
6670 return (proto_item *)pnode;
6671}
6672
6673
6674/* Generic way to allocate field_info and add to proto_tree.
6675 * Sets *pfi to address of newly-allocated field_info struct */
6676static proto_item *
6677proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6678 int *length)
6679{
6680 proto_item *pi;
6681 field_info *fi;
6682 int item_length;
6683
6684 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6685 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6686 pi = proto_tree_add_node(tree, fi);
6687
6688 return pi;
6689}
6690
6691/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6692 * Eventually this should replace the other function.
6693 * Sets *pfi to address of newly-allocated field_info struct */
6694static proto_item *
6695proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6696 unsigned *length)
6697{
6698 proto_item *pi;
6699 field_info *fi;
6700 unsigned item_length;
6701
6702 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6703 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6704 pi = proto_tree_add_node(tree, fi);
6705
6706 return pi;
6707}
6708
6709static void
6710get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6711 int *item_length, const unsigned encoding)
6712{
6713 int length_remaining;
6714
6715 /*
6716 * We only allow a null tvbuff if the item has a zero length,
6717 * i.e. if there's no data backing it.
6718 */
6719 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", 6719, "tvb != ((void*)0) || *length == 0"
))))
;
6720
6721 /*
6722 * XXX - in some protocols, there are 32-bit unsigned length
6723 * fields, so lengths in protocol tree and tvbuff routines
6724 * should really be unsigned. We should have, for those
6725 * field types for which "to the end of the tvbuff" makes sense,
6726 * additional routines that take no length argument and
6727 * add fields that run to the end of the tvbuff.
6728 */
6729 if (*length == -1) {
6730 /*
6731 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6732 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6733 * of -1 means "set the length to what remains in the
6734 * tvbuff".
6735 *
6736 * The assumption is either that
6737 *
6738 * 1) the length of the item can only be determined
6739 * by dissection (typically true of items with
6740 * subitems, which are probably FT_NONE or
6741 * FT_PROTOCOL)
6742 *
6743 * or
6744 *
6745 * 2) if the tvbuff is "short" (either due to a short
6746 * snapshot length or due to lack of reassembly of
6747 * fragments/segments/whatever), we want to display
6748 * what's available in the field (probably FT_BYTES
6749 * or FT_STRING) and then throw an exception later
6750 *
6751 * or
6752 *
6753 * 3) the field is defined to be "what's left in the
6754 * packet"
6755 *
6756 * so we set the length to what remains in the tvbuff so
6757 * that, if we throw an exception while dissecting, it
6758 * has what is probably the right value.
6759 *
6760 * For FT_STRINGZ, it means "the string is null-terminated,
6761 * not null-padded; set the length to the actual length
6762 * of the string", and if the tvbuff if short, we just
6763 * throw an exception.
6764 *
6765 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6766 * it means "find the end of the string",
6767 * and if the tvbuff if short, we just throw an exception.
6768 *
6769 * It's not valid for any other type of field. For those
6770 * fields, we treat -1 the same way we treat other
6771 * negative values - we assume the length is a Really
6772 * Big Positive Number, and throw a ReportedBoundsError
6773 * exception, under the assumption that the Really Big
6774 * Length would run past the end of the packet.
6775 */
6776 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
))
)) {
6777 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6778 /*
6779 * Leave the length as -1, so our caller knows
6780 * it was -1.
6781 */
6782 *item_length = *length;
6783 return;
6784 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6785 switch (tvb_get_uint8(tvb, start) >> 6)
6786 {
6787 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6788 *item_length = 1;
6789 break;
6790 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6791 *item_length = 2;
6792 break;
6793 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6794 *item_length = 4;
6795 break;
6796 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6797 *item_length = 8;
6798 break;
6799 }
6800 }
6801 }
6802
6803 switch (hfinfo->type) {
6804
6805 case FT_PROTOCOL:
6806 case FT_NONE:
6807 case FT_BYTES:
6808 case FT_STRING:
6809 case FT_STRINGZPAD:
6810 case FT_STRINGZTRUNC:
6811 /*
6812 * We allow FT_PROTOCOLs to be zero-length -
6813 * for example, an ONC RPC NULL procedure has
6814 * neither arguments nor reply, so the
6815 * payload for that protocol is empty.
6816 *
6817 * We also allow the others to be zero-length -
6818 * because that's the way the code has been for a
6819 * long, long time.
6820 *
6821 * However, we want to ensure that the start
6822 * offset is not *past* the byte past the end
6823 * of the tvbuff: we throw an exception in that
6824 * case.
6825 */
6826 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6827 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6827, "*length >= 0"
))))
;
6828 break;
6829
6830 case FT_STRINGZ:
6831 /*
6832 * Leave the length as -1, so our caller knows
6833 * it was -1.
6834 */
6835 break;
6836
6837 default:
6838 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6839 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6839))
;
6840 }
6841 *item_length = *length;
6842 } else {
6843 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6844 /*
6845 * These types are for interior nodes of the
6846 * tree, and don't have data associated with
6847 * them; if the length is negative (XXX - see
6848 * above) or goes past the end of the tvbuff,
6849 * cut it short at the end of the tvbuff.
6850 * That way, if this field is selected in
6851 * Wireshark, we don't highlight stuff past
6852 * the end of the data.
6853 *
6854 * If we don't have a tvb, then length must be zero,
6855 * per the DISSECTOR_ASSERT() above.
6856 *
6857 * If we do have a tvb, and the length requested is
6858 * nonzero, we want to ensure that the start offset
6859 * is not *past* the byte past the end of the tvbuff
6860 * data: we throw an exception in that case as above.
6861 */
6862 if (tvb && *length) {
6863 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6864 if (*length < 0 ||
6865 (*length > 0 &&
6866 (length_remaining < *length)))
6867 *length = length_remaining;
6868 }
6869 }
6870 *item_length = *length;
6871 if (*item_length < 0) {
6872 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6873 }
6874 }
6875}
6876
6877static void
6878get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6879 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6880{
6881 unsigned length_remaining;
6882
6883 /*
6884 * We only allow a null tvbuff if the item has a zero length,
6885 * i.e. if there's no data backing it.
6886 */
6887 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", 6887, "tvb != ((void*)0) || *length == 0"
))))
;
6888
6889
6890 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6891 /*
6892 * These types are for interior nodes of the
6893 * tree, and don't have data associated with
6894 * them; if the length is negative (XXX - see
6895 * above) or goes past the end of the tvbuff,
6896 * cut it short at the end of the tvbuff.
6897 * That way, if this field is selected in
6898 * Wireshark, we don't highlight stuff past
6899 * the end of the data.
6900 *
6901 * If we don't have a tvb, then length must be zero,
6902 * per the DISSECTOR_ASSERT() above.
6903 *
6904 * If we do have a tvb, and the length requested is
6905 * nonzero, we want to ensure that the start offset
6906 * is not *past* the byte past the end of the tvbuff
6907 * data: we throw an exception in that case as above.
6908 * (If the length requested is zero, then it's quite
6909 * likely that the start offset is the byte past the
6910 * end, but that's ok.)
6911 */
6912 if (tvb && *length) {
6913 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6914 if (length_remaining < *length) {
6915 *length = length_remaining;
6916 }
6917 }
6918 }
6919 *item_length = *length;
6920}
6921
6922static int
6923get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6924 int length, unsigned item_length, const int encoding)
6925{
6926 uint32_t n;
6927
6928 /*
6929 * We need to get the correct item length here.
6930 * That's normally done by proto_tree_new_item(),
6931 * but we won't be calling it.
6932 */
6933 switch (hfinfo->type) {
6934
6935 case FT_NONE:
6936 case FT_PROTOCOL:
6937 case FT_BYTES:
6938 /*
6939 * The length is the specified length.
6940 */
6941 break;
6942
6943 case FT_UINT_BYTES:
6944 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6945 item_length += n;
6946 if ((int)item_length < length) {
6947 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6948 }
6949 break;
6950
6951 /* XXX - make these just FT_UINT? */
6952 case FT_UINT8:
6953 case FT_UINT16:
6954 case FT_UINT24:
6955 case FT_UINT32:
6956 case FT_UINT40:
6957 case FT_UINT48:
6958 case FT_UINT56:
6959 case FT_UINT64:
6960 /* XXX - make these just FT_INT? */
6961 case FT_INT8:
6962 case FT_INT16:
6963 case FT_INT24:
6964 case FT_INT32:
6965 case FT_INT40:
6966 case FT_INT48:
6967 case FT_INT56:
6968 case FT_INT64:
6969 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6970 if (length < -1) {
6971 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6972 }
6973 if (length == -1) {
6974 uint64_t dummy;
6975 /* This can throw an exception */
6976 /* XXX - do this without fetching the varint? */
6977 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6978 if (length == 0) {
6979 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6980 }
6981 }
6982 item_length = length;
6983 break;
6984 }
6985
6986 /*
6987 * The length is the specified length.
6988 */
6989 break;
6990
6991 case FT_BOOLEAN:
6992 case FT_CHAR:
6993 case FT_IPv4:
6994 case FT_IPXNET:
6995 case FT_IPv6:
6996 case FT_FCWWN:
6997 case FT_AX25:
6998 case FT_VINES:
6999 case FT_ETHER:
7000 case FT_EUI64:
7001 case FT_GUID:
7002 case FT_OID:
7003 case FT_REL_OID:
7004 case FT_SYSTEM_ID:
7005 case FT_FLOAT:
7006 case FT_DOUBLE:
7007 case FT_STRING:
7008 /*
7009 * The length is the specified length.
7010 */
7011 break;
7012
7013 case FT_STRINGZ:
7014 if (length < -1) {
7015 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7016 }
7017 if (length == -1) {
7018 /* This can throw an exception */
7019 item_length = tvb_strsize_enc(tvb, start, encoding);
7020 }
7021 break;
7022
7023 case FT_UINT_STRING:
7024 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7025 item_length += n;
7026 if ((int)item_length < length) {
7027 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7028 }
7029 break;
7030
7031 case FT_STRINGZPAD:
7032 case FT_STRINGZTRUNC:
7033 case FT_ABSOLUTE_TIME:
7034 case FT_RELATIVE_TIME:
7035 case FT_IEEE_11073_SFLOAT:
7036 case FT_IEEE_11073_FLOAT:
7037 /*
7038 * The length is the specified length.
7039 */
7040 break;
7041
7042 default:
7043 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
))
7044 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
))
7045 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
))
7046 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
))
;
7047 break;
7048 }
7049 return item_length;
7050}
7051
7052// This was arbitrarily chosen, but if you're adding 50K items to the tree
7053// without advancing the offset you should probably take a long, hard look
7054// at what you're doing.
7055// We *could* make this a configurable option, but I (Gerald) would like to
7056// avoid adding yet another nerd knob.
7057# define PROTO_TREE_MAX_IDLE50000 50000
7058static field_info *
7059new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7060 const unsigned start, const int item_length)
7061{
7062 field_info *fi;
7063
7064 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7065
7066 fi->hfinfo = hfinfo;
7067 fi->start = start;
7068 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7069 /* add the data source tvbuff */
7070 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7071
7072 // If our start offset hasn't advanced after adding many items it probably
7073 // means we're in a large or infinite loop.
7074 if (fi->start > 0) {
7075 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7076 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7077 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7078 if (wireshark_abort_on_too_many_items) {
7079 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", 7080
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7080 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7080
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7081 }
7082 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7083 * but if not, we should hit the max item error earlier,
7084 * so we shouldn't need to reset the tree count to
7085 * ensure that the exception handler can add the item. */
7086 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)))
7087 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)))
7088 "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)))
7089 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)))
;
7090 }
7091 } else {
7092 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7093 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7094 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7095 }
7096 }
7097 fi->length = item_length;
7098 fi->tree_type = -1;
7099 fi->flags = 0;
7100 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7101 /* If the tree is not visible, set the item hidden, unless we
7102 * need the representation or length and can't fake them.
7103 */
7104 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7105 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7106 }
7107 }
7108 fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7109 fi->rep = NULL((void*)0);
7110
7111 fi->appendix_start = 0;
7112 fi->appendix_length = 0;
7113
7114 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7115 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7116
7117 return fi;
7118}
7119
7120static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7121{
7122 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7123 return 0;
7124 }
7125
7126 /* Search for field name */
7127 char *ptr = strstr(representation, hfinfo->name);
7128 if (!ptr) {
7129 return 0;
7130 }
7131
7132 /* Check if field name ends with the ": " delimiter */
7133 ptr += strlen(hfinfo->name);
7134 if (strncmp(ptr, ": ", 2) == 0) {
7135 ptr += 2;
7136 }
7137
7138 /* Return offset to after field name */
7139 return ptr - representation;
7140}
7141
7142static size_t label_find_name_pos(const item_label_t *rep)
7143{
7144 size_t name_pos = 0;
7145
7146 /* If the value_pos is too small or too large, we can't find the expected format */
7147 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7148 return 0;
7149 }
7150
7151 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7152 if (rep->representation[rep->value_pos-2] == ':') {
7153 name_pos = rep->value_pos - 2;
7154 }
7155
7156 return name_pos;
7157}
7158
7159/* If the protocol tree is to be visible, set the representation of a
7160 proto_tree entry with the name of the field for the item and with
7161 the value formatted with the supplied printf-style format and
7162 argument list. */
7163static void
7164proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7165{
7166 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7166, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7167
7168 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7169 * items string representation */
7170 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7171 size_t name_pos, ret = 0;
7172 char *str;
7173 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7174 const header_field_info *hf;
7175
7176 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7176, "fi"))))
;
7177
7178 hf = fi->hfinfo;
7179
7180 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;
;
7181 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))
)) {
7182 uint64_t val;
7183 char *p;
7184
7185 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)
)
7186 val = fvalue_get_uinteger(fi->value);
7187 else
7188 val = fvalue_get_uinteger64(fi->value);
7189
7190 val <<= hfinfo_bitshift(hf);
7191
7192 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7193 ret = (p - fi->rep->representation);
7194 }
7195
7196 /* put in the hf name */
7197 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)
;
7198
7199 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7200 /* If possible, Put in the value of the string */
7201 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7202 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"
, 7202, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7203 fi->rep->value_pos = ret;
7204 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7205 if (ret >= ITEM_LABEL_LENGTH240) {
7206 /* Uh oh, we don't have enough room. Tell the user
7207 * that the field is truncated.
7208 */
7209 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7210 }
7211 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7212 }
7213}
7214
7215/* If the protocol tree is to be visible, set the representation of a
7216 proto_tree entry with the representation formatted with the supplied
7217 printf-style format and argument list. */
7218static void
7219proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7220{
7221 size_t ret; /*tmp return value */
7222 char *str;
7223 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7224
7225 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7225, "fi"))))
;
7226
7227 if (!proto_item_is_hidden(pi)) {
7228 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;
;
7229
7230 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7231 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"
, 7231, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7232 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7233 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7234 if (ret >= ITEM_LABEL_LENGTH240) {
7235 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7236 size_t name_pos = label_find_name_pos(fi->rep);
7237 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7238 }
7239 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7240 }
7241}
7242
7243static int
7244proto_strlcpy(char *dest, const char *src, size_t dest_size)
7245{
7246 if (dest_size == 0) return 0;
7247
7248 size_t res = g_strlcpy(dest, src, dest_size);
7249
7250 /* At most dest_size - 1 characters will be copied
7251 * (unless dest_size is 0). */
7252 if (res >= dest_size)
7253 res = dest_size - 1;
7254 return (int) res;
7255}
7256
7257static header_field_info *
7258hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7259{
7260 header_field_info *dup_hfinfo;
7261
7262 if (hfinfo->same_name_prev_id == -1)
7263 return NULL((void*)0);
7264 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", 7264
, __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", 7264, "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", 7264,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7265 return dup_hfinfo;
7266}
7267
7268static void
7269hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7270{
7271 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)
;
7272 last_field_name = NULL((void*)0);
7273
7274 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7275 /* No hfinfo with the same name */
7276 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7277 return;
7278 }
7279
7280 if (hfinfo->same_name_next) {
7281 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7282 }
7283
7284 if (hfinfo->same_name_prev_id != -1) {
7285 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7286 same_name_prev->same_name_next = hfinfo->same_name_next;
7287 if (!hfinfo->same_name_next) {
7288 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7289 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7290 }
7291 }
7292}
7293
7294int
7295proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7296{
7297 const header_field_info *hfinfo = finfo->hfinfo;
7298 int label_len = 0;
7299 char *tmp_str;
7300 const char *str;
7301 const uint8_t *bytes;
7302 uint32_t number;
7303 uint64_t number64;
7304 const char *hf_str_val;
7305 char number_buf[NUMBER_LABEL_LENGTH80];
7306 const char *number_out;
7307 address addr;
7308 const ipv4_addr_and_mask *ipv4;
7309 const ipv6_addr_and_prefix *ipv6;
7310
7311 switch (hfinfo->type) {
7312
7313 case FT_NONE:
7314 case FT_PROTOCOL:
7315 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7316
7317 case FT_UINT_BYTES:
7318 case FT_BYTES:
7319 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7320 hfinfo,
7321 fvalue_get_bytes_data(finfo->value),
7322 (unsigned)fvalue_length2(finfo->value),
7323 label_str_size);
7324 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7325 wmem_free(NULL((void*)0), tmp_str);
7326 break;
7327
7328 case FT_ABSOLUTE_TIME:
7329 {
7330 const nstime_t *value = fvalue_get_time(finfo->value);
7331 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7332 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7333 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7334 }
7335 if (hfinfo->strings) {
7336 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7337 if (time_string != NULL((void*)0)) {
7338 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7339 break;
7340 }
7341 }
7342 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7343 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7344 wmem_free(NULL((void*)0), tmp_str);
7345 break;
7346 }
7347
7348 case FT_RELATIVE_TIME:
7349 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7350 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7351 wmem_free(NULL((void*)0), tmp_str);
7352 break;
7353
7354 case FT_BOOLEAN:
7355 number64 = fvalue_get_uinteger64(finfo->value);
7356 label_len = proto_strlcpy(display_label_str,
7357 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7358 break;
7359
7360 case FT_CHAR:
7361 number = fvalue_get_uinteger(finfo->value);
7362
7363 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7364 char tmp[ITEM_LABEL_LENGTH240];
7365 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7366
7367 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7367, "fmtfunc"))))
;
7368 fmtfunc(tmp, number);
7369
7370 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7371
7372 } else if (hfinfo->strings) {
7373 number_out = hf_try_val_to_str(number, hfinfo);
7374
7375 if (!number_out) {
7376 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7377 }
7378
7379 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7380
7381 } else {
7382 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7383
7384 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7385 }
7386
7387 break;
7388
7389 /* XXX - make these just FT_NUMBER? */
7390 case FT_INT8:
7391 case FT_INT16:
7392 case FT_INT24:
7393 case FT_INT32:
7394 case FT_UINT8:
7395 case FT_UINT16:
7396 case FT_UINT24:
7397 case FT_UINT32:
7398 case FT_FRAMENUM:
7399 hf_str_val = NULL((void*)0);
7400 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
))
?
7401 (uint32_t) fvalue_get_sinteger(finfo->value) :
7402 fvalue_get_uinteger(finfo->value);
7403
7404 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7405 char tmp[ITEM_LABEL_LENGTH240];
7406 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7407
7408 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7408, "fmtfunc"))))
;
7409 fmtfunc(tmp, number);
7410
7411 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7412
7413 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7414 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7415 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7416 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7417 hf_str_val = hf_try_val_to_str(number, hfinfo);
7418 if (hf_str_val)
7419 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7420 } else {
7421 number_out = hf_try_val_to_str(number, hfinfo);
7422
7423 if (!number_out) {
7424 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7425 }
7426
7427 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7428 }
7429 } else {
7430 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7431
7432 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7433 }
7434
7435 break;
7436
7437 case FT_INT40:
7438 case FT_INT48:
7439 case FT_INT56:
7440 case FT_INT64:
7441 case FT_UINT40:
7442 case FT_UINT48:
7443 case FT_UINT56:
7444 case FT_UINT64:
7445 hf_str_val = NULL((void*)0);
7446 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
))
?
7447 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7448 fvalue_get_uinteger64(finfo->value);
7449
7450 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7451 char tmp[ITEM_LABEL_LENGTH240];
7452 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7453
7454 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7454, "fmtfunc64"
))))
;
7455 fmtfunc64(tmp, number64);
7456
7457 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7458 } else if (hfinfo->strings) {
7459 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7460 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7461 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7462 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7463 if (hf_str_val)
7464 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7465 } else {
7466 number_out = hf_try_val64_to_str(number64, hfinfo);
7467
7468 if (!number_out)
7469 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7470
7471 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7472 }
7473 } else {
7474 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7475
7476 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7477 }
7478
7479 break;
7480
7481 case FT_EUI64:
7482 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7483 tmp_str = address_to_display(NULL((void*)0), &addr);
7484 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7485 wmem_free(NULL((void*)0), tmp_str);
7486 break;
7487
7488 case FT_IPv4:
7489 ipv4 = fvalue_get_ipv4(finfo->value);
7490 //XXX: Should we ignore the mask?
7491 set_address_ipv4(&addr, ipv4);
7492 tmp_str = address_to_display(NULL((void*)0), &addr);
7493 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7494 wmem_free(NULL((void*)0), tmp_str);
7495 free_address(&addr);
7496 break;
7497
7498 case FT_IPv6:
7499 ipv6 = fvalue_get_ipv6(finfo->value);
7500 set_address_ipv6(&addr, ipv6);
7501 tmp_str = address_to_display(NULL((void*)0), &addr);
7502 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7503 wmem_free(NULL((void*)0), tmp_str);
7504 free_address(&addr);
7505 break;
7506
7507 case FT_FCWWN:
7508 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7509 tmp_str = address_to_display(NULL((void*)0), &addr);
7510 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7511 wmem_free(NULL((void*)0), tmp_str);
7512 break;
7513
7514 case FT_ETHER:
7515 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7516 tmp_str = address_to_display(NULL((void*)0), &addr);
7517 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7518 wmem_free(NULL((void*)0), tmp_str);
7519 break;
7520
7521 case FT_GUID:
7522 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7523 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7524 wmem_free(NULL((void*)0), tmp_str);
7525 break;
7526
7527 case FT_REL_OID:
7528 bytes = fvalue_get_bytes_data(finfo->value);
7529 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7530 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7531 wmem_free(NULL((void*)0), tmp_str);
7532 break;
7533
7534 case FT_OID:
7535 bytes = fvalue_get_bytes_data(finfo->value);
7536 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7537 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7538 wmem_free(NULL((void*)0), tmp_str);
7539 break;
7540
7541 case FT_SYSTEM_ID:
7542 bytes = fvalue_get_bytes_data(finfo->value);
7543 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7544 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7545 wmem_free(NULL((void*)0), tmp_str);
7546 break;
7547
7548 case FT_FLOAT:
7549 case FT_DOUBLE:
7550 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7551 break;
7552
7553 case FT_IEEE_11073_SFLOAT:
7554 case FT_IEEE_11073_FLOAT:
7555 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7556 break;
7557
7558 case FT_STRING:
7559 case FT_STRINGZ:
7560 case FT_UINT_STRING:
7561 case FT_STRINGZPAD:
7562 case FT_STRINGZTRUNC:
7563 str = fvalue_get_string(finfo->value);
7564 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7565 if (label_len >= label_str_size) {
7566 /* Truncation occurred. Get the real length
7567 * copied (not including '\0') */
7568 label_len = label_str_size ? label_str_size - 1 : 0;
7569 }
7570 break;
7571
7572 default:
7573 /* First try ftype string representation */
7574 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7575 if (!tmp_str) {
7576 /* Default to show as bytes */
7577 bytes = fvalue_get_bytes_data(finfo->value);
7578 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7579 }
7580 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7581 wmem_free(NULL((void*)0), tmp_str);
7582 break;
7583 }
7584 return label_len;
7585}
7586
7587const char *
7588proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7589 char *result, char *expr, const int size)
7590{
7591 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7592 GPtrArray *finfos;
7593 field_info *finfo = NULL((void*)0);
7594 header_field_info* hfinfo;
7595 const char *abbrev = NULL((void*)0);
7596
7597 char *str;
7598 col_custom_t *field_idx;
7599 int field_id;
7600 int ii = 0;
7601
7602 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7602, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7603 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7604 field_id = field_idx->field_id;
7605 if (field_id == 0) {
7606 GPtrArray *fvals = NULL((void*)0);
7607 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7608 if (fvals != NULL((void*)0)) {
7609
7610 // XXX - Handling occurrences is unusual when more
7611 // than one field is involved, e.g. there's four
7612 // results for tcp.port + tcp.port. We may really
7613 // want to apply it to the operands, not the output.
7614 // Note that occurrences are not quite the same as
7615 // the layer operator (should the grammar support
7616 // both?)
7617 /* Calculate single index or set outer boundaries */
7618 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7619 if (occurrence < 0) {
7620 i = occurrence + len;
7621 last = i;
7622 } else if (occurrence > 0) {
7623 i = occurrence - 1;
7624 last = i;
7625 } else {
7626 i = 0;
7627 last = len - 1;
7628 }
7629 if (i < 0 || i >= len) {
7630 g_ptr_array_unref(fvals);
7631 continue;
7632 }
7633 for (; i <= last; i++) {
7634 /* XXX - We could have a "resolved" result
7635 * for types where the value depends only
7636 * on the type, e.g. FT_IPv4, and not on
7637 * hfinfo->strings. Supporting the latter
7638 * requires knowing which hfinfo matched
7639 * if there are multiple with the same
7640 * abbreviation. In any case, we need to
7641 * know the expected return type of the
7642 * field expression.
7643 */
7644 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7645 if (offset_r && (offset_r < (size - 1)))
7646 result[offset_r++] = ',';
7647 if (offset_e && (offset_e < (size - 1)))
7648 expr[offset_e++] = ',';
7649 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7650 // col_{add,append,set}_* calls ws_label_strcpy
7651 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7652
7653 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7654 }
7655 g_ptr_array_unref(fvals);
7656 } else if (passed) {
7657 // XXX - Occurrence doesn't make sense for a test
7658 // output, it should be applied to the operands.
7659 if (offset_r && (offset_r < (size - 1)))
7660 result[offset_r++] = ',';
7661 if (offset_e && (offset_e < (size - 1)))
7662 expr[offset_e++] = ',';
7663 /* Prevent multiple check marks */
7664 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7665 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7666 } else {
7667 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7668 }
7669 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7670 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7671 } else {
7672 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7673 }
7674 }
7675 continue;
7676 }
7677 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", 7677
, __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", 7677,
"(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", 7677,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7678
7679 /* do we need to rewind ? */
7680 if (!hfinfo)
7681 return "";
7682
7683 if (occurrence < 0) {
7684 /* Search other direction */
7685 while (hfinfo->same_name_prev_id != -1) {
7686 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", 7686
, __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", 7686, "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", 7686,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7687 }
7688 }
7689
7690 prev_len = 0; /* Reset handled occurrences */
7691
7692 while (hfinfo) {
7693 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7694
7695 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7696 if (occurrence < 0) {
7697 hfinfo = hfinfo->same_name_next;
7698 } else {
7699 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7700 }
7701 continue;
7702 }
7703
7704 /* Are there enough occurrences of the field? */
7705 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7706 if (occurrence < 0) {
7707 hfinfo = hfinfo->same_name_next;
7708 } else {
7709 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7710 }
7711 prev_len += len;
7712 continue;
7713 }
7714
7715 /* Calculate single index or set outer boundaries */
7716 if (occurrence < 0) {
7717 i = occurrence + len + prev_len;
7718 last = i;
7719 } else if (occurrence > 0) {
7720 i = occurrence - 1 - prev_len;
7721 last = i;
7722 } else {
7723 i = 0;
7724 last = len - 1;
7725 }
7726
7727 prev_len += len; /* Count handled occurrences */
7728
7729 while (i <= last) {
7730 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7731
7732 if (offset_r && (offset_r < (size - 1)))
7733 result[offset_r++] = ',';
7734
7735 if (display_details) {
7736 char representation[ITEM_LABEL_LENGTH240];
7737 size_t offset = 0;
7738
7739 if (finfo->rep && finfo->rep->value_len) {
7740 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7741 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7742 } else {
7743 proto_item_fill_label(finfo, representation, &offset);
7744 }
7745 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7746 } else {
7747 switch (hfinfo->type) {
7748
7749 case FT_NONE:
7750 case FT_PROTOCOL:
7751 /* Prevent multiple check marks */
7752 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7753 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7754 } else {
7755 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7756 }
7757 break;
7758
7759 default:
7760 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7761 break;
7762 }
7763 }
7764
7765 if (offset_e && (offset_e < (size - 1)))
7766 expr[offset_e++] = ',';
7767
7768 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
))
)) {
7769 const char *hf_str_val;
7770 /* Integer types with BASE_NONE never get the numeric value. */
7771 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7772 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7773 } 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
)
) {
7774 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7775 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7776 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7777 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7778 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7779 }
7780 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7781 offset_e = (int)strlen(expr);
7782 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7783 /* Prevent multiple check marks */
7784 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7785 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7786 } else {
7787 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7788 }
7789 } else {
7790 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7791 // col_{add,append,set}_* calls ws_label_strcpy
7792 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7793 wmem_free(NULL((void*)0), str);
7794 }
7795 i++;
7796 }
7797
7798 /* XXX: Why is only the first abbreviation returned for a multifield
7799 * custom column? */
7800 if (!abbrev) {
7801 /* Store abbrev for return value */
7802 abbrev = hfinfo->abbrev;
7803 }
7804
7805 if (occurrence == 0) {
7806 /* Fetch next hfinfo with same name (abbrev) */
7807 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7808 } else {
7809 hfinfo = NULL((void*)0);
7810 }
7811 }
7812 }
7813
7814 if (offset_r >= (size - 1)) {
7815 mark_truncated(result, 0, size, NULL((void*)0));
7816 }
7817 if (offset_e >= (size - 1)) {
7818 mark_truncated(expr, 0, size, NULL((void*)0));
7819 }
7820 return abbrev ? abbrev : "";
7821}
7822
7823char *
7824proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7825{
7826 int len, prev_len, last, i;
7827 GPtrArray *finfos;
7828 field_info *finfo = NULL((void*)0);
7829 header_field_info* hfinfo;
7830
7831 char *filter = NULL((void*)0);
7832 GPtrArray *filter_array;
7833
7834 col_custom_t *col_custom;
7835 int field_id;
7836
7837 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7837, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7838 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7839 for (GSList *iter = field_ids; iter; iter = iter->next) {
7840 col_custom = (col_custom_t*)iter->data;
7841 field_id = col_custom->field_id;
7842 if (field_id == 0) {
7843 GPtrArray *fvals = NULL((void*)0);
7844 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7845 if (fvals != NULL((void*)0)) {
7846 // XXX - Handling occurrences is unusual when more
7847 // than one field is involved, e.g. there's four
7848 // results for tcp.port + tcp.port. We really
7849 // want to apply it to the operands, not the output.
7850 /* Calculate single index or set outer boundaries */
7851 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7852 if (occurrence < 0) {
7853 i = occurrence + len;
7854 last = i;
7855 } else if (occurrence > 0) {
7856 i = occurrence - 1;
7857 last = i;
7858 } else {
7859 i = 0;
7860 last = len - 1;
7861 }
7862 if (i < 0 || i >= len) {
7863 g_ptr_array_unref(fvals);
7864 continue;
7865 }
7866 for (; i <= last; i++) {
7867 /* XXX - Should multiple values for one
7868 * field use set membership to reduce
7869 * verbosity, here and below? */
7870 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7871 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7872 wmem_free(NULL((void*)0), str);
7873 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7874 g_ptr_array_add(filter_array, filter);
7875 }
7876 }
7877 g_ptr_array_unref(fvals);
7878 } else if (passed) {
7879 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7880 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7881 g_ptr_array_add(filter_array, filter);
7882 }
7883 } else {
7884 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7885 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7886 g_ptr_array_add(filter_array, filter);
7887 }
7888 }
7889 continue;
7890 }
7891
7892 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", 7892
, __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", 7892,
"(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", 7892,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7893
7894 /* do we need to rewind ? */
7895 if (!hfinfo)
7896 return NULL((void*)0);
7897
7898 if (occurrence < 0) {
7899 /* Search other direction */
7900 while (hfinfo->same_name_prev_id != -1) {
7901 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", 7901
, __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", 7901, "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", 7901,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7902 }
7903 }
7904
7905 prev_len = 0; /* Reset handled occurrences */
7906
7907 while (hfinfo) {
7908 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7909
7910 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7911 if (occurrence < 0) {
7912 hfinfo = hfinfo->same_name_next;
7913 } else {
7914 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7915 }
7916 continue;
7917 }
7918
7919 /* Are there enough occurrences of the field? */
7920 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7921 if (occurrence < 0) {
7922 hfinfo = hfinfo->same_name_next;
7923 } else {
7924 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7925 }
7926 prev_len += len;
7927 continue;
7928 }
7929
7930 /* Calculate single index or set outer boundaries */
7931 if (occurrence < 0) {
7932 i = occurrence + len + prev_len;
7933 last = i;
7934 } else if (occurrence > 0) {
7935 i = occurrence - 1 - prev_len;
7936 last = i;
7937 } else {
7938 i = 0;
7939 last = len - 1;
7940 }
7941
7942 prev_len += len; /* Count handled occurrences */
7943
7944 while (i <= last) {
7945 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7946
7947 filter = proto_construct_match_selected_string(finfo, edt);
7948 if (filter) {
7949 /* Only add the same expression once (especially for FT_PROTOCOL).
7950 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7951 */
7952 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7953 g_ptr_array_add(filter_array, filter);
7954 }
7955 }
7956 i++;
7957 }
7958
7959 if (occurrence == 0) {
7960 /* Fetch next hfinfo with same name (abbrev) */
7961 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7962 } else {
7963 hfinfo = NULL((void*)0);
7964 }
7965 }
7966 }
7967
7968 g_ptr_array_add(filter_array, NULL((void*)0));
7969
7970 /* XXX: Should this be || or && ? */
7971 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7972
7973 g_ptr_array_free(filter_array, true1);
7974
7975 return output;
7976}
7977
7978/* Set text of proto_item after having already been created. */
7979void
7980proto_item_set_text(proto_item *pi, const char *format, ...)
7981{
7982 field_info *fi = NULL((void*)0);
7983 va_list ap;
7984
7985 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7986
7987 fi = PITEM_FINFO(pi)((pi)->finfo);
7988 if (fi == NULL((void*)0))
7989 return;
7990
7991 if (fi->rep) {
7992 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7993 fi->rep = NULL((void*)0);
7994 }
7995
7996 va_start(ap, format)__builtin_va_start(ap, format);
7997 proto_tree_set_representation(pi, format, ap);
7998 va_end(ap)__builtin_va_end(ap);
7999}
8000
8001/* Append to text of proto_item after having already been created. */
8002void
8003proto_item_append_text(proto_item *pi, const char *format, ...)
8004{
8005 field_info *fi = NULL((void*)0);
8006 size_t curlen;
8007 char *str;
8008 va_list ap;
8009
8010 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8011
8012 fi = PITEM_FINFO(pi)((pi)->finfo);
8013 if (fi == NULL((void*)0)) {
8014 return;
8015 }
8016
8017 if (!proto_item_is_hidden(pi)) {
8018 /*
8019 * If we don't already have a representation,
8020 * generate the default representation.
8021 */
8022 if (fi->rep == NULL((void*)0)) {
8023 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;
;
8024 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8025 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8026 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8027 (strncmp(format, ": ", 2) == 0)) {
8028 fi->rep->value_pos += 2;
8029 }
8030 }
8031 if (fi->rep) {
8032 curlen = strlen(fi->rep->representation);
8033 /* curlen doesn't include the \0 byte.
8034 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8035 * the representation has already been truncated (of an up
8036 * to 4 byte UTF-8 character) or is just at the maximum length
8037 * unless we search for " [truncated]" (which may not be
8038 * at the start.)
8039 * It's safer to do nothing.
8040 */
8041 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8042 va_start(ap, format)__builtin_va_start(ap, format);
8043 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8044 va_end(ap)__builtin_va_end(ap);
8045 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"
, 8045, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8046 /* Keep fi->rep->value_pos */
8047 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8048 if (curlen >= ITEM_LABEL_LENGTH240) {
8049 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8050 size_t name_pos = label_find_name_pos(fi->rep);
8051 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8052 }
8053 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8054 }
8055 }
8056 }
8057}
8058
8059/* Prepend to text of proto_item after having already been created. */
8060void
8061proto_item_prepend_text(proto_item *pi, const char *format, ...)
8062{
8063 field_info *fi = NULL((void*)0);
8064 size_t pos;
8065 char representation[ITEM_LABEL_LENGTH240];
8066 char *str;
8067 va_list ap;
8068
8069 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8070
8071 fi = PITEM_FINFO(pi)((pi)->finfo);
8072 if (fi == NULL((void*)0)) {
8073 return;
8074 }
8075
8076 if (!proto_item_is_hidden(pi)) {
8077 /*
8078 * If we don't already have a representation,
8079 * generate the default representation.
8080 */
8081 if (fi->rep == NULL((void*)0)) {
8082 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;
;
8083 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8084 } else
8085 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8086
8087 va_start(ap, format)__builtin_va_start(ap, format);
8088 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8089 va_end(ap)__builtin_va_end(ap);
8090 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"
, 8090, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8091 fi->rep->value_pos += strlen(str);
8092 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8093 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8094 /* XXX: As above, if the old representation is close to the label
8095 * length, it might already be marked as truncated. */
8096 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8097 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8098 size_t name_pos = label_find_name_pos(fi->rep);
8099 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8100 }
8101 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8102 }
8103}
8104
8105static void
8106finfo_set_len(field_info *fi, const unsigned length)
8107{
8108 unsigned length_remaining;
8109
8110 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8111 if (length > length_remaining)
8112 fi->length = length_remaining;
8113 else
8114 fi->length = length;
8115
8116 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8117 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8118 fvalue_set_protocol_length(fi->value, fi->length);
8119 }
8120
8121 /*
8122 * You cannot just make the "len" field of a GByteArray
8123 * larger, if there's no data to back that length;
8124 * you can only make it smaller.
8125 */
8126 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8127 GBytes *bytes = fvalue_get_bytes(fi->value);
8128 size_t size;
8129 const void *data = g_bytes_get_data(bytes, &size);
8130 if ((size_t)fi->length <= size) {
8131 fvalue_set_bytes_data(fi->value, data, fi->length);
8132 }
8133 g_bytes_unref(bytes);
8134 }
8135}
8136
8137void
8138proto_item_set_len(proto_item *pi, const unsigned length)
8139{
8140 field_info *fi;
8141
8142 if (pi == NULL((void*)0))
8143 return;
8144
8145 fi = PITEM_FINFO(pi)((pi)->finfo);
8146 if (fi == NULL((void*)0))
8147 return;
8148
8149 finfo_set_len(fi, length);
8150}
8151
8152/*
8153 * Sets the length of the item based on its start and on the specified
8154 * offset, which is the offset past the end of the item; as the start
8155 * in the item is relative to the beginning of the data source tvbuff,
8156 * we need to pass in a tvbuff - the end offset is relative to the beginning
8157 * of that tvbuff.
8158 */
8159void
8160proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8161{
8162 field_info *fi;
8163 unsigned length;
8164
8165 if (pi == NULL((void*)0))
8166 return;
8167
8168 fi = PITEM_FINFO(pi)((pi)->finfo);
8169 if (fi == NULL((void*)0))
8170 return;
8171
8172 if (G_LIKELY(tvb)(tvb)) {
8173 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"
, 8173, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8174 end += tvb_raw_offset(tvb);
8175 } else {
8176 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", 8176, "((void*)0) == fi->ds_tvb"
))))
;
8177 }
8178 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8178, "end >= fi->start"
))))
;
8179 length = end - fi->start;
8180
8181 finfo_set_len(fi, length);
8182}
8183
8184unsigned
8185proto_item_get_len(const proto_item *pi)
8186{
8187 /* XXX - The only use case where this is really guaranteed to work is
8188 * increasing the length of an item (which has no effect if the item
8189 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8190 *
8191 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8192 *
8193 * Should there be a macro or function to do that, and possibly this
8194 * be deprecated? As a bonus, we could handle overflow.
8195 */
8196 field_info *fi;
8197
8198 if (!pi)
8199 return 0;
8200 fi = PITEM_FINFO(pi)((pi)->finfo);
8201 if (fi) {
8202 return fi->length;
8203 }
8204 return 0;
8205}
8206
8207void
8208proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8209 if (!ti) {
8210 return;
8211 }
8212 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)
;
8213 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)
;
8214}
8215
8216char *
8217proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8218{
8219 field_info *fi;
8220
8221 if (!pi)
8222 return wmem_strdup(scope, "");
8223 fi = PITEM_FINFO(pi)((pi)->finfo);
8224 if (!fi)
8225 return wmem_strdup(scope, "");
8226 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8226, "fi->hfinfo != ((void*)0)"
))))
;
8227 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8228}
8229
8230proto_tree *
8231proto_tree_create_root(packet_info *pinfo)
8232{
8233 proto_node *pnode;
8234
8235 /* Initialize the proto_node */
8236 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8237 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8238 pnode->parent = NULL((void*)0);
8239 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8240 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)))
;
8241
8242 /* Make sure we can access pinfo everywhere */
8243 pnode->tree_data->pinfo = pinfo;
8244
8245 /* Don't initialize the tree_data_t. Wait until we know we need it */
8246 pnode->tree_data->interesting_hfids = NULL((void*)0);
8247
8248 /* Set the default to false so it's easier to
8249 * find errors; if we expect to see the protocol tree
8250 * but for some reason the default 'visible' is not
8251 * changed, then we'll find out very quickly. */
8252 pnode->tree_data->visible = false0;
8253
8254 /* Make sure that we fake protocols (if possible) */
8255 pnode->tree_data->fake_protocols = true1;
8256
8257 /* Keep track of the number of children */
8258 pnode->tree_data->count = 0;
8259
8260 /* Initialize our loop checks */
8261 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8262 pnode->tree_data->max_start = 0;
8263 pnode->tree_data->start_idle_count = 0;
8264
8265 return (proto_tree *)pnode;
8266}
8267
8268
8269/* "prime" a proto_tree with a single hfid that a dfilter
8270 * is interested in. */
8271void
8272proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8273{
8274 header_field_info *hfinfo;
8275
8276 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", 8276, __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", 8276, "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", 8276, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8277 /* this field is referenced by a filter so increase the refcount.
8278 also increase the refcount for the parent, i.e the protocol.
8279 Don't increase the refcount if we're already printing the
8280 type, as that is a superset of direct reference.
8281 */
8282 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8283 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8284 }
8285 /* only increase the refcount if there is a parent.
8286 if this is a protocol and not a field then parent will be -1
8287 and there is no parent to add any refcounting for.
8288 */
8289 if (hfinfo->parent != -1) {
8290 header_field_info *parent_hfinfo;
8291 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", 8291
, __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", 8291,
"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", 8291,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8292
8293 /* Mark parent as indirectly referenced unless it is already directly
8294 * referenced, i.e. the user has specified the parent in a filter.
8295 */
8296 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8297 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8298 }
8299}
8300
8301/* "prime" a proto_tree with a single hfid that a dfilter
8302 * is interested in. */
8303void
8304proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8305{
8306 header_field_info *hfinfo;
8307
8308 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", 8308, __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", 8308, "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", 8308, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8309 /* this field is referenced by an (output) filter so increase the refcount.
8310 also increase the refcount for the parent, i.e the protocol.
8311 */
8312 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8313 /* only increase the refcount if there is a parent.
8314 if this is a protocol and not a field then parent will be -1
8315 and there is no parent to add any refcounting for.
8316 */
8317 if (hfinfo->parent != -1) {
8318 header_field_info *parent_hfinfo;
8319 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", 8319
, __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", 8319,
"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", 8319,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8320
8321 /* Mark parent as indirectly referenced unless it is already directly
8322 * referenced, i.e. the user has specified the parent in a filter.
8323 */
8324 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8325 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8326 }
8327}
8328
8329proto_tree *
8330proto_item_add_subtree(proto_item *pi, const int idx) {
8331 field_info *fi;
8332
8333 if (!pi)
8334 return NULL((void*)0);
8335
8336 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", 8336, "idx >= 0 && idx < num_tree_types"
))))
;
8337
8338 fi = PITEM_FINFO(pi)((pi)->finfo);
8339 if (!fi)
8340 return (proto_tree *)pi;
8341
8342 fi->tree_type = idx;
8343
8344 return (proto_tree *)pi;
8345}
8346
8347proto_tree *
8348proto_item_get_subtree(proto_item *pi) {
8349 field_info *fi;
8350
8351 if (!pi)
8352 return NULL((void*)0);
8353 fi = PITEM_FINFO(pi)((pi)->finfo);
8354 if ( (fi) && (fi->tree_type == -1) )
8355 return NULL((void*)0);
8356 return (proto_tree *)pi;
8357}
8358
8359proto_item *
8360proto_item_get_parent(const proto_item *ti) {
8361 if (!ti)
8362 return NULL((void*)0);
8363 return ti->parent;
8364}
8365
8366proto_item *
8367proto_item_get_parent_nth(proto_item *ti, int gen) {
8368 if (!ti)
8369 return NULL((void*)0);
8370 while (gen--) {
8371 ti = ti->parent;
8372 if (!ti)
8373 return NULL((void*)0);
8374 }
8375 return ti;
8376}
8377
8378
8379proto_item *
8380proto_tree_get_parent(proto_tree *tree) {
8381 if (!tree)
8382 return NULL((void*)0);
8383 return (proto_item *)tree;
8384}
8385
8386proto_tree *
8387proto_tree_get_parent_tree(proto_tree *tree) {
8388 if (!tree)
8389 return NULL((void*)0);
8390
8391 /* we're the root tree, there's no parent
8392 return ourselves so the caller has at least a tree to attach to */
8393 if (!tree->parent)
8394 return tree;
8395
8396 return (proto_tree *)tree->parent;
8397}
8398
8399proto_tree *
8400proto_tree_get_root(proto_tree *tree) {
8401 if (!tree)
8402 return NULL((void*)0);
8403 while (tree->parent) {
8404 tree = tree->parent;
8405 }
8406 return tree;
8407}
8408
8409void
8410proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8411 proto_item *item_to_move)
8412{
8413 /* This function doesn't generate any values. It only reorganizes the protocol tree
8414 * so we can bail out immediately if it isn't visible. */
8415 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8416 return;
8417
8418 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", 8418, "item_to_move->parent == tree"
))))
;
8419 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", 8419, "fixed_item->parent == tree"
))))
;
8420
8421 /*** cut item_to_move out ***/
8422
8423 /* is item_to_move the first? */
8424 if (tree->first_child == item_to_move) {
8425 /* simply change first child to next */
8426 tree->first_child = item_to_move->next;
8427
8428 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", 8428, "tree->last_child != item_to_move"
))))
;
8429 } else {
8430 proto_item *curr_item;
8431 /* find previous and change it's next */
8432 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8433 if (curr_item->next == item_to_move) {
8434 break;
8435 }
8436 }
8437
8438 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8438, "curr_item"
))))
;
8439
8440 curr_item->next = item_to_move->next;
8441
8442 /* fix last_child if required */
8443 if (tree->last_child == item_to_move) {
8444 tree->last_child = curr_item;
8445 }
8446 }
8447
8448 /*** insert to_move after fixed ***/
8449 item_to_move->next = fixed_item->next;
8450 fixed_item->next = item_to_move;
8451 if (tree->last_child == fixed_item) {
8452 tree->last_child = item_to_move;
8453 }
8454}
8455
8456void
8457proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8458 const unsigned length)
8459{
8460 field_info *fi;
8461
8462 if (tree == NULL((void*)0))
8463 return;
8464
8465 fi = PTREE_FINFO(tree)((tree)->finfo);
8466 if (fi == NULL((void*)0))
8467 return;
8468
8469 /* We don't store a separate data source tvb for the appendix, so
8470 * it must be from the same data source. (XXX - Are there any
8471 * situations where it makes sense to have an appendix from a
8472 * different data source?) */
8473 if (G_LIKELY(tvb)(tvb)) {
8474 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"
, 8474, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8475 start += tvb_raw_offset(tvb);
8476 } else {
8477 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", 8477, "((void*)0) == fi->ds_tvb"
))))
;
8478 }
8479
8480 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8481 * main body? */
8482
8483 fi->appendix_start = start;
8484 fi->appendix_length = length;
8485}
8486
8487static void
8488check_protocol_filter_name_or_fail(const char *filter_name)
8489{
8490 /* Require at least two characters. */
8491 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8492 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)
;
8493 }
8494
8495 if (proto_check_field_name(filter_name) != '\0') {
8496 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)
8497 " 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)
8498 " 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)
;
8499 }
8500
8501 /* Check that it doesn't match some very common numeric forms. */
8502 if (filter_name[0] == '0' &&
8503 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8504 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8505 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])
8506 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])
;
8507 }
8508
8509 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8510
8511 /* Check that it contains at least one letter. */
8512 bool_Bool have_letter = false0;
8513 for (const char *s = filter_name; *s != '\0'; s++) {
8514 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8515 have_letter = true1;
8516 break;
8517 }
8518 }
8519 if (!have_letter) {
8520 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)
8521 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8522 }
8523
8524 /* Check for reserved keywords. */
8525 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8526 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)
8527 " 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)
;
8528 }
8529}
8530
8531int
8532proto_register_protocol(const char *name, const char *short_name,
8533 const char *filter_name)
8534{
8535 protocol_t *protocol;
8536 header_field_info *hfinfo;
8537
8538 check_protocol_filter_name_or_fail(filter_name);
8539
8540 /*
8541 * Add this protocol to the list of known protocols;
8542 * the list is sorted by protocol short name.
8543 */
8544 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8545 protocol->name = name;
8546 protocol->short_name = short_name;
8547 protocol->filter_name = filter_name;
8548 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8549 protocol->is_enabled = true1; /* protocol is enabled by default */
8550 protocol->enabled_by_default = true1; /* see previous comment */
8551 protocol->can_toggle = true1;
8552 protocol->parent_proto_id = -1;
8553 protocol->heur_list = NULL((void*)0);
8554
8555 /* List will be sorted later by name, when all protocols completed registering */
8556 protocols = g_list_prepend(protocols, protocol);
8557 /*
8558 * Make sure there's not already a protocol with any of those
8559 * names. Crash if there is, as that's an error in the code
8560 * or an inappropriate plugin.
8561 * This situation has to be fixed to not register more than one
8562 * protocol with the same name.
8563 */
8564 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8565 /* ws_error will terminate the program */
8566 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)
8567 " 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)
;
8568 }
8569 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8570 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)
8571 " 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)
;
8572 }
8573 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8574 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)
8575 " 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)
;
8576 }
8577
8578 /* Here we allocate a new header_field_info struct */
8579 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8580 hfinfo->name = name;
8581 hfinfo->abbrev = filter_name;
8582 hfinfo->type = FT_PROTOCOL;
8583 hfinfo->display = BASE_NONE;
8584 hfinfo->strings = protocol;
8585 hfinfo->bitmask = 0;
8586 hfinfo->ref_type = HF_REF_TYPE_NONE;
8587 hfinfo->blurb = NULL((void*)0);
8588 hfinfo->parent = -1; /* This field differentiates protos and fields */
8589
8590 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8591 return protocol->proto_id;
8592}
8593
8594int
8595proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8596{
8597 protocol_t *protocol;
8598 header_field_info *hfinfo;
8599
8600 /*
8601 * Helper protocols don't need the strict rules as a "regular" protocol
8602 * Just register it in a list and make a hf_ field from it
8603 */
8604 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8605 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)
;
8606 }
8607
8608 if (parent_proto <= 0) {
8609 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)
8610 " 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)
;
8611 }
8612
8613 check_protocol_filter_name_or_fail(filter_name);
8614
8615 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8616 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8617 protocol->name = name;
8618 protocol->short_name = short_name;
8619 protocol->filter_name = filter_name;
8620 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8621
8622 /* Enabling and toggling is really determined by parent protocol,
8623 but provide default values here */
8624 protocol->is_enabled = true1;
8625 protocol->enabled_by_default = true1;
8626 protocol->can_toggle = true1;
8627
8628 protocol->parent_proto_id = parent_proto;
8629 protocol->heur_list = NULL((void*)0);
8630
8631 /* List will be sorted later by name, when all protocols completed registering */
8632 protocols = g_list_prepend(protocols, protocol);
8633
8634 /* Here we allocate a new header_field_info struct */
8635 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8636 hfinfo->name = name;
8637 hfinfo->abbrev = filter_name;
8638 hfinfo->type = field_type;
8639 hfinfo->display = BASE_NONE;
8640 if (field_type == FT_BYTES) {
8641 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8642 }
8643 hfinfo->strings = protocol;
8644 hfinfo->bitmask = 0;
8645 hfinfo->ref_type = HF_REF_TYPE_NONE;
8646 hfinfo->blurb = NULL((void*)0);
8647 hfinfo->parent = -1; /* This field differentiates protos and fields */
8648
8649 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8650 return protocol->proto_id;
8651}
8652
8653bool_Bool
8654proto_deregister_protocol(const char *short_name)
8655{
8656 protocol_t *protocol;
8657 header_field_info *hfinfo;
8658 int proto_id;
8659 unsigned i;
8660
8661 proto_id = proto_get_id_by_short_name(short_name);
8662 protocol = find_protocol_by_id(proto_id);
8663 if (protocol == NULL((void*)0))
8664 return false0;
8665
8666 g_hash_table_remove(proto_names, protocol->name);
8667 g_hash_table_remove(proto_short_names, (void *)short_name);
8668 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8669
8670 if (protocol->fields) {
8671 for (i = 0; i < protocol->fields->len; i++) {
8672 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8673 hfinfo_remove_from_gpa_name_map(hfinfo);
8674 expert_deregister_expertinfo(hfinfo->abbrev);
8675 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8676 }
8677 g_ptr_array_free(protocol->fields, true1);
8678 protocol->fields = NULL((void*)0);
8679 }
8680
8681 g_list_free(protocol->heur_list);
8682
8683 /* Remove this protocol from the list of known protocols */
8684 protocols = g_list_remove(protocols, protocol);
8685
8686 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8687 wmem_map_remove(gpa_name_map, protocol->filter_name);
8688
8689 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)
;
8690 last_field_name = NULL((void*)0);
8691
8692 return true1;
8693}
8694
8695void
8696proto_register_alias(const int proto_id, const char *alias_name)
8697{
8698 protocol_t *protocol;
8699
8700 protocol = find_protocol_by_id(proto_id);
8701 if (alias_name && protocol) {
8702 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8703 }
8704}
8705
8706/*
8707 * Routines to use to iterate over the protocols.
8708 * The argument passed to the iterator routines is an opaque cookie to
8709 * their callers; it's the GList pointer for the current element in
8710 * the list.
8711 * The ID of the protocol is returned, or -1 if there is no protocol.
8712 */
8713int
8714proto_get_first_protocol(void **cookie)
8715{
8716 protocol_t *protocol;
8717
8718 if (protocols == NULL((void*)0))
8719 return -1;
8720 *cookie = protocols;
8721 protocol = (protocol_t *)protocols->data;
8722 return protocol->proto_id;
8723}
8724
8725int
8726proto_get_data_protocol(void *cookie)
8727{
8728 GList *list_item = (GList *)cookie;
8729
8730 protocol_t *protocol = (protocol_t *)list_item->data;
8731 return protocol->proto_id;
8732}
8733
8734int
8735proto_get_next_protocol(void **cookie)
8736{
8737 GList *list_item = (GList *)*cookie;
8738 protocol_t *protocol;
8739
8740 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8741 if (list_item == NULL((void*)0))
8742 return -1;
8743 *cookie = list_item;
8744 protocol = (protocol_t *)list_item->data;
8745 return protocol->proto_id;
8746}
8747
8748header_field_info *
8749proto_get_first_protocol_field(const int proto_id, void **cookie)
8750{
8751 protocol_t *protocol = find_protocol_by_id(proto_id);
8752
8753 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8754 return NULL((void*)0);
8755
8756 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8757 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8758}
8759
8760header_field_info *
8761proto_get_next_protocol_field(const int proto_id, void **cookie)
8762{
8763 protocol_t *protocol = find_protocol_by_id(proto_id);
8764 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8765
8766 i++;
8767
8768 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8769 return NULL((void*)0);
8770
8771 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8772 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8773}
8774
8775protocol_t *
8776find_protocol_by_id(const int proto_id)
8777{
8778 header_field_info *hfinfo;
8779
8780 if (proto_id <= 0)
8781 return NULL((void*)0);
8782
8783 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", 8783, __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", 8783,
"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", 8783, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8784 if (hfinfo->type != FT_PROTOCOL) {
8785 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", 8785, "hfinfo->display & 0x00004000"
))))
;
8786 }
8787 return (protocol_t *)hfinfo->strings;
8788}
8789
8790int
8791proto_get_id(const protocol_t *protocol)
8792{
8793 return protocol->proto_id;
8794}
8795
8796bool_Bool
8797proto_name_already_registered(const char *name)
8798{
8799 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8799, "name", "No name present"))))
;
8800
8801 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8802 return true1;
8803 return false0;
8804}
8805
8806int
8807proto_get_id_by_filter_name(const char *filter_name)
8808{
8809 const protocol_t *protocol = NULL((void*)0);
8810
8811 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", 8811,
"filter_name", "No filter name present"))))
;
8812
8813 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8814
8815 if (protocol == NULL((void*)0))
8816 return -1;
8817 return protocol->proto_id;
8818}
8819
8820int
8821proto_get_id_by_short_name(const char *short_name)
8822{
8823 const protocol_t *protocol = NULL((void*)0);
8824
8825 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", 8825,
"short_name", "No short name present"))))
;
8826
8827 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8828
8829 if (protocol == NULL((void*)0))
8830 return -1;
8831 return protocol->proto_id;
8832}
8833
8834const char *
8835proto_get_protocol_name(const int proto_id)
8836{
8837 protocol_t *protocol;
8838
8839 protocol = find_protocol_by_id(proto_id);
8840
8841 if (protocol == NULL((void*)0))
8842 return NULL((void*)0);
8843 return protocol->name;
8844}
8845
8846const char *
8847proto_get_protocol_short_name(const protocol_t *protocol)
8848{
8849 if (protocol == NULL((void*)0))
8850 return "(none)";
8851 return protocol->short_name;
8852}
8853
8854const char *
8855proto_get_protocol_long_name(const protocol_t *protocol)
8856{
8857 if (protocol == NULL((void*)0))
8858 return "(none)";
8859 return protocol->name;
8860}
8861
8862const char *
8863proto_get_protocol_filter_name(const int proto_id)
8864{
8865 protocol_t *protocol;
8866
8867 protocol = find_protocol_by_id(proto_id);
8868 if (protocol == NULL((void*)0))
8869 return "(none)";
8870 return protocol->filter_name;
8871}
8872
8873void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8874{
8875 heur_dtbl_entry_t* heuristic_dissector;
8876
8877 if (protocol == NULL((void*)0))
8878 return;
8879
8880 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8881 if (heuristic_dissector != NULL((void*)0))
8882 {
8883 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8884 }
8885}
8886
8887void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8888{
8889 if (protocol == NULL((void*)0))
8890 return;
8891
8892 g_list_foreach(protocol->heur_list, func, user_data);
8893}
8894
8895void
8896proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8897 bool_Bool *is_tcp, bool_Bool *is_udp,
8898 bool_Bool *is_sctp, bool_Bool *is_tls,
8899 bool_Bool *is_rtp,
8900 bool_Bool *is_lte_rlc)
8901{
8902 wmem_list_frame_t *protos = wmem_list_head(layers);
8903 int proto_id;
8904 const char *proto_name;
8905
8906 /* Walk the list of a available protocols in the packet and
8907 attempt to find "major" ones. */
8908 /* It might make more sense to assemble and return a bitfield. */
8909 while (protos != NULL((void*)0))
8910 {
8911 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8912 proto_name = proto_get_protocol_filter_name(proto_id);
8913
8914 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8915 (!strcmp(proto_name, "ipv6")))) {
8916 *is_ip = true1;
8917 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8918 *is_tcp = true1;
8919 } else if (is_udp && !strcmp(proto_name, "udp")) {
8920 *is_udp = true1;
8921 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8922 *is_sctp = true1;
8923 } else if (is_tls && !strcmp(proto_name, "tls")) {
8924 *is_tls = true1;
8925 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8926 *is_rtp = true1;
8927 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8928 *is_lte_rlc = true1;
8929 }
8930
8931 protos = wmem_list_frame_next(protos);
8932 }
8933}
8934
8935bool_Bool
8936proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8937{
8938 wmem_list_frame_t *protos = wmem_list_head(layers);
8939 int proto_id;
8940 const char *name;
8941
8942 /* Walk the list of a available protocols in the packet and
8943 attempt to find the specified protocol. */
8944 while (protos != NULL((void*)0))
8945 {
8946 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8947 name = proto_get_protocol_filter_name(proto_id);
8948
8949 if (!strcmp(name, proto_name))
8950 {
8951 return true1;
8952 }
8953
8954 protos = wmem_list_frame_next(protos);
8955 }
8956
8957 return false0;
8958}
8959
8960char *
8961proto_list_layers(const packet_info *pinfo)
8962{
8963 wmem_strbuf_t *buf;
8964 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8965
8966 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8967
8968 /* Walk the list of layers in the packet and
8969 return a string of all entries. */
8970 while (layers != NULL((void*)0))
8971 {
8972 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8973
8974 layers = wmem_list_frame_next(layers);
8975 if (layers != NULL((void*)0)) {
8976 wmem_strbuf_append_c(buf, ':');
8977 }
8978 }
8979
8980 return wmem_strbuf_finalize(buf);
8981}
8982
8983uint8_t
8984proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8985{
8986 int *proto_layer_num_ptr;
8987
8988 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8989 if (proto_layer_num_ptr == NULL((void*)0)) {
8990 return 0;
8991 }
8992
8993 return (uint8_t)*proto_layer_num_ptr;
8994}
8995
8996bool_Bool
8997proto_is_pino(const protocol_t *protocol)
8998{
8999 return (protocol->parent_proto_id != -1);
9000}
9001
9002bool_Bool
9003// NOLINTNEXTLINE(misc-no-recursion)
9004proto_is_protocol_enabled(const protocol_t *protocol)
9005{
9006 if (protocol == NULL((void*)0))
9007 return false0;
9008
9009 //parent protocol determines enable/disable for helper dissectors
9010 if (proto_is_pino(protocol))
9011 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9012
9013 return protocol->is_enabled;
9014}
9015
9016bool_Bool
9017// NOLINTNEXTLINE(misc-no-recursion)
9018proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9019{
9020 //parent protocol determines enable/disable for helper dissectors
9021 if (proto_is_pino(protocol))
9022 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9023
9024 return protocol->enabled_by_default;
9025}
9026
9027bool_Bool
9028// NOLINTNEXTLINE(misc-no-recursion)
9029proto_can_toggle_protocol(const int proto_id)
9030{
9031 protocol_t *protocol;
9032
9033 protocol = find_protocol_by_id(proto_id);
9034 //parent protocol determines toggling for helper dissectors
9035 if (proto_is_pino(protocol))
9036 return proto_can_toggle_protocol(protocol->parent_proto_id);
9037
9038 return protocol->can_toggle;
9039}
9040
9041void
9042proto_disable_by_default(const int proto_id)
9043{
9044 protocol_t *protocol;
9045
9046 protocol = find_protocol_by_id(proto_id);
9047 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9047, "protocol->can_toggle"
))))
;
9048 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", 9048, "proto_is_pino(protocol) == 0"
))))
;
9049 protocol->is_enabled = false0;
9050 protocol->enabled_by_default = false0;
9051}
9052
9053void
9054proto_set_decoding(const int proto_id, const bool_Bool enabled)
9055{
9056 protocol_t *protocol;
9057
9058 protocol = find_protocol_by_id(proto_id);
9059 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9059, "protocol->can_toggle"
))))
;
9060 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", 9060, "proto_is_pino(protocol) == 0"
))))
;
9061 protocol->is_enabled = enabled;
9062}
9063
9064void
9065proto_disable_all(void)
9066{
9067 /* This doesn't explicitly disable heuristic protocols,
9068 * but the heuristic doesn't get called if the parent
9069 * protocol isn't enabled.
9070 */
9071 protocol_t *protocol;
9072 GList *list_item = protocols;
9073
9074 if (protocols == NULL((void*)0))
9075 return;
9076
9077 while (list_item) {
9078 protocol = (protocol_t *)list_item->data;
9079 if (protocol->can_toggle) {
9080 protocol->is_enabled = false0;
9081 }
9082 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9083 }
9084}
9085
9086static void
9087heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9088{
9089 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9090
9091 heur->enabled = heur->enabled_by_default;
9092}
9093
9094void
9095proto_reenable_all(void)
9096{
9097 protocol_t *protocol;
9098 GList *list_item = protocols;
9099
9100 if (protocols == NULL((void*)0))
9101 return;
9102
9103 while (list_item) {
9104 protocol = (protocol_t *)list_item->data;
9105 if (protocol->can_toggle)
9106 protocol->is_enabled = protocol->enabled_by_default;
9107 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9108 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9109 }
9110}
9111
9112void
9113proto_set_cant_toggle(const int proto_id)
9114{
9115 protocol_t *protocol;
9116
9117 protocol = find_protocol_by_id(proto_id);
9118 protocol->can_toggle = false0;
9119}
9120
9121static int
9122proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9123{
9124 g_ptr_array_add(proto->fields, hfi);
9125
9126 return proto_register_field_init(hfi, parent);
9127}
9128
9129/* for use with static arrays only, since we don't allocate our own copies
9130of the header_field_info struct contained within the hf_register_info struct */
9131void
9132proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9133{
9134 hf_register_info *ptr = hf;
9135 protocol_t *proto;
9136 int i;
9137
9138 proto = find_protocol_by_id(parent);
9139
9140 /* if (proto == NULL) - error or return? */
9141
9142 if (proto->fields == NULL((void*)0)) {
9143 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9144 * GLib introduced g_ptr_array_new_from_array, which might have
9145 * given a reason to actually use it. (#17774)
9146 */
9147 proto->fields = g_ptr_array_sized_new(num_records);
9148 }
9149
9150 for (i = 0; i < num_records; i++, ptr++) {
9151 /*
9152 * Make sure we haven't registered this yet.
9153 * Most fields have variables associated with them that
9154 * are initialized to 0; some are initialized to -1 (which
9155 * was the standard before 4.4).
9156 *
9157 * XXX - Since this is called almost 300000 times at startup,
9158 * it might be nice to compare to only 0 and require
9159 * dissectors to pass in zero for unregistered fields.
9160 */
9161 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9162 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9163 "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)
9164 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9165 return;
9166 }
9167
9168 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9169 }
9170}
9171
9172/* deregister already registered fields */
9173void
9174proto_deregister_field (const int parent, int hf_id)
9175{
9176 header_field_info *hfi;
9177 protocol_t *proto;
9178 unsigned i;
9179
9180 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)
;
9181 last_field_name = NULL((void*)0);
9182
9183 if (hf_id == -1 || hf_id == 0)
9184 return;
9185
9186 proto = find_protocol_by_id (parent);
9187 if (!proto || proto->fields == NULL((void*)0)) {
9188 return;
9189 }
9190
9191 for (i = 0; i < proto->fields->len; i++) {
9192 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9193 if (hfi->id == hf_id) {
9194 /* Found the hf_id in this protocol */
9195 wmem_map_remove(gpa_name_map, hfi->abbrev);
9196 g_ptr_array_remove_index_fast(proto->fields, i);
9197 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9198 return;
9199 }
9200 }
9201}
9202
9203/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9204void
9205proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9206{
9207 header_field_info *hfinfo;
9208 protocol_t *proto;
9209
9210 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)
;
9211 last_field_name = NULL((void*)0);
9212
9213 proto = find_protocol_by_id(parent);
9214 if (proto && proto->fields && proto->fields->len > 0) {
9215 unsigned i = proto->fields->len;
9216 do {
9217 i--;
9218
9219 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9220 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) )
) {
9221 hfinfo_remove_from_gpa_name_map(hfinfo);
9222 expert_deregister_expertinfo(hfinfo->abbrev);
9223 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9224 g_ptr_array_remove_index_fast(proto->fields, i);
9225 }
9226 } while (i > 0);
9227 }
9228}
9229
9230void
9231proto_add_deregistered_data (void *data)
9232{
9233 g_ptr_array_add(deregistered_data, data);
9234}
9235
9236void
9237proto_add_deregistered_slice (size_t block_size, void *mem_block)
9238{
9239 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)))
;
9240
9241 slice_data->block_size = block_size;
9242 slice_data->mem_block = mem_block;
9243
9244 g_ptr_array_add(deregistered_slice, slice_data);
9245}
9246
9247void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9248{
9249 if (field_strings == NULL((void*)0)) {
9250 return;
9251 }
9252
9253 switch (field_type) {
9254 case FT_FRAMENUM:
9255 /* This is just an integer represented as a pointer */
9256 break;
9257 case FT_PROTOCOL: {
9258 protocol_t *protocol = (protocol_t *)field_strings;
9259 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)
;
9260 break;
9261 }
9262 case FT_BOOLEAN: {
9263 true_false_string *tf = (true_false_string *)field_strings;
9264 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)
;
9265 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)
;
9266 break;
9267 }
9268 case FT_UINT40:
9269 case FT_INT40:
9270 case FT_UINT48:
9271 case FT_INT48:
9272 case FT_UINT56:
9273 case FT_INT56:
9274 case FT_UINT64:
9275 case FT_INT64: {
9276 if (field_display & BASE_UNIT_STRING0x00001000) {
9277 unit_name_string *unit = (unit_name_string *)field_strings;
9278 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)
;
9279 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)
;
9280 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9281 range_string *rs = (range_string *)field_strings;
9282 while (rs->strptr) {
9283 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
)
;
9284 rs++;
9285 }
9286 } else if (field_display & BASE_EXT_STRING0x00000200) {
9287 val64_string_ext *vse = (val64_string_ext *)field_strings;
9288 val64_string *vs = (val64_string *)vse->_vs_p;
9289 while (vs->strptr) {
9290 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
)
;
9291 vs++;
9292 }
9293 val64_string_ext_free(vse);
9294 field_strings = NULL((void*)0);
9295 } else if (field_display == BASE_CUSTOM) {
9296 /* this will be a pointer to a function, don't free that */
9297 field_strings = NULL((void*)0);
9298 } else {
9299 val64_string *vs64 = (val64_string *)field_strings;
9300 while (vs64->strptr) {
9301 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)
;
9302 vs64++;
9303 }
9304 }
9305 break;
9306 }
9307 case FT_CHAR:
9308 case FT_UINT8:
9309 case FT_INT8:
9310 case FT_UINT16:
9311 case FT_INT16:
9312 case FT_UINT24:
9313 case FT_INT24:
9314 case FT_UINT32:
9315 case FT_INT32:
9316 case FT_FLOAT:
9317 case FT_DOUBLE: {
9318 if (field_display & BASE_UNIT_STRING0x00001000) {
9319 unit_name_string *unit = (unit_name_string *)field_strings;
9320 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)
;
9321 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)
;
9322 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9323 range_string *rs = (range_string *)field_strings;
9324 while (rs->strptr) {
9325 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
)
;
9326 rs++;
9327 }
9328 } else if (field_display & BASE_EXT_STRING0x00000200) {
9329 value_string_ext *vse = (value_string_ext *)field_strings;
9330 value_string *vs = (value_string *)vse->_vs_p;
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 value_string_ext_free(vse);
9336 field_strings = NULL((void*)0);
9337 } else if (field_display == BASE_CUSTOM) {
9338 /* this will be a pointer to a function, don't free that */
9339 field_strings = NULL((void*)0);
9340 } else {
9341 value_string *vs = (value_string *)field_strings;
9342 while (vs->strptr) {
9343 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
)
;
9344 vs++;
9345 }
9346 }
9347 break;
9348 default:
9349 break;
9350 }
9351 }
9352
9353 if (field_type != FT_FRAMENUM) {
9354 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
)
;
9355 }
9356}
9357
9358static void
9359free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9360{
9361 header_field_info *hfi = (header_field_info *) data;
9362 int hf_id = hfi->id;
9363
9364 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
)
;
9365 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
)
;
9366 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
)
;
9367
9368 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9369
9370 if (hfi->parent == -1)
9371 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)
;
9372
9373 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9374}
9375
9376static void
9377free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9378{
9379 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9380}
9381
9382static void
9383free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9384{
9385 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9386
9387 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9388 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)
;
9389}
9390
9391/* free deregistered fields and data */
9392void
9393proto_free_deregistered_fields (void)
9394{
9395 expert_free_deregistered_expertinfos();
9396
9397 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9398 g_ptr_array_free(deregistered_fields, true1);
9399 deregistered_fields = g_ptr_array_new();
9400
9401 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9402 g_ptr_array_free(deregistered_data, true1);
9403 deregistered_data = g_ptr_array_new();
9404
9405 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9406 g_ptr_array_free(deregistered_slice, true1);
9407 deregistered_slice = g_ptr_array_new();
9408}
9409
9410static const value_string hf_display[] = {
9411 { BASE_NONE, "BASE_NONE" },
9412 { BASE_DEC, "BASE_DEC" },
9413 { BASE_HEX, "BASE_HEX" },
9414 { BASE_OCT, "BASE_OCT" },
9415 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9416 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9417 { BASE_CUSTOM, "BASE_CUSTOM" },
9418 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9419 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9420 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9421 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9422 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9423 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9424 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9425 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9426 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9427 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9428 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9429 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9430 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9431 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9432 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9433 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9434 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9435 { BASE_PT_UDP, "BASE_PT_UDP" },
9436 { BASE_PT_TCP, "BASE_PT_TCP" },
9437 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9438 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9439 { BASE_OUI, "BASE_OUI" },
9440 { 0, NULL((void*)0) } };
9441
9442const char* proto_field_display_to_string(int field_display)
9443{
9444 return val_to_str_const(field_display, hf_display, "Unknown");
9445}
9446
9447static inline port_type
9448display_to_port_type(field_display_e e)
9449{
9450 switch (e) {
9451 case BASE_PT_UDP:
9452 return PT_UDP;
9453 case BASE_PT_TCP:
9454 return PT_TCP;
9455 case BASE_PT_DCCP:
9456 return PT_DCCP;
9457 case BASE_PT_SCTP:
9458 return PT_SCTP;
9459 default:
9460 break;
9461 }
9462 return PT_NONE;
9463}
9464
9465/* temporary function containing assert part for easier profiling */
9466static void
9467tmp_fld_check_assert(header_field_info *hfinfo)
9468{
9469 char* tmp_str;
9470
9471 /* The field must have a name (with length > 0) */
9472 if (!hfinfo->name || !hfinfo->name[0]) {
9473 if (hfinfo->abbrev)
9474 /* Try to identify the field */
9475 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)
9476 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9477 else
9478 /* Hum, no luck */
9479 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)"
)
;
9480 }
9481
9482 /* fields with an empty string for an abbreviation aren't filterable */
9483 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9484 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)
;
9485
9486 /* TODO: This check is a significant percentage of startup time (~10%),
9487 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9488 It might be nice to have a way to disable this check when, e.g.,
9489 running TShark many times with the same configuration. */
9490 /* Check that the filter name (abbreviation) is legal;
9491 * it must contain only alphanumerics, '-', "_", and ".". */
9492 unsigned char c;
9493 c = module_check_valid_name(hfinfo->abbrev, false0);
9494 if (c) {
9495 if (c == '.') {
9496 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)
;
9497 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9498 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)
;
9499 } else {
9500 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)
;
9501 }
9502 }
9503
9504 /* These types of fields are allowed to have value_strings,
9505 * true_false_strings or a protocol_t struct
9506 */
9507 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9508 switch (hfinfo->type) {
9509
9510 /*
9511 * These types are allowed to support display value_strings,
9512 * value64_strings, the extended versions of the previous
9513 * two, range strings, or unit strings.
9514 */
9515 case FT_CHAR:
9516 case FT_UINT8:
9517 case FT_UINT16:
9518 case FT_UINT24:
9519 case FT_UINT32:
9520 case FT_UINT40:
9521 case FT_UINT48:
9522 case FT_UINT56:
9523 case FT_UINT64:
9524 case FT_INT8:
9525 case FT_INT16:
9526 case FT_INT24:
9527 case FT_INT32:
9528 case FT_INT40:
9529 case FT_INT48:
9530 case FT_INT56:
9531 case FT_INT64:
9532 case FT_BOOLEAN:
9533 case FT_PROTOCOL:
9534 break;
9535
9536 /*
9537 * This is allowed to have a value of type
9538 * enum ft_framenum_type to indicate what relationship
9539 * the frame in question has to the frame in which
9540 * the field is put.
9541 */
9542 case FT_FRAMENUM:
9543 break;
9544
9545 /*
9546 * These types are allowed to support only unit strings.
9547 */
9548 case FT_FLOAT:
9549 case FT_DOUBLE:
9550 case FT_IEEE_11073_SFLOAT:
9551 case FT_IEEE_11073_FLOAT:
9552 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9553 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))
9554 " (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))
9555 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))
;
9556 }
9557 break;
9558
9559 /*
9560 * These types are allowed to support display
9561 * time_value_strings.
9562 */
9563 case FT_ABSOLUTE_TIME:
9564 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9565 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9566 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9567 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9568 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))
9569 " (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))
9570 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))
;
9571 }
9572 break;
9573
9574 /*
9575 * This type is only allowed to support a string if it's
9576 * a protocol (for pinos).
9577 */
9578 case FT_BYTES:
9579 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9580 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))
9581 " (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))
9582 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))
;
9583 }
9584 break;
9585
9586 default:
9587 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))
9588 " (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))
9589 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))
;
9590 }
9591 }
9592
9593 /* TODO: This check may slow down startup, and output quite a few warnings.
9594 It would be good to be able to enable this (and possibly other checks?)
9595 in non-release builds. */
9596#ifdef ENABLE_CHECK_FILTER
9597 /* Check for duplicate value_string values.
9598 There are lots that have the same value *and* string, so for now only
9599 report those that have same value but different string. */
9600 if ((hfinfo->strings != NULL((void*)0)) &&
9601 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9602 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9603 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9604 (
9605 (hfinfo->type == FT_CHAR) ||
9606 (hfinfo->type == FT_UINT8) ||
9607 (hfinfo->type == FT_UINT16) ||
9608 (hfinfo->type == FT_UINT24) ||
9609 (hfinfo->type == FT_UINT32) ||
9610 (hfinfo->type == FT_INT8) ||
9611 (hfinfo->type == FT_INT16) ||
9612 (hfinfo->type == FT_INT24) ||
9613 (hfinfo->type == FT_INT32) )) {
9614
9615 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9616 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9617 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9618 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9619 } else {
9620 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9621 CHECK_HF_VALUE(value_string, "u", start_values);
9622 }
9623 } else {
9624 const value_string *start_values = (const value_string*)hfinfo->strings;
9625 CHECK_HF_VALUE(value_string, "u", start_values);
9626 }
9627 }
9628
9629 if (hfinfo->type == FT_BOOLEAN) {
9630 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9631 if (tfs) {
9632 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9633 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9635
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9634 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9635
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9635 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9635
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9636 }
9637 }
9638 }
9639
9640 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9641 const range_string *rs = (const range_string*)(hfinfo->strings);
9642 if (rs) {
9643 const range_string *this_it = rs;
9644
9645 do {
9646 if (this_it->value_max < this_it->value_min) {
9647 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"
, 9651, __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)
9648 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9651, __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)
9649 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9651, __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)
9650 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9651, __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)
9651 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9651, __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)
;
9652 ++this_it;
9653 continue;
9654 }
9655
9656 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9657 /* Not OK if this one is completely hidden by an earlier one! */
9658 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9659 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"
, 9665, __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)
9660 "(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"
, 9665, __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)
9661 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9665, __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)
9662 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9665, __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)
9663 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9665, __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)
9664 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9665, __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)
9665 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9665, __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)
;
9666 }
9667 }
9668 ++this_it;
9669 } while (this_it->strptr);
9670 }
9671 }
9672#endif
9673
9674 switch (hfinfo->type) {
9675
9676 case FT_CHAR:
9677 /* Require the char type to have BASE_HEX, BASE_OCT,
9678 * BASE_CUSTOM, or BASE_NONE as its base.
9679 *
9680 * If the display value is BASE_NONE and there is a
9681 * strings conversion then the dissector writer is
9682 * telling us that the field's numerical value is
9683 * meaningless; we'll avoid showing the value to the
9684 * user.
9685 */
9686 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9687 case BASE_HEX:
9688 case BASE_OCT:
9689 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9690 break;
9691 case BASE_NONE:
9692 if (hfinfo->strings == NULL((void*)0))
9693 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
))
9694 " 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
))
9695 " 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
))
9696 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
))
9697 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
))
;
9698 break;
9699 default:
9700 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9701 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)
9702 " 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)
9703 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)
9704 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)
;
9705 //wmem_free(NULL, tmp_str);
9706 }
9707 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9708 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
))
9709 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
))
9710 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
))
;
9711 }
9712 break;
9713 case FT_INT8:
9714 case FT_INT16:
9715 case FT_INT24:
9716 case FT_INT32:
9717 case FT_INT40:
9718 case FT_INT48:
9719 case FT_INT56:
9720 case FT_INT64:
9721 /* Hexadecimal and octal are, in printf() and everywhere
9722 * else, unsigned so don't allow dissectors to register a
9723 * signed field to be displayed unsigned. (Else how would
9724 * we display negative values?)
9725 */
9726 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9727 case BASE_HEX:
9728 case BASE_OCT:
9729 case BASE_DEC_HEX:
9730 case BASE_HEX_DEC:
9731 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9732 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)
9733 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)
9734 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)
;
9735 //wmem_free(NULL, tmp_str);
9736 }
9737 /* FALL THROUGH */
9738 case FT_UINT8:
9739 case FT_UINT16:
9740 case FT_UINT24:
9741 case FT_UINT32:
9742 case FT_UINT40:
9743 case FT_UINT48:
9744 case FT_UINT56:
9745 case FT_UINT64:
9746 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
))
) {
9747 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9748 if (hfinfo->type != FT_UINT16) {
9749 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))
9750 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))
9751 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))
;
9752 }
9753 if (hfinfo->strings != NULL((void*)0)) {
9754 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)
9755 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)
9756 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)
;
9757 }
9758 if (hfinfo->bitmask != 0) {
9759 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)
9760 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)
9761 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)
;
9762 }
9763 wmem_free(NULL((void*)0), tmp_str);
9764 break;
9765 }
9766
9767 if (hfinfo->display == BASE_OUI) {
9768 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9769 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) {
9770 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))
9771 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))
9772 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))
;
9773 }
9774 if (hfinfo->strings != NULL((void*)0)) {
9775 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)
9776 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)
9777 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)
;
9778 }
9779 /* It can be a FT_UINT24 with a 0 bitmask, or
9780 * larger with a bitmask with 24 bits set. */
9781 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9782 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)
9783 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)
9784 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)
;
9785 }
9786 wmem_free(NULL((void*)0), tmp_str);
9787 break;
9788 }
9789
9790 /* Require integral types (other than frame number,
9791 * which is always displayed in decimal) to have a
9792 * number base.
9793 *
9794 * If the display value is BASE_NONE and there is a
9795 * strings conversion then the dissector writer is
9796 * telling us that the field's numerical value is
9797 * meaningless; we'll avoid showing the value to the
9798 * user.
9799 */
9800 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9801 case BASE_DEC:
9802 case BASE_HEX:
9803 case BASE_OCT:
9804 case BASE_DEC_HEX:
9805 case BASE_HEX_DEC:
9806 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9807 break;
9808 case BASE_NONE:
9809 if (hfinfo->strings == NULL((void*)0)) {
9810 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
))
9811 " 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
))
9812 " 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
))
9813 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
))
9814 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
))
;
9815 }
9816 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9817 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
))
9818 " 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
))
9819 " 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
))
9820 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
))
9821 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
))
;
9822 }
9823 break;
9824
9825 default:
9826 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9827 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)
9828 " 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)
9829 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)
9830 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)
;
9831 //wmem_free(NULL, tmp_str);
9832 }
9833 break;
9834 case FT_BYTES:
9835 case FT_UINT_BYTES:
9836 /* Require bytes to have a "display type" that could
9837 * add a character between displayed bytes.
9838 */
9839 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9840 case BASE_NONE:
9841 case SEP_DOT:
9842 case SEP_DASH:
9843 case SEP_COLON:
9844 case SEP_SPACE:
9845 break;
9846 default:
9847 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9848 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)
9849 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)
;
9850 //wmem_free(NULL, tmp_str);
9851 }
9852 if (hfinfo->bitmask != 0)
9853 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
))
9854 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
))
9855 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
))
;
9856 //allowed to support string if its a protocol (for pinos)
9857 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9858 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
))
9859 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
))
9860 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
))
;
9861 break;
9862
9863 case FT_PROTOCOL:
9864 case FT_FRAMENUM:
9865 if (hfinfo->display != BASE_NONE) {
9866 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9867 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)
9868 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)
9869 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)
;
9870 //wmem_free(NULL, tmp_str);
9871 }
9872 if (hfinfo->bitmask != 0)
9873 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
))
9874 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
))
9875 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
))
;
9876 break;
9877
9878 case FT_BOOLEAN:
9879 break;
9880
9881 case FT_ABSOLUTE_TIME:
9882 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9883 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9884 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)
9885 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)
;
9886 //wmem_free(NULL, tmp_str);
9887 }
9888 if (hfinfo->bitmask != 0)
9889 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
))
9890 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
))
9891 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
))
;
9892 break;
9893
9894 case FT_STRING:
9895 case FT_STRINGZ:
9896 case FT_UINT_STRING:
9897 case FT_STRINGZPAD:
9898 case FT_STRINGZTRUNC:
9899 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9900 case BASE_NONE:
9901 case BASE_STR_WSP:
9902 break;
9903
9904 default:
9905 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9906 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)
9907 " 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)
9908 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)
9909 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)
;
9910 //wmem_free(NULL, tmp_str);
9911 }
9912
9913 if (hfinfo->bitmask != 0)
9914 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
))
9915 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
))
9916 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
))
;
9917 if (hfinfo->strings != NULL((void*)0))
9918 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
))
9919 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
))
9920 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
))
;
9921 break;
9922
9923 case FT_IPv4:
9924 switch (hfinfo->display) {
9925 case BASE_NONE:
9926 case BASE_NETMASK:
9927 break;
9928
9929 default:
9930 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9931 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)
9932 " 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)
9933 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)
9934 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)
;
9935 //wmem_free(NULL, tmp_str);
9936 break;
9937 }
9938 break;
9939 case FT_FLOAT:
9940 case FT_DOUBLE:
9941 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9942 case BASE_NONE:
9943 case BASE_DEC:
9944 case BASE_HEX:
9945 case BASE_EXP:
9946 case BASE_CUSTOM:
9947 break;
9948 default:
9949 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9950 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)
9951 " 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)
9952 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)
9953 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)
;
9954 //wmem_free(NULL, tmp_str);
9955 }
9956 if (hfinfo->bitmask != 0)
9957 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
))
9958 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
))
9959 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
))
;
9960 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9961 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
))
9962 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
))
9963 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
))
;
9964 break;
9965 case FT_IEEE_11073_SFLOAT:
9966 case FT_IEEE_11073_FLOAT:
9967 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9968 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9969 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)
9970 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)
9971 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)
9972 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)
;
9973 //wmem_free(NULL, tmp_str);
9974 }
9975 if (hfinfo->bitmask != 0)
9976 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
))
9977 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
))
9978 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
))
;
9979 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9980 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
))
9981 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
))
9982 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
))
;
9983 break;
9984 default:
9985 if (hfinfo->display != BASE_NONE) {
9986 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9987 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)
9988 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)
9989 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)
9990 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)
;
9991 //wmem_free(NULL, tmp_str);
9992 }
9993 if (hfinfo->bitmask != 0)
9994 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
))
9995 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
))
9996 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
))
;
9997 if (hfinfo->strings != NULL((void*)0))
9998 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
))
9999 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
))
10000 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
))
;
10001 break;
10002 }
10003}
10004
10005static void
10006register_type_length_mismatch(void)
10007{
10008 static ei_register_info ei[] = {
10009 { &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)}}
}},
10010 { &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)}}
}},
10011 };
10012
10013 expert_module_t* expert_type_length_mismatch;
10014
10015 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10016
10017 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10018 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10019
10020 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10021 disabling them makes no sense. */
10022 proto_set_cant_toggle(proto_type_length_mismatch);
10023}
10024
10025static void
10026register_byte_array_string_decodinws_error(void)
10027{
10028 static ei_register_info ei[] = {
10029 { &ei_byte_array_string_decoding_failed_error,
10030 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10031 "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)}}
10032 }
10033 },
10034 };
10035
10036 expert_module_t* expert_byte_array_string_decoding_error;
10037
10038 proto_byte_array_string_decoding_error =
10039 proto_register_protocol("Byte Array-String Decoding Error",
10040 "Byte Array-string decoding error",
10041 "_ws.byte_array_string.decoding_error");
10042
10043 expert_byte_array_string_decoding_error =
10044 expert_register_protocol(proto_byte_array_string_decoding_error);
10045 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10046
10047 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10048 disabling them makes no sense. */
10049 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10050}
10051
10052static void
10053register_date_time_string_decodinws_error(void)
10054{
10055 static ei_register_info ei[] = {
10056 { &ei_date_time_string_decoding_failed_error,
10057 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10058 "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)}}
10059 }
10060 },
10061 };
10062
10063 expert_module_t* expert_date_time_string_decoding_error;
10064
10065 proto_date_time_string_decoding_error =
10066 proto_register_protocol("Date and Time-String Decoding Error",
10067 "Date and Time-string decoding error",
10068 "_ws.date_time_string.decoding_error");
10069
10070 expert_date_time_string_decoding_error =
10071 expert_register_protocol(proto_date_time_string_decoding_error);
10072 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10073
10074 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10075 disabling them makes no sense. */
10076 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10077}
10078
10079static void
10080register_string_errors(void)
10081{
10082 static ei_register_info ei[] = {
10083 { &ei_string_trailing_characters,
10084 { "_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)}}
}
10085 },
10086 };
10087
10088 expert_module_t* expert_string_errors;
10089
10090 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10091
10092 expert_string_errors = expert_register_protocol(proto_string_errors);
10093 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10094
10095 /* "String Errors" isn't really a protocol, it's an error indication;
10096 disabling them makes no sense. */
10097 proto_set_cant_toggle(proto_string_errors);
10098}
10099
10100static void
10101register_varint_errors(void)
10102{
10103 static ei_register_info ei[] = {
10104 { &ei_varint_decoding_failed_error,
10105 { "_ws.varint.decoding_failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Varint decoding failed", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}
10106 },
10107 };
10108
10109 expert_module_t* expert_varint_errors;
10110
10111 proto_varint_errors = proto_register_protocol("Varint Errors", "Varint errors", "_ws.varint");
10112
10113 expert_varint_errors = expert_register_protocol(proto_varint_errors);
10114 expert_register_field_array(expert_varint_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10115
10116 /* "Varint Errors" isn't really a protocol, it's an error indication;
10117 disabling them makes no sense. */
10118 proto_set_cant_toggle(proto_varint_errors);
10119}
10120
10121static int
10122proto_register_field_init(header_field_info *hfinfo, const int parent)
10123{
10124
10125 tmp_fld_check_assert(hfinfo);
10126
10127 hfinfo->parent = parent;
10128 hfinfo->same_name_next = NULL((void*)0);
10129 hfinfo->same_name_prev_id = -1;
10130
10131 /* if we always add and never delete, then id == len - 1 is correct */
10132 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10133 if (!gpa_hfinfo.hfi) {
10134 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10135 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10136 /* The entry with index 0 is not used. */
10137 gpa_hfinfo.hfi[0] = NULL((void*)0);
10138 gpa_hfinfo.len = 1;
10139 } else {
10140 gpa_hfinfo.allocated_len += 1000;
10141 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10142 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10143 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10144 }
10145 }
10146 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10147 gpa_hfinfo.len++;
10148 hfinfo->id = gpa_hfinfo.len - 1;
10149
10150 /* if we have real names, enter this field in the name tree */
10151 /* Already checked in tmp_fld_check_assert */
10152 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10153 {
10154
10155 header_field_info *same_name_next_hfinfo;
10156
10157 /* We allow multiple hfinfo's to be registered under the same
10158 * abbreviation. This was done for X.25, as, depending
10159 * on whether it's modulo-8 or modulo-128 operation,
10160 * some bitfield fields may be in different bits of
10161 * a byte, and we want to be able to refer to that field
10162 * with one name regardless of whether the packets
10163 * are modulo-8 or modulo-128 packets. */
10164
10165 /* wmem_map_insert - if key is already present the previous
10166 * hfinfo with the same key/name is returned, otherwise NULL */
10167 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10168 if (same_name_hfinfo) {
10169 /* There's already a field with this name.
10170 * Put the current field *before* that field
10171 * in the list of fields with this name, Thus,
10172 * we end up with an effectively
10173 * doubly-linked-list of same-named hfinfo's,
10174 * with the head of the list (stored in the
10175 * hash) being the last seen hfinfo.
10176 */
10177 same_name_next_hfinfo =
10178 same_name_hfinfo->same_name_next;
10179
10180 hfinfo->same_name_next = same_name_next_hfinfo;
10181 if (same_name_next_hfinfo)
10182 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10183
10184 same_name_hfinfo->same_name_next = hfinfo;
10185 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10186#ifdef ENABLE_CHECK_FILTER
10187 while (same_name_hfinfo) {
10188 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10189 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", 10189
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10190 same_name_hfinfo = same_name_hfinfo->same_name_next;
10191 }
10192#endif
10193 }
10194 }
10195
10196 return hfinfo->id;
10197}
10198
10199void
10200proto_register_subtree_array(int * const *indices, const int num_indices)
10201{
10202 int i;
10203 int *const *ptr = indices;
10204
10205 /*
10206 * If we've already allocated the array of tree types, expand
10207 * it; this lets plugins such as mate add tree types after
10208 * the initial startup. (If we haven't already allocated it,
10209 * we don't allocate it; on the first pass, we just assign
10210 * ett values and keep track of how many we've assigned, and
10211 * when we're finished registering all dissectors we allocate
10212 * the array, so that we do only one allocation rather than
10213 * wasting CPU time and memory by growing the array for each
10214 * dissector that registers ett values.)
10215 */
10216 if (tree_is_expanded != NULL((void*)0)) {
10217 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10218
10219 /* set new items to 0 */
10220 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10221 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10222 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10223 }
10224
10225 /*
10226 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10227 * returning the indices through the pointers in the array whose
10228 * first element is pointed to by "indices", and update
10229 * "num_tree_types" appropriately.
10230 */
10231 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10232 if (**ptr != -1 && **ptr != 0) {
10233 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.")
10234 " 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.")
10235 " 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.")
10236 " 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.")
;
10237 }
10238 **ptr = num_tree_types;
10239 }
10240}
10241
10242static void
10243mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10244{
10245 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10246 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10247 char *last_char;
10248
10249 /* ..... field_name: dataaaaaaaaaaaaa
10250 * |
10251 * ^^^^^ name_pos
10252 *
10253 * ..... field_name […]: dataaaaaaaaaaaaa
10254 *
10255 * name_pos==0 means that we have only data or only a field_name
10256 */
10257
10258 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10258, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10259
10260 if (name_pos >= size - trunc_len) {
10261 /* No room for trunc_str after the field_name, put it first. */
10262 name_pos = 0;
10263 }
10264
10265 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10266 if (name_pos == 0) {
10267 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10268 memcpy(label_str, trunc_str + 1, trunc_len);
10269 } else {
10270 memcpy(label_str + name_pos, trunc_str, trunc_len);
10271 }
10272 /* in general, label_str is UTF-8
10273 we can truncate it only at the beginning of a new character
10274 we go backwards from the byte right after our buffer and
10275 find the next starting byte of a UTF-8 character, this is
10276 where we cut
10277 there's no need to use g_utf8_find_prev_char(), the search
10278 will always succeed since we copied trunc_str into the
10279 buffer */
10280 /* g_utf8_prev_char does not deference the memory address
10281 * passed in (until after decrementing it, so it is perfectly
10282 * legal to pass in a pointer one past the last element.
10283 */
10284 last_char = g_utf8_prev_char(label_str + size);
10285 *last_char = '\0';
10286 /* This is unnecessary (above always terminates), but try to
10287 * convince Coverity to avoid dozens of false positives. */
10288 label_str[size - 1] = '\0';
10289
10290 if (value_pos && *value_pos > 0) {
10291 if (name_pos == 0) {
10292 *value_pos += trunc_len;
10293 } else {
10294 /* Move one back to include trunc_str in the value. */
10295 *value_pos -= 1;
10296 }
10297 }
10298
10299 /* Check if value_pos is past label_str. */
10300 if (value_pos && *value_pos >= size) {
10301 *value_pos = size - 1;
10302 }
10303}
10304
10305static void
10306label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10307{
10308 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10309}
10310
10311static size_t
10312label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10313{
10314 size_t name_pos;
10315
10316 /* "%s: %s", hfinfo->name, text */
10317 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)
;
10318 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10319 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10320 if (value_pos) {
10321 *value_pos = pos;
10322 }
10323 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10324 }
10325
10326 if (pos >= ITEM_LABEL_LENGTH240) {
10327 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10328 label_mark_truncated(label_str, name_pos, value_pos);
10329 }
10330
10331 return pos;
10332}
10333
10334static size_t
10335label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10336{
10337 size_t name_pos;
10338
10339 /* "%s: %s (%s)", hfinfo->name, text, descr */
10340 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)
;
10341 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10342 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10343 if (value_pos) {
10344 *value_pos = pos;
10345 }
10346 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10347 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)
;
10348 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)
;
10349 } else {
10350 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)
;
10351 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10352 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)
;
10353 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10354 }
10355 }
10356
10357 if (pos >= ITEM_LABEL_LENGTH240) {
10358 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10359 label_mark_truncated(label_str, name_pos, value_pos);
10360 }
10361
10362 return pos;
10363}
10364
10365void
10366proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10367{
10368 const header_field_info *hfinfo;
10369 const char *str;
10370 const uint8_t *bytes;
10371 uint32_t integer;
10372 const ipv4_addr_and_mask *ipv4;
10373 const ipv6_addr_and_prefix *ipv6;
10374 const e_guid_t *guid;
10375 char *name;
10376 address addr;
10377 char *addr_str;
10378 char *tmp;
10379
10380 if (!label_str) {
10381 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10381, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10382 return;
10383 }
10384
10385 label_str[0]= '\0';
10386
10387 if (!fi) {
10388 return;
10389 }
10390
10391 hfinfo = fi->hfinfo;
10392
10393 switch (hfinfo->type) {
10394 case FT_NONE:
10395 case FT_PROTOCOL:
10396 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10397 if (value_pos) {
10398 *value_pos = strlen(hfinfo->name);
10399 }
10400 break;
10401
10402 case FT_BOOLEAN:
10403 fill_label_boolean(fi, label_str, value_pos);
10404 break;
10405
10406 case FT_BYTES:
10407 case FT_UINT_BYTES:
10408 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10409 fvalue_get_bytes_data(fi->value),
10410 (unsigned)fvalue_length2(fi->value));
10411 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10412 wmem_free(NULL((void*)0), tmp);
10413 break;
10414
10415 case FT_CHAR:
10416 if (hfinfo->bitmask) {
10417 fill_label_bitfield_char(fi, label_str, value_pos);
10418 } else {
10419 fill_label_char(fi, label_str, value_pos);
10420 }
10421 break;
10422
10423 /* Four types of integers to take care of:
10424 * Bitfield, with val_string
10425 * Bitfield, w/o val_string
10426 * Non-bitfield, with val_string
10427 * Non-bitfield, w/o val_string
10428 */
10429 case FT_UINT8:
10430 case FT_UINT16:
10431 case FT_UINT24:
10432 case FT_UINT32:
10433 if (hfinfo->bitmask) {
10434 fill_label_bitfield(fi, label_str, value_pos, false0);
10435 } else {
10436 fill_label_number(fi, label_str, value_pos, false0);
10437 }
10438 break;
10439
10440 case FT_FRAMENUM:
10441 fill_label_number(fi, label_str, value_pos, false0);
10442 break;
10443
10444 case FT_UINT40:
10445 case FT_UINT48:
10446 case FT_UINT56:
10447 case FT_UINT64:
10448 if (hfinfo->bitmask) {
10449 fill_label_bitfield64(fi, label_str, value_pos, false0);
10450 } else {
10451 fill_label_number64(fi, label_str, value_pos, false0);
10452 }
10453 break;
10454
10455 case FT_INT8:
10456 case FT_INT16:
10457 case FT_INT24:
10458 case FT_INT32:
10459 if (hfinfo->bitmask) {
10460 fill_label_bitfield(fi, label_str, value_pos, true1);
10461 } else {
10462 fill_label_number(fi, label_str, value_pos, true1);
10463 }
10464 break;
10465
10466 case FT_INT40:
10467 case FT_INT48:
10468 case FT_INT56:
10469 case FT_INT64:
10470 if (hfinfo->bitmask) {
10471 fill_label_bitfield64(fi, label_str, value_pos, true1);
10472 } else {
10473 fill_label_number64(fi, label_str, value_pos, true1);
10474 }
10475 break;
10476
10477 case FT_FLOAT:
10478 case FT_DOUBLE:
10479 fill_label_float(fi, label_str, value_pos);
10480 break;
10481
10482 case FT_ABSOLUTE_TIME:
10483 {
10484 const nstime_t *value = fvalue_get_time(fi->value);
10485 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10486 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10487 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10488 }
10489 if (hfinfo->strings) {
10490 /*
10491 * Table of time values to be displayed
10492 * specially.
10493 */
10494 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10495 if (time_string != NULL((void*)0)) {
10496 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10497 break;
10498 }
10499 }
10500 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10501 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10502 wmem_free(NULL((void*)0), tmp);
10503 break;
10504 }
10505 case FT_RELATIVE_TIME:
10506 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10507 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10508 wmem_free(NULL((void*)0), tmp);
10509 break;
10510
10511 case FT_IPXNET:
10512 integer = fvalue_get_uinteger(fi->value);
10513 tmp = get_ipxnet_name(NULL((void*)0), integer);
10514 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10515 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10516 wmem_free(NULL((void*)0), tmp);
10517 wmem_free(NULL((void*)0), addr_str);
10518 break;
10519
10520 case FT_VINES:
10521 addr.type = AT_VINES;
10522 addr.len = VINES_ADDR_LEN6;
10523 addr.data = fvalue_get_bytes_data(fi->value);
10524
10525 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10526 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10527 wmem_free(NULL((void*)0), addr_str);
10528 break;
10529
10530 case FT_ETHER:
10531 bytes = fvalue_get_bytes_data(fi->value);
10532
10533 addr.type = AT_ETHER;
10534 addr.len = 6;
10535 addr.data = bytes;
10536
10537 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10538 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10539 wmem_free(NULL((void*)0), addr_str);
10540 break;
10541
10542 case FT_IPv4:
10543 ipv4 = fvalue_get_ipv4(fi->value);
10544 set_address_ipv4(&addr, ipv4);
10545
10546 if (hfinfo->display == BASE_NETMASK) {
10547 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10548 } else {
10549 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10550 }
10551 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10552 wmem_free(NULL((void*)0), addr_str);
10553 free_address(&addr);
10554 break;
10555
10556 case FT_IPv6:
10557 ipv6 = fvalue_get_ipv6(fi->value);
10558 set_address_ipv6(&addr, ipv6);
10559
10560 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10561 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10562 wmem_free(NULL((void*)0), addr_str);
10563 free_address(&addr);
10564 break;
10565
10566 case FT_FCWWN:
10567 bytes = fvalue_get_bytes_data(fi->value);
10568 addr.type = AT_FCWWN;
10569 addr.len = FCWWN_ADDR_LEN8;
10570 addr.data = bytes;
10571
10572 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10573 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10574 wmem_free(NULL((void*)0), addr_str);
10575 break;
10576
10577 case FT_GUID:
10578 guid = fvalue_get_guid(fi->value);
10579 tmp = guid_to_str(NULL((void*)0), guid);
10580 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10581 wmem_free(NULL((void*)0), tmp);
10582 break;
10583
10584 case FT_OID:
10585 bytes = fvalue_get_bytes_data(fi->value);
10586 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10587 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10588 if (name) {
10589 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10590 wmem_free(NULL((void*)0), name);
10591 } else {
10592 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10593 }
10594 wmem_free(NULL((void*)0), tmp);
10595 break;
10596
10597 case FT_REL_OID:
10598 bytes = fvalue_get_bytes_data(fi->value);
10599 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10600 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10601 if (name) {
10602 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10603 wmem_free(NULL((void*)0), name);
10604 } else {
10605 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10606 }
10607 wmem_free(NULL((void*)0), tmp);
10608 break;
10609
10610 case FT_SYSTEM_ID:
10611 bytes = fvalue_get_bytes_data(fi->value);
10612 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10613 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10614 wmem_free(NULL((void*)0), tmp);
10615 break;
10616
10617 case FT_EUI64:
10618 bytes = fvalue_get_bytes_data(fi->value);
10619 addr.type = AT_EUI64;
10620 addr.len = EUI64_ADDR_LEN8;
10621 addr.data = bytes;
10622
10623 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10624 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10625 wmem_free(NULL((void*)0), addr_str);
10626 break;
10627 case FT_STRING:
10628 case FT_STRINGZ:
10629 case FT_UINT_STRING:
10630 case FT_STRINGZPAD:
10631 case FT_STRINGZTRUNC:
10632 case FT_AX25:
10633 str = fvalue_get_string(fi->value);
10634 label_fill(label_str, 0, hfinfo, str, value_pos);
10635 break;
10636
10637 case FT_IEEE_11073_SFLOAT:
10638 case FT_IEEE_11073_FLOAT:
10639 fill_label_ieee_11073_float(fi, label_str, value_pos);
10640 break;
10641
10642 default:
10643 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
))
10644 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
))
10645 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
))
10646 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
))
;
10647 break;
10648 }
10649}
10650
10651static void
10652fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10653{
10654 char *p;
10655 unsigned bitfield_byte_length = 0;
10656 int bitwidth;
10657 uint64_t unshifted_value;
10658 uint64_t value;
10659
10660 const header_field_info *hfinfo = fi->hfinfo;
10661
10662 value = fvalue_get_uinteger64(fi->value);
10663 if (hfinfo->bitmask) {
10664 /* Figure out the bit width */
10665 bitwidth = hfinfo_container_bitwidth(hfinfo);
10666
10667 /* Un-shift bits */
10668 unshifted_value = value;
10669 unshifted_value <<= hfinfo_bitshift(hfinfo);
10670
10671 /* Create the bitfield first */
10672 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10673 bitfield_byte_length = (unsigned) (p - label_str);
10674 }
10675
10676 /* Fill in the textual info */
10677 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10678}
10679
10680static const char *
10681hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10682{
10683 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10684 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10685
10686 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10687 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10688 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10689 else
10690 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10691 }
10692
10693 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10694 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10695
10696 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10697 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10698
10699 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10700}
10701
10702static const char *
10703hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10704{
10705 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10706 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10707 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10708 else
10709 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10710 }
10711
10712 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10713 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10714
10715 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10716 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10717
10718 /* If this is reached somebody registered a 64-bit field with a 32-bit
10719 * value-string, which isn't right. */
10720 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)
10721 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10722
10723 /* This is necessary to squelch MSVC errors; is there
10724 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10725 never returns? */
10726 return NULL((void*)0);
10727}
10728
10729static const char *
10730hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10731{
10732 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10733 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10734
10735 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)
;
10736
10737 /* This is necessary to squelch MSVC errors; is there
10738 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10739 never returns? */
10740 return NULL((void*)0);
10741}
10742
10743static const char *
10744hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10745{
10746 const char *str = hf_try_val_to_str(value, hfinfo);
10747
10748 return (str) ? str : unknown_str;
10749}
10750
10751static const char *
10752hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10753{
10754 const char *str = hf_try_val64_to_str(value, hfinfo);
10755
10756 return (str) ? str : unknown_str;
10757}
10758
10759/* Fills data for bitfield chars with val_strings */
10760static void
10761fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10762{
10763 char *p;
10764 unsigned bitfield_byte_length;
10765 int bitwidth;
10766 uint32_t unshifted_value;
10767 uint32_t value;
10768
10769 char buf[32];
10770 const char *out;
10771
10772 const header_field_info *hfinfo = fi->hfinfo;
10773
10774 /* Figure out the bit width */
10775 bitwidth = hfinfo_container_bitwidth(hfinfo);
10776
10777 /* Un-shift bits */
10778 value = fvalue_get_uinteger(fi->value);
10779
10780 unshifted_value = value;
10781 if (hfinfo->bitmask) {
10782 unshifted_value <<= hfinfo_bitshift(hfinfo);
10783 }
10784
10785 /* Create the bitfield first */
10786 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10787 bitfield_byte_length = (unsigned) (p - label_str);
10788
10789 /* Fill in the textual info using stored (shifted) value */
10790 if (hfinfo->display == BASE_CUSTOM) {
10791 char tmp[ITEM_LABEL_LENGTH240];
10792 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10793
10794 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10794, "fmtfunc"))))
;
10795 fmtfunc(tmp, value);
10796 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10797 }
10798 else if (hfinfo->strings) {
10799 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10800
10801 out = hfinfo_char_vals_format(hfinfo, buf, value);
10802 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10803 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10804 else
10805 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10806 }
10807 else {
10808 out = hfinfo_char_value_format(hfinfo, buf, value);
10809
10810 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10811 }
10812}
10813
10814/* Fills data for bitfield ints with val_strings */
10815static void
10816fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10817{
10818 char *p;
10819 unsigned bitfield_byte_length;
10820 int bitwidth;
10821 uint32_t value, unshifted_value;
10822 char buf[NUMBER_LABEL_LENGTH80];
10823 const char *out;
10824
10825 const header_field_info *hfinfo = fi->hfinfo;
10826
10827 /* Figure out the bit width */
10828 if (fi->flags & FI_VARINT0x00040000)
10829 bitwidth = fi->length*8;
10830 else
10831 bitwidth = hfinfo_container_bitwidth(hfinfo);
10832
10833 /* Un-shift bits */
10834 if (is_signed)
10835 value = fvalue_get_sinteger(fi->value);
10836 else
10837 value = fvalue_get_uinteger(fi->value);
10838
10839 unshifted_value = value;
10840 if (hfinfo->bitmask) {
10841 unshifted_value <<= hfinfo_bitshift(hfinfo);
10842 }
10843
10844 /* Create the bitfield first */
10845 if (fi->flags & FI_VARINT0x00040000)
10846 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10847 else
10848 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10849 bitfield_byte_length = (unsigned) (p - label_str);
10850
10851 /* Fill in the textual info using stored (shifted) value */
10852 if (hfinfo->display == BASE_CUSTOM) {
10853 char tmp[ITEM_LABEL_LENGTH240];
10854 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10855
10856 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10856, "fmtfunc"))))
;
10857 fmtfunc(tmp, value);
10858 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10859 }
10860 else if (hfinfo->strings) {
10861 const char *val_str = hf_try_val_to_str(value, hfinfo);
10862
10863 out = hfinfo_number_vals_format(hfinfo, buf, value);
10864 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10865 /*
10866 * Unique values only display value_string string
10867 * if there is a match. Otherwise it's just a number
10868 */
10869 if (val_str) {
10870 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10871 } else {
10872 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10873 }
10874 } else {
10875 if (val_str == NULL((void*)0))
10876 val_str = "Unknown";
10877
10878 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10879 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10880 else
10881 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10882 }
10883 }
10884 else {
10885 out = hfinfo_number_value_format(hfinfo, buf, value);
10886
10887 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10888 }
10889}
10890
10891static void
10892fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10893{
10894 char *p;
10895 unsigned bitfield_byte_length;
10896 int bitwidth;
10897 uint64_t value, unshifted_value;
10898 char buf[NUMBER_LABEL_LENGTH80];
10899 const char *out;
10900
10901 const header_field_info *hfinfo = fi->hfinfo;
10902
10903 /* Figure out the bit width */
10904 if (fi->flags & FI_VARINT0x00040000)
10905 bitwidth = fi->length*8;
10906 else
10907 bitwidth = hfinfo_container_bitwidth(hfinfo);
10908
10909 /* Un-shift bits */
10910 if (is_signed)
10911 value = fvalue_get_sinteger64(fi->value);
10912 else
10913 value = fvalue_get_uinteger64(fi->value);
10914
10915 unshifted_value = value;
10916 if (hfinfo->bitmask) {
10917 unshifted_value <<= hfinfo_bitshift(hfinfo);
10918 }
10919
10920 /* Create the bitfield first */
10921 if (fi->flags & FI_VARINT0x00040000)
10922 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10923 else
10924 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10925 bitfield_byte_length = (unsigned) (p - label_str);
10926
10927 /* Fill in the textual info using stored (shifted) value */
10928 if (hfinfo->display == BASE_CUSTOM) {
10929 char tmp[ITEM_LABEL_LENGTH240];
10930 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10931
10932 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10932, "fmtfunc64"
))))
;
10933 fmtfunc64(tmp, value);
10934 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10935 }
10936 else if (hfinfo->strings) {
10937 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10938
10939 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10940 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10941 /*
10942 * Unique values only display value_string string
10943 * if there is a match. Otherwise it's just a number
10944 */
10945 if (val_str) {
10946 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10947 } else {
10948 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10949 }
10950 } else {
10951 if (val_str == NULL((void*)0))
10952 val_str = "Unknown";
10953
10954 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10955 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10956 else
10957 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10958 }
10959 }
10960 else {
10961 out = hfinfo_number_value_format64(hfinfo, buf, value);
10962
10963 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10964 }
10965}
10966
10967static void
10968fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10969{
10970 const header_field_info *hfinfo = fi->hfinfo;
10971 uint32_t value;
10972
10973 char buf[32];
10974 const char *out;
10975
10976 value = fvalue_get_uinteger(fi->value);
10977
10978 /* Fill in the textual info */
10979 if (hfinfo->display == BASE_CUSTOM) {
10980 char tmp[ITEM_LABEL_LENGTH240];
10981 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10982
10983 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10983, "fmtfunc"))))
;
10984 fmtfunc(tmp, value);
10985 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10986 }
10987 else if (hfinfo->strings) {
10988 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10989
10990 out = hfinfo_char_vals_format(hfinfo, buf, value);
10991 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10992 }
10993 else {
10994 out = hfinfo_char_value_format(hfinfo, buf, value);
10995
10996 label_fill(label_str, 0, hfinfo, out, value_pos);
10997 }
10998}
10999
11000static void
11001fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11002{
11003 const header_field_info *hfinfo = fi->hfinfo;
11004 uint32_t value;
11005
11006 char buf[NUMBER_LABEL_LENGTH80];
11007 const char *out;
11008
11009 if (is_signed)
11010 value = fvalue_get_sinteger(fi->value);
11011 else
11012 value = fvalue_get_uinteger(fi->value);
11013
11014 /* Fill in the textual info */
11015 if (hfinfo->display == BASE_CUSTOM) {
11016 char tmp[ITEM_LABEL_LENGTH240];
11017 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11018
11019 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11019, "fmtfunc"))))
;
11020 fmtfunc(tmp, value);
11021 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11022 }
11023 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
11024 /*
11025 * It makes no sense to have a value-string table for a
11026 * frame-number field - they're just integers giving
11027 * the ordinal frame number.
11028 */
11029 const char *val_str = hf_try_val_to_str(value, hfinfo);
11030
11031 out = hfinfo_number_vals_format(hfinfo, buf, value);
11032 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11033 /*
11034 * Unique values only display value_string string
11035 * if there is a match. Otherwise it's just a number
11036 */
11037 if (val_str) {
11038 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11039 } else {
11040 label_fill(label_str, 0, hfinfo, out, value_pos);
11041 }
11042 } else {
11043 if (val_str == NULL((void*)0))
11044 val_str = "Unknown";
11045
11046 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11047 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11048 else
11049 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11050 }
11051 }
11052 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
))
) {
11053 char tmp[ITEM_LABEL_LENGTH240];
11054
11055 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11056 display_to_port_type((field_display_e)hfinfo->display), value);
11057 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11058 }
11059 else {
11060 out = hfinfo_number_value_format(hfinfo, buf, value);
11061
11062 label_fill(label_str, 0, hfinfo, out, value_pos);
11063 }
11064}
11065
11066static void
11067fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11068{
11069 const header_field_info *hfinfo = fi->hfinfo;
11070 uint64_t value;
11071
11072 char buf[NUMBER_LABEL_LENGTH80];
11073 const char *out;
11074
11075 if (is_signed)
11076 value = fvalue_get_sinteger64(fi->value);
11077 else
11078 value = fvalue_get_uinteger64(fi->value);
11079
11080 /* Fill in the textual info */
11081 if (hfinfo->display == BASE_CUSTOM) {
11082 char tmp[ITEM_LABEL_LENGTH240];
11083 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11084
11085 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11085, "fmtfunc64"
))))
;
11086 fmtfunc64(tmp, value);
11087 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11088 }
11089 else if (hfinfo->strings) {
11090 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11091
11092 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11093 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11094 /*
11095 * Unique values only display value_string string
11096 * if there is a match. Otherwise it's just a number
11097 */
11098 if (val_str) {
11099 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11100 } else {
11101 label_fill(label_str, 0, hfinfo, out, value_pos);
11102 }
11103 } else {
11104 if (val_str == NULL((void*)0))
11105 val_str = "Unknown";
11106
11107 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11108 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11109 else
11110 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11111 }
11112 }
11113 else {
11114 out = hfinfo_number_value_format64(hfinfo, buf, value);
11115
11116 label_fill(label_str, 0, hfinfo, out, value_pos);
11117 }
11118}
11119
11120static size_t
11121fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11122{
11123 int display;
11124 int n;
11125 double value;
11126
11127 if (label_str_size < 12) {
11128 /* Not enough room to write an entire floating point value. */
11129 return 0;
11130 }
11131
11132 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11133 value = fvalue_get_floating(fi->value);
11134
11135 if (display == BASE_CUSTOM) {
11136 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11137 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11137, "fmtfunc"))))
;
11138 fmtfunc(label_str, value);
11139 return strlen(label_str);
11140 }
11141
11142 switch (display) {
11143 case BASE_NONE:
11144 if (fi->hfinfo->type == FT_FLOAT) {
11145 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11146 } else {
11147 n = (int)strlen(dtoa_g_fmt(label_str, value));
11148 }
11149 break;
11150 case BASE_DEC:
11151 n = snprintf(label_str, label_str_size, "%f", value);
11152 break;
11153 case BASE_HEX:
11154 n = snprintf(label_str, label_str_size, "%a", value);
11155 break;
11156 case BASE_EXP:
11157 n = snprintf(label_str, label_str_size, "%e", value);
11158 break;
11159 default:
11160 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11160
, __func__, "assertion \"not reached\" failed")
;
11161 }
11162 if (n < 0) {
11163 return 0; /* error */
11164 }
11165 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11166 const char *hf_str_val;
11167 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11168 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11169 }
11170 if (n > label_str_size) {
11171 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11171, __func__, "label length too small"); } } while (0)
;
11172 return strlen(label_str);
11173 }
11174
11175 return n;
11176}
11177
11178void
11179fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11180{
11181 char tmp[ITEM_LABEL_LENGTH240];
11182
11183 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11184 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11185}
11186
11187static size_t
11188fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11189{
11190 int display;
11191 size_t pos = 0;
11192 double value;
11193 char* tmp_str;
11194
11195 if (label_str_size < 12) {
11196 /* Not enough room to write an entire floating point value. */
11197 return 0;
11198 }
11199
11200 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11201 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11202 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11203 wmem_free(NULL((void*)0), tmp_str);
11204
11205 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11206 const char *hf_str_val;
11207 fvalue_to_double(fi->value, &value);
11208 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11209 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)
;
11210 }
11211 if ((int)pos > label_str_size) {
11212 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11212, __func__, "label length too small"); } } while (0)
;
11213 return strlen(label_str);
11214 }
11215
11216 return pos;
11217}
11218
11219void
11220fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11221{
11222 char tmp[ITEM_LABEL_LENGTH240];
11223
11224 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11225 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11226}
11227
11228int
11229hfinfo_bitshift(const header_field_info *hfinfo)
11230{
11231 return ws_ctz(hfinfo->bitmask);
11232}
11233
11234
11235static int
11236hfinfo_bitoffset(const header_field_info *hfinfo)
11237{
11238 if (!hfinfo->bitmask) {
11239 return 0;
11240 }
11241
11242 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11243 * as the first bit */
11244 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11245}
11246
11247static int
11248hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11249{
11250 if (!hfinfo->bitmask) {
11251 return 0;
11252 }
11253
11254 /* ilog2 = first set bit, ctz = last set bit */
11255 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11256}
11257
11258static int
11259hfinfo_type_bitwidth(enum ftenum type)
11260{
11261 int bitwidth = 0;
11262
11263 switch (type) {
11264 case FT_CHAR:
11265 case FT_UINT8:
11266 case FT_INT8:
11267 bitwidth = 8;
11268 break;
11269 case FT_UINT16:
11270 case FT_INT16:
11271 bitwidth = 16;
11272 break;
11273 case FT_UINT24:
11274 case FT_INT24:
11275 bitwidth = 24;
11276 break;
11277 case FT_UINT32:
11278 case FT_INT32:
11279 bitwidth = 32;
11280 break;
11281 case FT_UINT40:
11282 case FT_INT40:
11283 bitwidth = 40;
11284 break;
11285 case FT_UINT48:
11286 case FT_INT48:
11287 bitwidth = 48;
11288 break;
11289 case FT_UINT56:
11290 case FT_INT56:
11291 bitwidth = 56;
11292 break;
11293 case FT_UINT64:
11294 case FT_INT64:
11295 bitwidth = 64;
11296 break;
11297 default:
11298 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11298))
;
11299 ;
11300 }
11301 return bitwidth;
11302}
11303
11304
11305static int
11306hfinfo_container_bitwidth(const header_field_info *hfinfo)
11307{
11308 if (!hfinfo->bitmask) {
11309 return 0;
11310 }
11311
11312 if (hfinfo->type == FT_BOOLEAN) {
11313 return hfinfo->display; /* hacky? :) */
11314 }
11315
11316 return hfinfo_type_bitwidth(hfinfo->type);
11317}
11318
11319static int
11320hfinfo_hex_digits(const header_field_info *hfinfo)
11321{
11322 int bitwidth;
11323
11324 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11325 * appropriate to determine the number of hex digits for the field.
11326 * So instead, we compute it from the bitmask.
11327 */
11328 if (hfinfo->bitmask != 0) {
11329 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11330 } else {
11331 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11332 }
11333
11334 /* Divide by 4, rounding up, to get number of hex digits. */
11335 return (bitwidth + 3) / 4;
11336}
11337
11338const char *
11339hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11340{
11341 char *ptr = &buf[6];
11342 static const char hex_digits[16] =
11343 { '0', '1', '2', '3', '4', '5', '6', '7',
11344 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11345
11346 *ptr = '\0';
11347 *(--ptr) = '\'';
11348 /* Properly format value */
11349 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11350 /*
11351 * Printable, so just show the character, and, if it needs
11352 * to be escaped, escape it.
11353 */
11354 *(--ptr) = value;
11355 if (value == '\\' || value == '\'')
11356 *(--ptr) = '\\';
11357 } else {
11358 /*
11359 * Non-printable; show it as an escape sequence.
11360 */
11361 switch (value) {
11362
11363 case '\0':
11364 /*
11365 * Show a NUL with only one digit.
11366 */
11367 *(--ptr) = '0';
11368 break;
11369
11370 case '\a':
11371 case '\b':
11372 case '\f':
11373 case '\n':
11374 case '\r':
11375 case '\t':
11376 case '\v':
11377 *(--ptr) = value - '\a' + 'a';
11378 break;
11379
11380 default:
11381 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11382
11383 case BASE_OCT:
11384 *(--ptr) = (value & 0x7) + '0';
11385 value >>= 3;
11386 *(--ptr) = (value & 0x7) + '0';
11387 value >>= 3;
11388 *(--ptr) = (value & 0x7) + '0';
11389 break;
11390
11391 case BASE_HEX:
11392 *(--ptr) = hex_digits[value & 0x0F];
11393 value >>= 4;
11394 *(--ptr) = hex_digits[value & 0x0F];
11395 *(--ptr) = 'x';
11396 break;
11397
11398 default:
11399 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11400 }
11401 }
11402 *(--ptr) = '\\';
11403 }
11404 *(--ptr) = '\'';
11405 return ptr;
11406}
11407
11408static const char *
11409hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11410{
11411 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11412 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
))
;
11413
11414 *ptr = '\0';
11415 /* Properly format value */
11416 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11417 case BASE_DEC:
11418 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11419
11420 case BASE_DEC_HEX:
11421 *(--ptr) = ')';
11422 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11423 *(--ptr) = '(';
11424 *(--ptr) = ' ';
11425 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11426 return ptr;
11427
11428 case BASE_OCT:
11429 return oct_to_str_back(ptr, value);
11430
11431 case BASE_HEX:
11432 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11433
11434 case BASE_HEX_DEC:
11435 *(--ptr) = ')';
11436 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11437 *(--ptr) = '(';
11438 *(--ptr) = ' ';
11439 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11440 return ptr;
11441
11442 case BASE_PT_UDP:
11443 case BASE_PT_TCP:
11444 case BASE_PT_DCCP:
11445 case BASE_PT_SCTP:
11446 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11447 display_to_port_type((field_display_e)display), value);
11448 return buf;
11449 case BASE_OUI:
11450 {
11451 uint8_t p_oui[3];
11452 const char *manuf_name;
11453
11454 p_oui[0] = value >> 16 & 0xFF;
11455 p_oui[1] = value >> 8 & 0xFF;
11456 p_oui[2] = value & 0xFF;
11457
11458 /* Attempt an OUI lookup. */
11459 manuf_name = uint_get_manuf_name_if_known(value);
11460 if (manuf_name == NULL((void*)0)) {
11461 /* Could not find an OUI. */
11462 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11463 }
11464 else {
11465 /* Found an address string. */
11466 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11467 }
11468 return buf;
11469 }
11470
11471 default:
11472 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11473 }
11474 return ptr;
11475}
11476
11477static const char *
11478hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11479{
11480 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11481 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
))
;
11482
11483 *ptr = '\0';
11484 /* Properly format value */
11485 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11486 case BASE_DEC:
11487 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11488
11489 case BASE_DEC_HEX:
11490 *(--ptr) = ')';
11491 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11492 *(--ptr) = '(';
11493 *(--ptr) = ' ';
11494 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11495 return ptr;
11496
11497 case BASE_OCT:
11498 return oct64_to_str_back(ptr, value);
11499
11500 case BASE_HEX:
11501 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11502
11503 case BASE_HEX_DEC:
11504 *(--ptr) = ')';
11505 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11506 *(--ptr) = '(';
11507 *(--ptr) = ' ';
11508 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11509 return ptr;
11510
11511 default:
11512 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11513 }
11514
11515 return ptr;
11516}
11517
11518static const char *
11519hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11520{
11521 int display = hfinfo->display;
11522
11523 if (hfinfo->type == FT_FRAMENUM) {
11524 /*
11525 * Frame numbers are always displayed in decimal.
11526 */
11527 display = BASE_DEC;
11528 }
11529
11530 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11531}
11532
11533static const char *
11534hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11535{
11536 int display = hfinfo->display;
11537
11538 if (hfinfo->type == FT_FRAMENUM) {
11539 /*
11540 * Frame numbers are always displayed in decimal.
11541 */
11542 display = BASE_DEC;
11543 }
11544
11545 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11546}
11547
11548static const char *
11549hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11550{
11551 /* Get the underlying BASE_ value */
11552 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11553
11554 return hfinfo_char_value_format_display(display, buf, value);
11555}
11556
11557static const char *
11558hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11559{
11560 /* Get the underlying BASE_ value */
11561 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11562
11563 if (hfinfo->type == FT_FRAMENUM) {
11564 /*
11565 * Frame numbers are always displayed in decimal.
11566 */
11567 display = BASE_DEC;
11568 }
11569
11570 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11571 display = BASE_DEC;
11572 } else if (display == BASE_OUI) {
11573 display = BASE_HEX;
11574 }
11575
11576 switch (display) {
11577 case BASE_NONE:
11578 /* case BASE_DEC: */
11579 case BASE_DEC_HEX:
11580 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11581 case BASE_CUSTOM:
11582 display = BASE_DEC;
11583 break;
11584
11585 /* case BASE_HEX: */
11586 case BASE_HEX_DEC:
11587 display = BASE_HEX;
11588 break;
11589 }
11590
11591 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11592}
11593
11594static const char *
11595hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11596{
11597 /* Get the underlying BASE_ value */
11598 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11599
11600 if (hfinfo->type == FT_FRAMENUM) {
11601 /*
11602 * Frame numbers are always displayed in decimal.
11603 */
11604 display = BASE_DEC;
11605 }
11606
11607 switch (display) {
11608 case BASE_NONE:
11609 /* case BASE_DEC: */
11610 case BASE_DEC_HEX:
11611 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11612 case BASE_CUSTOM:
11613 display = BASE_DEC;
11614 break;
11615
11616 /* case BASE_HEX: */
11617 case BASE_HEX_DEC:
11618 display = BASE_HEX;
11619 break;
11620 }
11621
11622 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11623}
11624
11625static const char *
11626hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11627{
11628 /* Get the underlying BASE_ value */
11629 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11630
11631 return hfinfo_char_value_format_display(display, buf, value);
11632}
11633
11634static const char *
11635hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11636{
11637 /* Get the underlying BASE_ value */
11638 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11639
11640 if (display == BASE_NONE)
11641 return NULL((void*)0);
11642
11643 if (display == BASE_DEC_HEX)
11644 display = BASE_DEC;
11645 if (display == BASE_HEX_DEC)
11646 display = BASE_HEX;
11647
11648 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11649}
11650
11651static const char *
11652hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11653{
11654 /* Get the underlying BASE_ value */
11655 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11656
11657 if (display == BASE_NONE)
11658 return NULL((void*)0);
11659
11660 if (display == BASE_DEC_HEX)
11661 display = BASE_DEC;
11662 if (display == BASE_HEX_DEC)
11663 display = BASE_HEX;
11664
11665 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11666}
11667
11668const char *
11669proto_registrar_get_name(const int n)
11670{
11671 header_field_info *hfinfo;
11672
11673 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", 11673
, __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", 11673
, "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", 11673, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11674 return hfinfo->name;
11675}
11676
11677const char *
11678proto_registrar_get_abbrev(const int n)
11679{
11680 header_field_info *hfinfo;
11681
11682 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", 11682
, __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", 11682
, "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", 11682, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11683 return hfinfo->abbrev;
11684}
11685
11686enum ftenum
11687proto_registrar_get_ftype(const int n)
11688{
11689 header_field_info *hfinfo;
11690
11691 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", 11691
, __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", 11691
, "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", 11691, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11692 return hfinfo->type;
11693}
11694
11695int
11696proto_registrar_get_parent(const int n)
11697{
11698 header_field_info *hfinfo;
11699
11700 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", 11700
, __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", 11700
, "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", 11700, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11701 return hfinfo->parent;
11702}
11703
11704bool_Bool
11705proto_registrar_is_protocol(const int n)
11706{
11707 header_field_info *hfinfo;
11708
11709 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", 11709
, __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", 11709
, "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", 11709, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11710 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11711}
11712
11713/* Returns length of field in packet (not necessarily the length
11714 * in our internal representation, as in the case of IPv4).
11715 * 0 means undeterminable at time of registration
11716 * -1 means the field is not registered. */
11717int
11718proto_registrar_get_length(const int n)
11719{
11720 header_field_info *hfinfo;
11721
11722 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", 11722
, __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", 11722
, "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", 11722, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11723 return ftype_wire_size(hfinfo->type);
11724}
11725
11726size_t
11727proto_registrar_get_count(struct proto_registrar_stats *stats)
11728{
11729 header_field_info *hfinfo;
11730
11731 // Index zero is not used. We have to skip it.
11732 size_t total_count = gpa_hfinfo.len - 1;
11733 if (stats == NULL((void*)0)) {
11734 return total_count;
11735 }
11736 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11737 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11738 stats->deregistered_count++;
11739 continue; /* This is a deregistered protocol or header field */
11740 }
11741
11742 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", 11742
, __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", 11742, "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", 11742, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11743
11744 if (proto_registrar_is_protocol(id))
11745 stats->protocol_count++;
11746
11747 if (hfinfo->same_name_prev_id != -1)
11748 stats->same_name_count++;
11749 }
11750
11751 return total_count;
11752}
11753
11754/* Looks for a protocol or a field in a proto_tree. Returns true if
11755 * it exists anywhere, or false if it exists nowhere. */
11756bool_Bool
11757proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11758{
11759 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11760
11761 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11762 return true1;
11763 }
11764 else {
11765 return false0;
11766 }
11767}
11768
11769/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11770 * This only works if the hfindex was "primed" before the dissection
11771 * took place, as we just pass back the already-created GPtrArray*.
11772 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11773 * handles that. */
11774GPtrArray *
11775proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11776{
11777 if (!tree)
11778 return NULL((void*)0);
11779
11780 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11781 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11782 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11783 else
11784 return NULL((void*)0);
11785}
11786
11787bool_Bool
11788proto_tracking_interesting_fields(const proto_tree *tree)
11789{
11790 GHashTable *interesting_hfids;
11791
11792 if (!tree)
11793 return false0;
11794
11795 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11796
11797 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11798}
11799
11800/* Helper struct for proto_find_info() and proto_all_finfos() */
11801typedef struct {
11802 GPtrArray *array;
11803 int id;
11804} ffdata_t;
11805
11806/* Helper function for proto_find_info() */
11807static bool_Bool
11808find_finfo(proto_node *node, void * data)
11809{
11810 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11811 if (fi && fi->hfinfo) {
11812 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11813 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11814 }
11815 }
11816
11817 /* Don't stop traversing. */
11818 return false0;
11819}
11820
11821/* Helper function for proto_find_first_info() */
11822static bool_Bool
11823find_first_finfo(proto_node *node, void *data)
11824{
11825 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11826 if (fi && fi->hfinfo) {
11827 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11828 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11829
11830 /* Stop traversing. */
11831 return true1;
11832 }
11833 }
11834
11835 /* Continue traversing. */
11836 return false0;
11837}
11838
11839/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11840* This works on any proto_tree, primed or unprimed, but actually searches
11841* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11842* The caller does need to free the returned GPtrArray with
11843* g_ptr_array_free(<array>, true).
11844*/
11845GPtrArray *
11846proto_find_finfo(proto_tree *tree, const int id)
11847{
11848 ffdata_t ffdata;
11849
11850 ffdata.array = g_ptr_array_new();
11851 ffdata.id = id;
11852
11853 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11854
11855 return ffdata.array;
11856}
11857
11858/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11859* This works on any proto_tree, primed or unprimed, but actually searches
11860* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11861* The caller does need to free the returned GPtrArray with
11862* g_ptr_array_free(<array>, true).
11863*/
11864GPtrArray *
11865proto_find_first_finfo(proto_tree *tree, const int id)
11866{
11867 ffdata_t ffdata;
11868
11869 ffdata.array = g_ptr_array_new();
11870 ffdata.id = id;
11871
11872 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11873
11874 return ffdata.array;
11875}
11876
11877/* Helper function for proto_all_finfos() */
11878static bool_Bool
11879every_finfo(proto_node *node, void * data)
11880{
11881 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11882 if (fi && fi->hfinfo) {
11883 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11884 }
11885
11886 /* Don't stop traversing. */
11887 return false0;
11888}
11889
11890/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11891 * The caller does need to free the returned GPtrArray with
11892 * g_ptr_array_free(<array>, true).
11893 */
11894GPtrArray *
11895proto_all_finfos(proto_tree *tree)
11896{
11897 ffdata_t ffdata;
11898
11899 /* Pre allocate enough space to hold all fields in most cases */
11900 ffdata.array = g_ptr_array_sized_new(512);
11901 ffdata.id = 0;
11902
11903 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11904
11905 return ffdata.array;
11906}
11907
11908
11909typedef struct {
11910 unsigned offset;
11911 field_info *finfo;
11912 tvbuff_t *tvb;
11913} offset_search_t;
11914
11915static bool_Bool
11916check_for_offset(proto_node *node, void * data)
11917{
11918 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11919 offset_search_t *offsearch = (offset_search_t *)data;
11920
11921 /* !fi == the top most container node which holds nothing */
11922 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11923 if (offsearch->offset >= (unsigned) fi->start &&
11924 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11925
11926 offsearch->finfo = fi;
11927 return false0; /* keep traversing */
11928 }
11929 }
11930 return false0; /* keep traversing */
11931}
11932
11933/* Search a proto_tree backwards (from leaves to root) looking for the field
11934 * whose start/length occupies 'offset' */
11935/* XXX - I couldn't find an easy way to search backwards, so I search
11936 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11937 * the one I want to return to the user. This algorithm is inefficient
11938 * and could be re-done, but I'd have to handle all the children and
11939 * siblings of each node myself. When I have more time I'll do that.
11940 * (yeah right) */
11941field_info *
11942proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11943{
11944 offset_search_t offsearch;
11945
11946 offsearch.offset = offset;
11947 offsearch.finfo = NULL((void*)0);
11948 offsearch.tvb = tvb;
11949
11950 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11951
11952 return offsearch.finfo;
11953}
11954
11955typedef struct {
11956 unsigned length;
11957 char *buf;
11958} decoded_data_t;
11959
11960static bool_Bool
11961check_for_undecoded(proto_node *node, void * data)
11962{
11963 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11964 decoded_data_t* decoded = (decoded_data_t*)data;
11965 unsigned i;
11966 unsigned byte;
11967 unsigned bit;
11968
11969 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11970 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11971 byte = i / 8;
11972 bit = i % 8;
11973 decoded->buf[byte] |= (1 << bit);
11974 }
11975 }
11976
11977 return false0;
11978}
11979
11980char*
11981proto_find_undecoded_data(proto_tree *tree, unsigned length)
11982{
11983 decoded_data_t decoded;
11984 decoded.length = length;
11985 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11986
11987 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11988 return decoded.buf;
11989}
11990
11991/* Dumps the protocols in the registration database to stdout. An independent
11992 * program can take this output and format it into nice tables or HTML or
11993 * whatever.
11994 *
11995 * There is one record per line. The fields are tab-delimited.
11996 *
11997 * Field 1 = protocol name
11998 * Field 2 = protocol short name
11999 * Field 3 = protocol filter name
12000 * Field 4 = protocol enabled
12001 * Field 5 = protocol enabled by default
12002 * Field 6 = protocol can toggle
12003 */
12004void
12005proto_registrar_dump_protocols(void)
12006{
12007 protocol_t *protocol;
12008 int i;
12009 void *cookie = NULL((void*)0);
12010
12011
12012 i = proto_get_first_protocol(&cookie);
12013 while (i != -1) {
12014 protocol = find_protocol_by_id(i);
12015 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
12016 protocol->name,
12017 protocol->short_name,
12018 protocol->filter_name,
12019 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
12020 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
12021 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
12022 i = proto_get_next_protocol(&cookie);
12023 }
12024}
12025
12026/* Dumps the value_strings, extended value string headers, range_strings
12027 * or true/false strings for fields that have them.
12028 * There is one record per line. Fields are tab-delimited.
12029 * There are four types of records: Value String, Extended Value String Header,
12030 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
12031 * the type of record.
12032 *
12033 * Note that a record will be generated only if the value_string,... is referenced
12034 * in a registered hfinfo entry.
12035 *
12036 *
12037 * Value Strings
12038 * -------------
12039 * Field 1 = 'V'
12040 * Field 2 = Field abbreviation to which this value string corresponds
12041 * Field 3 = Integer value
12042 * Field 4 = String
12043 *
12044 * Extended Value String Headers
12045 * -----------------------------
12046 * Field 1 = 'E'
12047 * Field 2 = Field abbreviation to which this extended value string header corresponds
12048 * Field 3 = Extended Value String "Name"
12049 * Field 4 = Number of entries in the associated value_string array
12050 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12051 *
12052 * Range Strings
12053 * -------------
12054 * Field 1 = 'R'
12055 * Field 2 = Field abbreviation to which this range string corresponds
12056 * Field 3 = Integer value: lower bound
12057 * Field 4 = Integer value: upper bound
12058 * Field 5 = String
12059 *
12060 * True/False Strings
12061 * ------------------
12062 * Field 1 = 'T'
12063 * Field 2 = Field abbreviation to which this true/false string corresponds
12064 * Field 3 = True String
12065 * Field 4 = False String
12066 */
12067void
12068proto_registrar_dump_values(void)
12069{
12070 header_field_info *hfinfo;
12071 int i, len, vi;
12072 const value_string *vals;
12073 const val64_string *vals64;
12074 const range_string *range;
12075 const true_false_string *tfs;
12076 const unit_name_string *units;
12077
12078 len = gpa_hfinfo.len;
12079 for (i = 1; i < len ; i++) {
12080 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12081 continue; /* This is a deregistered protocol or field */
12082
12083 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", 12083
, __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", 12083
, "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", 12083, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12084
12085 if (hfinfo->id == hf_text_only) {
12086 continue;
12087 }
12088
12089 /* ignore protocols */
12090 if (proto_registrar_is_protocol(i)) {
12091 continue;
12092 }
12093 /* process header fields */
12094#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12095 /*
12096 * If this field isn't at the head of the list of
12097 * fields with this name, skip this field - all
12098 * fields with the same name are really just versions
12099 * of the same field stored in different bits, and
12100 * should have the same type/radix/value list, and
12101 * just differ in their bit masks. (If a field isn't
12102 * a bitfield, but can be, say, 1 or 2 bytes long,
12103 * it can just be made FT_UINT16, meaning the
12104 * *maximum* length is 2 bytes, and be used
12105 * for all lengths.)
12106 */
12107 if (hfinfo->same_name_prev_id != -1)
12108 continue;
12109#endif
12110 vals = NULL((void*)0);
12111 vals64 = NULL((void*)0);
12112 range = NULL((void*)0);
12113 tfs = NULL((void*)0);
12114 units = NULL((void*)0);
12115
12116 if (hfinfo->strings != NULL((void*)0)) {
12117 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12118 (hfinfo->type == FT_CHAR ||
12119 hfinfo->type == FT_UINT8 ||
12120 hfinfo->type == FT_UINT16 ||
12121 hfinfo->type == FT_UINT24 ||
12122 hfinfo->type == FT_UINT32 ||
12123 hfinfo->type == FT_UINT40 ||
12124 hfinfo->type == FT_UINT48 ||
12125 hfinfo->type == FT_UINT56 ||
12126 hfinfo->type == FT_UINT64 ||
12127 hfinfo->type == FT_INT8 ||
12128 hfinfo->type == FT_INT16 ||
12129 hfinfo->type == FT_INT24 ||
12130 hfinfo->type == FT_INT32 ||
12131 hfinfo->type == FT_INT40 ||
12132 hfinfo->type == FT_INT48 ||
12133 hfinfo->type == FT_INT56 ||
12134 hfinfo->type == FT_INT64 ||
12135 hfinfo->type == FT_FLOAT ||
12136 hfinfo->type == FT_DOUBLE)) {
12137
12138 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12139 range = (const range_string *)hfinfo->strings;
12140 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12141 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12142 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12143 } else {
12144 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12145 }
12146 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12147 vals64 = (const val64_string *)hfinfo->strings;
12148 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12149 units = (const unit_name_string *)hfinfo->strings;
12150 } else {
12151 vals = (const value_string *)hfinfo->strings;
12152 }
12153 }
12154 else if (hfinfo->type == FT_BOOLEAN) {
12155 tfs = (const struct true_false_string *)hfinfo->strings;
12156 }
12157 }
12158
12159 /* Print value strings? */
12160 if (vals) {
12161 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12162 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12163 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12164 if (!val64_string_ext_validate(vse_p)) {
12165 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12165, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12166 continue;
12167 }
12168 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12169 printf("E\t%s\t%u\t%s\t%s\n",
12170 hfinfo->abbrev,
12171 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12172 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12173 val64_string_ext_match_type_str(vse_p));
12174 } else {
12175 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12176 if (!value_string_ext_validate(vse_p)) {
12177 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12177, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12178 continue;
12179 }
12180 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12181 printf("E\t%s\t%u\t%s\t%s\n",
12182 hfinfo->abbrev,
12183 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12184 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12185 value_string_ext_match_type_str(vse_p));
12186 }
12187 }
12188 vi = 0;
12189 while (vals[vi].strptr) {
12190 /* Print in the proper base */
12191 if (hfinfo->type == FT_CHAR) {
12192 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12193 printf("V\t%s\t'%c'\t%s\n",
12194 hfinfo->abbrev,
12195 vals[vi].value,
12196 vals[vi].strptr);
12197 } else {
12198 if (hfinfo->display == BASE_HEX) {
12199 printf("V\t%s\t'\\x%02x'\t%s\n",
12200 hfinfo->abbrev,
12201 vals[vi].value,
12202 vals[vi].strptr);
12203 }
12204 else {
12205 printf("V\t%s\t'\\%03o'\t%s\n",
12206 hfinfo->abbrev,
12207 vals[vi].value,
12208 vals[vi].strptr);
12209 }
12210 }
12211 } else {
12212 if (hfinfo->display == BASE_HEX) {
12213 printf("V\t%s\t0x%x\t%s\n",
12214 hfinfo->abbrev,
12215 vals[vi].value,
12216 vals[vi].strptr);
12217 }
12218 else {
12219 printf("V\t%s\t%u\t%s\n",
12220 hfinfo->abbrev,
12221 vals[vi].value,
12222 vals[vi].strptr);
12223 }
12224 }
12225 vi++;
12226 }
12227 }
12228 else if (vals64) {
12229 vi = 0;
12230 while (vals64[vi].strptr) {
12231 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12232 hfinfo->abbrev,
12233 vals64[vi].value,
12234 vals64[vi].strptr);
12235 vi++;
12236 }
12237 }
12238
12239 /* print range strings? */
12240 else if (range) {
12241 vi = 0;
12242 while (range[vi].strptr) {
12243 /* Print in the proper base */
12244 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12245 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12246 hfinfo->abbrev,
12247 range[vi].value_min,
12248 range[vi].value_max,
12249 range[vi].strptr);
12250 }
12251 else {
12252 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12253 hfinfo->abbrev,
12254 range[vi].value_min,
12255 range[vi].value_max,
12256 range[vi].strptr);
12257 }
12258 vi++;
12259 }
12260 }
12261
12262 /* Print true/false strings? */
12263 else if (tfs) {
12264 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12265 tfs->true_string, tfs->false_string);
12266 }
12267 /* Print unit strings? */
12268 else if (units) {
12269 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12270 units->singular, units->plural ? units->plural : "(no plural)");
12271 }
12272 }
12273}
12274
12275/* Prints the number of registered fields.
12276 * Useful for determining an appropriate value for
12277 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12278 *
12279 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12280 * the number of fields, true otherwise.
12281 */
12282bool_Bool
12283proto_registrar_dump_fieldcount(void)
12284{
12285 struct proto_registrar_stats stats = {0, 0, 0};
12286 size_t total_count = proto_registrar_get_count(&stats);
12287
12288 printf("There are %zu header fields registered, of which:\n"
12289 "\t%zu are deregistered\n"
12290 "\t%zu are protocols\n"
12291 "\t%zu have the same name as another field\n\n",
12292 total_count, stats.deregistered_count, stats.protocol_count,
12293 stats.same_name_count);
12294
12295 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12296 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12297 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12298 "\n");
12299
12300 printf("The header field table consumes %u KiB of memory.\n",
12301 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12302 printf("The fields themselves consume %u KiB of memory.\n",
12303 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12304
12305 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12306}
12307
12308static void
12309elastic_add_base_mapping(json_dumper *dumper)
12310{
12311 json_dumper_set_member_name(dumper, "index_patterns");
12312 json_dumper_begin_array(dumper);
12313 // The index names from write_json_index() in print.c
12314 json_dumper_value_string(dumper, "packets-*");
12315 json_dumper_end_array(dumper);
12316
12317 json_dumper_set_member_name(dumper, "settings");
12318 json_dumper_begin_object(dumper);
12319 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12320 json_dumper_value_anyf(dumper, "%d", 1000000);
12321 json_dumper_end_object(dumper);
12322}
12323
12324static char*
12325ws_type_to_elastic(unsigned type)
12326{
12327 switch(type) {
12328 case FT_INT8:
12329 return "byte";
12330 case FT_UINT8:
12331 case FT_INT16:
12332 return "short";
12333 case FT_UINT16:
12334 case FT_INT32:
12335 case FT_UINT24:
12336 case FT_INT24:
12337 return "integer";
12338 case FT_FRAMENUM:
12339 case FT_UINT32:
12340 case FT_UINT40:
12341 case FT_UINT48:
12342 case FT_UINT56:
12343 case FT_INT40:
12344 case FT_INT48:
12345 case FT_INT56:
12346 case FT_INT64:
12347 return "long";
12348 case FT_UINT64:
12349 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12350 case FT_FLOAT:
12351 return "float";
12352 case FT_DOUBLE:
12353 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12354 return "double";
12355 case FT_IPv6:
12356 case FT_IPv4:
12357 return "ip";
12358 case FT_ABSOLUTE_TIME:
12359 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12360 case FT_BOOLEAN:
12361 return "boolean";
12362 default:
12363 return NULL((void*)0);
12364 }
12365}
12366
12367static char*
12368dot_to_underscore(char* str)
12369{
12370 unsigned i;
12371 for (i = 0; i < strlen(str); i++) {
12372 if (str[i] == '.')
12373 str[i] = '_';
12374 }
12375 return str;
12376}
12377
12378/* Dumps a mapping file for ElasticSearch
12379 * This is the v1 (legacy) _template API.
12380 * At some point it may need to be updated with the composable templates
12381 * introduced in Elasticsearch 7.8 (_index_template)
12382 */
12383void
12384proto_registrar_dump_elastic(const char* filter)
12385{
12386 header_field_info *hfinfo;
12387 header_field_info *parent_hfinfo;
12388 unsigned i;
12389 bool_Bool open_object = true1;
12390 const char* prev_proto = NULL((void*)0);
12391 char* str;
12392 char** protos = NULL((void*)0);
12393 char* proto;
12394 bool_Bool found;
12395 unsigned j;
12396 char* type;
12397 char* prev_item = NULL((void*)0);
12398
12399 /* We have filtering protocols. Extract them. */
12400 if (filter) {
12401 protos = g_strsplit(filter, ",", -1);
12402 }
12403
12404 /*
12405 * To help tracking down the json tree, objects have been appended with a comment:
12406 * n.label -> where n is the indentation level and label the name of the object
12407 */
12408
12409 json_dumper dumper = {
12410 .output_file = stdoutstdout,
12411 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12412 };
12413 json_dumper_begin_object(&dumper); // 1.root
12414 elastic_add_base_mapping(&dumper);
12415
12416 json_dumper_set_member_name(&dumper, "mappings");
12417 json_dumper_begin_object(&dumper); // 2.mappings
12418
12419 json_dumper_set_member_name(&dumper, "properties");
12420 json_dumper_begin_object(&dumper); // 3.properties
12421 json_dumper_set_member_name(&dumper, "timestamp");
12422 json_dumper_begin_object(&dumper); // 4.timestamp
12423 json_dumper_set_member_name(&dumper, "type");
12424 json_dumper_value_string(&dumper, "date");
12425 json_dumper_end_object(&dumper); // 4.timestamp
12426
12427 json_dumper_set_member_name(&dumper, "layers");
12428 json_dumper_begin_object(&dumper); // 4.layers
12429 json_dumper_set_member_name(&dumper, "properties");
12430 json_dumper_begin_object(&dumper); // 5.properties
12431
12432 for (i = 1; i < gpa_hfinfo.len; i++) {
12433 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12434 continue; /* This is a deregistered protocol or header field */
12435
12436 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", 12436
, __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", 12436
, "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", 12436, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12437
12438 /*
12439 * Skip the pseudo-field for "proto_tree_add_text()" since
12440 * we don't want it in the list of filterable protocols.
12441 */
12442 if (hfinfo->id == hf_text_only)
12443 continue;
12444
12445 if (!proto_registrar_is_protocol(i)) {
12446 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", 12446
, __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", 12446
, "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", 12446
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12447
12448 /*
12449 * Skip the field if filter protocols have been set and this one's
12450 * parent is not listed.
12451 */
12452 if (protos) {
12453 found = false0;
12454 j = 0;
12455 proto = protos[0];
12456 while(proto) {
12457 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12458 found = true1;
12459 break;
12460 }
12461 j++;
12462 proto = protos[j];
12463 }
12464 if (!found)
12465 continue;
12466 }
12467
12468 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12469 json_dumper_end_object(&dumper); // 7.properties
12470 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12471 open_object = true1;
12472 }
12473
12474 prev_proto = parent_hfinfo->abbrev;
12475
12476 if (open_object) {
12477 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12478 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12479 json_dumper_set_member_name(&dumper, "properties");
12480 json_dumper_begin_object(&dumper); // 7.properties
12481 open_object = false0;
12482 }
12483 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12484 type = ws_type_to_elastic(hfinfo->type);
12485 /* when type is NULL, we have the default mapping: string */
12486 if (type) {
12487 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12488 dot_to_underscore(str);
12489 if (g_strcmp0(prev_item, str)) {
12490 json_dumper_set_member_name(&dumper, str);
12491 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12492 json_dumper_set_member_name(&dumper, "type");
12493 json_dumper_value_string(&dumper, type);
12494 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12495 }
12496 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)
;
12497 prev_item = str;
12498 }
12499 }
12500 }
12501 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)
;
12502
12503 if (prev_proto) {
12504 json_dumper_end_object(&dumper); // 7.properties
12505 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12506 }
12507
12508 json_dumper_end_object(&dumper); // 5.properties
12509 json_dumper_end_object(&dumper); // 4.layers
12510 json_dumper_end_object(&dumper); // 3.properties
12511 json_dumper_end_object(&dumper); // 2.mappings
12512 json_dumper_end_object(&dumper); // 1.root
12513 bool_Bool ret = json_dumper_finish(&dumper);
12514 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12514, "ret"))))
;
12515
12516 g_strfreev(protos);
12517}
12518
12519/* Dumps the contents of the registration database to stdout. An independent
12520 * program can take this output and format it into nice tables or HTML or
12521 * whatever.
12522 *
12523 * There is one record per line. Each record is either a protocol or a header
12524 * field, differentiated by the first field. The fields are tab-delimited.
12525 *
12526 * Protocols
12527 * ---------
12528 * Field 1 = 'P'
12529 * Field 2 = descriptive protocol name
12530 * Field 3 = protocol abbreviation
12531 *
12532 * Header Fields
12533 * -------------
12534 * Field 1 = 'F'
12535 * Field 2 = descriptive field name
12536 * Field 3 = field abbreviation
12537 * Field 4 = type ( textual representation of the ftenum type )
12538 * Field 5 = parent protocol abbreviation
12539 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12540 * Field 7 = bitmask: format: hex: 0x....
12541 * Field 8 = blurb describing field
12542 */
12543void
12544proto_registrar_dump_fields(void)
12545{
12546 header_field_info *hfinfo, *parent_hfinfo;
12547 int i, len;
12548 const char *enum_name;
12549 const char *base_name;
12550 const char *blurb;
12551 char width[5];
12552
12553 len = gpa_hfinfo.len;
12554 for (i = 1; i < len ; i++) {
12555 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12556 continue; /* This is a deregistered protocol or header field */
12557
12558 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", 12558
, __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", 12558
, "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", 12558, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12559
12560 /*
12561 * Skip the pseudo-field for "proto_tree_add_text()" since
12562 * we don't want it in the list of filterable fields.
12563 */
12564 if (hfinfo->id == hf_text_only)
12565 continue;
12566
12567 /* format for protocols */
12568 if (proto_registrar_is_protocol(i)) {
12569 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12570 }
12571 /* format for header fields */
12572 else {
12573 /*
12574 * If this field isn't at the head of the list of
12575 * fields with this name, skip this field - all
12576 * fields with the same name are really just versions
12577 * of the same field stored in different bits, and
12578 * should have the same type/radix/value list, and
12579 * just differ in their bit masks. (If a field isn't
12580 * a bitfield, but can be, say, 1 or 2 bytes long,
12581 * it can just be made FT_UINT16, meaning the
12582 * *maximum* length is 2 bytes, and be used
12583 * for all lengths.)
12584 */
12585 if (hfinfo->same_name_prev_id != -1)
12586 continue;
12587
12588 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", 12588
, __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", 12588
, "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", 12588
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12589
12590 enum_name = ftype_name(hfinfo->type);
12591 base_name = "";
12592
12593 if (hfinfo->type == FT_CHAR ||
12594 hfinfo->type == FT_UINT8 ||
12595 hfinfo->type == FT_UINT16 ||
12596 hfinfo->type == FT_UINT24 ||
12597 hfinfo->type == FT_UINT32 ||
12598 hfinfo->type == FT_UINT40 ||
12599 hfinfo->type == FT_UINT48 ||
12600 hfinfo->type == FT_UINT56 ||
12601 hfinfo->type == FT_UINT64 ||
12602 hfinfo->type == FT_INT8 ||
12603 hfinfo->type == FT_INT16 ||
12604 hfinfo->type == FT_INT24 ||
12605 hfinfo->type == FT_INT32 ||
12606 hfinfo->type == FT_INT40 ||
12607 hfinfo->type == FT_INT48 ||
12608 hfinfo->type == FT_INT56 ||
12609 hfinfo->type == FT_INT64) {
12610
12611 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12612 case BASE_NONE:
12613 case BASE_DEC:
12614 case BASE_HEX:
12615 case BASE_OCT:
12616 case BASE_DEC_HEX:
12617 case BASE_HEX_DEC:
12618 case BASE_CUSTOM:
12619 case BASE_PT_UDP:
12620 case BASE_PT_TCP:
12621 case BASE_PT_DCCP:
12622 case BASE_PT_SCTP:
12623 case BASE_OUI:
12624 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12625 break;
12626 default:
12627 base_name = "????";
12628 break;
12629 }
12630 } else if (hfinfo->type == FT_BOOLEAN) {
12631 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12632 snprintf(width, sizeof(width), "%d", hfinfo->display);
12633 base_name = width;
12634 }
12635
12636 blurb = hfinfo->blurb;
12637 if (blurb == NULL((void*)0))
12638 blurb = "";
12639 else if (strlen(blurb) == 0)
12640 blurb = "\"\"";
12641
12642 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12643 hfinfo->name, hfinfo->abbrev, enum_name,
12644 parent_hfinfo->abbrev, base_name,
12645 hfinfo->bitmask, blurb);
12646 }
12647 }
12648}
12649
12650/* Dumps all abbreviated field and protocol completions of the given string to
12651 * stdout. An independent program may use this for command-line tab completion
12652 * of fields.
12653 */
12654bool_Bool
12655proto_registrar_dump_field_completions(const char *prefix)
12656{
12657 header_field_info *hfinfo;
12658 int i, len;
12659 size_t prefix_len;
12660 bool_Bool matched = false0;
12661
12662 prefix_len = strlen(prefix);
12663 len = gpa_hfinfo.len;
12664 for (i = 1; i < len ; i++) {
12665 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12666 continue; /* This is a deregistered protocol or header field */
12667
12668 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", 12668
, __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", 12668
, "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", 12668, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12669
12670 /*
12671 * Skip the pseudo-field for "proto_tree_add_text()" since
12672 * we don't want it in the list of filterable fields.
12673 */
12674 if (hfinfo->id == hf_text_only)
12675 continue;
12676
12677 /* format for protocols */
12678 if (proto_registrar_is_protocol(i)) {
12679 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12680 matched = true1;
12681 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12682 }
12683 }
12684 /* format for header fields */
12685 else {
12686 /*
12687 * If this field isn't at the head of the list of
12688 * fields with this name, skip this field - all
12689 * fields with the same name are really just versions
12690 * of the same field stored in different bits, and
12691 * should have the same type/radix/value list, and
12692 * just differ in their bit masks. (If a field isn't
12693 * a bitfield, but can be, say, 1 or 2 bytes long,
12694 * it can just be made FT_UINT16, meaning the
12695 * *maximum* length is 2 bytes, and be used
12696 * for all lengths.)
12697 */
12698 if (hfinfo->same_name_prev_id != -1)
12699 continue;
12700
12701 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12702 matched = true1;
12703 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12704 }
12705 }
12706 }
12707 return matched;
12708}
12709
12710/* Dumps field types and descriptive names to stdout. An independent
12711 * program can take this output and format it into nice tables or HTML or
12712 * whatever.
12713 *
12714 * There is one record per line. The fields are tab-delimited.
12715 *
12716 * Field 1 = field type name, e.g. FT_UINT8
12717 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12718 */
12719void
12720proto_registrar_dump_ftypes(void)
12721{
12722 int fte;
12723
12724 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12725 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12726 }
12727}
12728
12729/* This function indicates whether it's possible to construct a
12730 * "match selected" display filter string for the specified field,
12731 * returns an indication of whether it's possible, and, if it's
12732 * possible and "filter" is non-null, constructs the filter and
12733 * sets "*filter" to point to it.
12734 * You do not need to [g_]free() this string since it will be automatically
12735 * freed once the next packet is dissected.
12736 */
12737static bool_Bool
12738construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12739 char **filter)
12740{
12741 const header_field_info *hfinfo;
12742 int start, length, length_remaining;
12743
12744 if (!finfo)
12745 return false0;
12746
12747 hfinfo = finfo->hfinfo;
12748 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12748, "hfinfo"))))
;
12749
12750 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12751 * then "the numeric value ... is not used when preparing
12752 * filters for the field in question." If it's any other
12753 * base, we'll generate the filter normally (which will
12754 * be numeric, even though the human-readable string does
12755 * work for filtering.)
12756 *
12757 * XXX - It might be nice to use fvalue_to_string_repr() in
12758 * "proto_item_fill_label()" as well, although, there, you'd
12759 * have to deal with the base *and* with resolved values for
12760 * addresses.
12761 *
12762 * Perhaps in addition to taking the repr type (DISPLAY
12763 * or DFILTER) and the display (base), fvalue_to_string_repr()
12764 * should have the the "strings" values in the header_field_info
12765 * structure for the field as a parameter, so it can have
12766 * if the field is Boolean or an enumerated integer type,
12767 * the tables used to generate human-readable values.
12768 */
12769 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12770 const char *str = NULL((void*)0);
12771
12772 switch (hfinfo->type) {
12773
12774 case FT_INT8:
12775 case FT_INT16:
12776 case FT_INT24:
12777 case FT_INT32:
12778 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12779 break;
12780
12781 case FT_CHAR:
12782 case FT_UINT8:
12783 case FT_UINT16:
12784 case FT_UINT24:
12785 case FT_UINT32:
12786 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12787 break;
12788
12789 default:
12790 break;
12791 }
12792
12793 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12794 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12795 return true1;
12796 }
12797 }
12798
12799 switch (hfinfo->type) {
12800
12801 case FT_PROTOCOL:
12802 if (filter != NULL((void*)0))
12803 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12804 break;
12805
12806 case FT_NONE:
12807 /*
12808 * If the length is 0, just match the name of the
12809 * field.
12810 *
12811 * (Also check for negative values, just in case,
12812 * as we'll cast it to an unsigned value later.)
12813 */
12814 length = finfo->length;
12815 if (length == 0) {
12816 if (filter != NULL((void*)0))
12817 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12818 break;
12819 }
12820 if (length < 0)
12821 return false0;
12822
12823 /*
12824 * This doesn't have a value, so we'd match
12825 * on the raw bytes at this address.
12826 *
12827 * Should we be allowed to access to the raw bytes?
12828 * If "edt" is NULL, the answer is "no".
12829 */
12830 if (edt == NULL((void*)0))
12831 return false0;
12832
12833 /*
12834 * Is this field part of the raw frame tvbuff?
12835 * If not, we can't use "frame[N:M]" to match
12836 * it.
12837 *
12838 * XXX - should this be frame-relative, or
12839 * protocol-relative?
12840 *
12841 * XXX - does this fallback for non-registered
12842 * fields even make sense?
12843 */
12844 if (finfo->ds_tvb != edt->tvb)
12845 return false0; /* you lose */
12846
12847 /*
12848 * Don't go past the end of that tvbuff.
12849 */
12850 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12851 if (length > length_remaining)
12852 length = length_remaining;
12853 if (length <= 0)
12854 return false0;
12855
12856 if (filter != NULL((void*)0)) {
12857 start = finfo->start;
12858 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12859 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12860 wmem_free(NULL((void*)0), str);
12861 }
12862 break;
12863
12864 /* By default, use the fvalue's "to_string_repr" method. */
12865 default:
12866 if (filter != NULL((void*)0)) {
12867 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12868 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12869 wmem_free(NULL((void*)0), str);
12870 }
12871 break;
12872 }
12873
12874 return true1;
12875}
12876
12877/*
12878 * Returns true if we can do a "match selected" on the field, false
12879 * otherwise.
12880 */
12881bool_Bool
12882proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12883{
12884 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12885}
12886
12887/* This function attempts to construct a "match selected" display filter
12888 * string for the specified field; if it can do so, it returns a pointer
12889 * to the string, otherwise it returns NULL.
12890 *
12891 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12892 */
12893char *
12894proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12895{
12896 char *filter = NULL((void*)0);
12897
12898 if (!construct_match_selected_string(finfo, edt, &filter))
12899 {
12900 wmem_free(NULL((void*)0), filter);
12901 return NULL((void*)0);
12902 }
12903 return filter;
12904}
12905
12906/* This function is common code for all proto_tree_add_bitmask... functions.
12907 */
12908
12909static bool_Bool
12910proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12911 const unsigned len, const int ett, int * const *fields,
12912 const int flags, bool_Bool first,
12913 bool_Bool use_parent_tree,
12914 proto_tree* tree, uint64_t value)
12915{
12916 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12917 uint64_t bitmask = 0;
12918 uint64_t tmpval;
12919 header_field_info *hf;
12920 uint32_t integer32;
12921 int bit_offset;
12922 int no_of_bits;
12923
12924 if (!*fields)
12925 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"
)
;
12926
12927 if (len > 8)
12928 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12929 /**
12930 * packet-frame.c uses len=0 since the value is taken from the packet
12931 * metadata, not the packet bytes. In that case, assume that all bits
12932 * in the provided value are valid.
12933 */
12934 if (len > 0) {
12935 available_bits >>= (8 - len)*8;
12936 }
12937
12938 if (use_parent_tree == false0)
12939 tree = proto_item_add_subtree(item, ett);
12940
12941 while (*fields) {
12942 uint64_t present_bits;
12943 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", 12943, __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", 12943
, "**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", 12943, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12944 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", 12944
, "hf->bitmask != 0", hf->abbrev))))
;
12945
12946 bitmask |= hf->bitmask;
12947
12948 /* Skip fields that aren't fully present */
12949 present_bits = available_bits & hf->bitmask;
12950 if (present_bits != hf->bitmask) {
12951 fields++;
12952 continue;
12953 }
12954
12955 switch (hf->type) {
12956 case FT_CHAR:
12957 case FT_UINT8:
12958 case FT_UINT16:
12959 case FT_UINT24:
12960 case FT_UINT32:
12961 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12962 break;
12963
12964 case FT_INT8:
12965 case FT_INT16:
12966 case FT_INT24:
12967 case FT_INT32:
12968 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12969 break;
12970
12971 case FT_UINT40:
12972 case FT_UINT48:
12973 case FT_UINT56:
12974 case FT_UINT64:
12975 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12976 break;
12977
12978 case FT_INT40:
12979 case FT_INT48:
12980 case FT_INT56:
12981 case FT_INT64:
12982 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12983 break;
12984
12985 case FT_BOOLEAN:
12986 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12987 break;
12988
12989 default:
12990 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))
12991 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))
12992 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))
12993 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))
;
12994 break;
12995 }
12996 if (flags & BMT_NO_APPEND0x01) {
12997 fields++;
12998 continue;
12999 }
13000 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
13001
13002 /* XXX: README.developer and the comments have always defined
13003 * BMT_NO_INT as "only boolean flags are added to the title /
13004 * don't add non-boolean (integral) fields", but the
13005 * implementation has always added BASE_CUSTOM and fields with
13006 * value_strings, though not fields with unit_strings.
13007 * Possibly this is because some dissectors use a FT_UINT8
13008 * with a value_string for fields that should be a FT_BOOLEAN.
13009 */
13010 switch (hf->type) {
13011 case FT_CHAR:
13012 if (hf->display == BASE_CUSTOM) {
13013 char lbl[ITEM_LABEL_LENGTH240];
13014 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13015
13016 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13016, "fmtfunc"))))
;
13017 fmtfunc(lbl, (uint32_t) tmpval);
13018 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13019 hf->name, lbl);
13020 first = false0;
13021 }
13022 else if (hf->strings) {
13023 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13024 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13025 first = false0;
13026 }
13027 else if (!(flags & BMT_NO_INT0x02)) {
13028 char buf[32];
13029 const char *out;
13030
13031 if (!first) {
13032 proto_item_append_text(item, ", ");
13033 }
13034
13035 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13036 proto_item_append_text(item, "%s: %s", hf->name, out);
13037 first = false0;
13038 }
13039
13040 break;
13041
13042 case FT_UINT8:
13043 case FT_UINT16:
13044 case FT_UINT24:
13045 case FT_UINT32:
13046 if (hf->display == BASE_CUSTOM) {
13047 char lbl[ITEM_LABEL_LENGTH240];
13048 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13049
13050 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13050, "fmtfunc"))))
;
13051 fmtfunc(lbl, (uint32_t) tmpval);
13052 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13053 hf->name, lbl);
13054 first = false0;
13055 }
13056 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13057 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13058 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13059 first = false0;
13060 }
13061 else if (!(flags & BMT_NO_INT0x02)) {
13062 char buf[NUMBER_LABEL_LENGTH80];
13063 const char *out = NULL((void*)0);
13064
13065 if (!first) {
13066 proto_item_append_text(item, ", ");
13067 }
13068
13069 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13070 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13071 }
13072 if (out == NULL((void*)0)) {
13073 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13074 }
13075 proto_item_append_text(item, "%s: %s", hf->name, out);
13076 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13077 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13078 }
13079 first = false0;
13080 }
13081
13082 break;
13083
13084 case FT_INT8:
13085 case FT_INT16:
13086 case FT_INT24:
13087 case FT_INT32:
13088 integer32 = (uint32_t) tmpval;
13089 if (hf->bitmask) {
13090 no_of_bits = ws_count_ones(hf->bitmask);
13091 integer32 = ws_sign_ext32(integer32, no_of_bits);
13092 }
13093 if (hf->display == BASE_CUSTOM) {
13094 char lbl[ITEM_LABEL_LENGTH240];
13095 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13096
13097 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13097, "fmtfunc"))))
;
13098 fmtfunc(lbl, (int32_t) integer32);
13099 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13100 hf->name, lbl);
13101 first = false0;
13102 }
13103 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13104 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13105 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13106 first = false0;
13107 }
13108 else if (!(flags & BMT_NO_INT0x02)) {
13109 char buf[NUMBER_LABEL_LENGTH80];
13110 const char *out = NULL((void*)0);
13111
13112 if (!first) {
13113 proto_item_append_text(item, ", ");
13114 }
13115
13116 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13117 out = hf_try_val_to_str((int32_t) integer32, hf);
13118 }
13119 if (out == NULL((void*)0)) {
13120 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13121 }
13122 proto_item_append_text(item, "%s: %s", hf->name, out);
13123 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13124 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13125 }
13126 first = false0;
13127 }
13128
13129 break;
13130
13131 case FT_UINT40:
13132 case FT_UINT48:
13133 case FT_UINT56:
13134 case FT_UINT64:
13135 if (hf->display == BASE_CUSTOM) {
13136 char lbl[ITEM_LABEL_LENGTH240];
13137 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13138
13139 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13139, "fmtfunc"))))
;
13140 fmtfunc(lbl, tmpval);
13141 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13142 hf->name, lbl);
13143 first = false0;
13144 }
13145 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13146 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13147 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13148 first = false0;
13149 }
13150 else if (!(flags & BMT_NO_INT0x02)) {
13151 char buf[NUMBER_LABEL_LENGTH80];
13152 const char *out = NULL((void*)0);
13153
13154 if (!first) {
13155 proto_item_append_text(item, ", ");
13156 }
13157
13158 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13159 out = hf_try_val64_to_str(tmpval, hf);
13160 }
13161 if (out == NULL((void*)0)) {
13162 out = hfinfo_number_value_format64(hf, buf, tmpval);
13163 }
13164 proto_item_append_text(item, "%s: %s", hf->name, out);
13165 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13166 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13167 }
13168 first = false0;
13169 }
13170
13171 break;
13172
13173 case FT_INT40:
13174 case FT_INT48:
13175 case FT_INT56:
13176 case FT_INT64:
13177 if (hf->bitmask) {
13178 no_of_bits = ws_count_ones(hf->bitmask);
13179 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13180 }
13181 if (hf->display == BASE_CUSTOM) {
13182 char lbl[ITEM_LABEL_LENGTH240];
13183 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13184
13185 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13185, "fmtfunc"))))
;
13186 fmtfunc(lbl, (int64_t) tmpval);
13187 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13188 hf->name, lbl);
13189 first = false0;
13190 }
13191 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13192 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13193 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13194 first = false0;
13195 }
13196 else if (!(flags & BMT_NO_INT0x02)) {
13197 char buf[NUMBER_LABEL_LENGTH80];
13198 const char *out = NULL((void*)0);
13199
13200 if (!first) {
13201 proto_item_append_text(item, ", ");
13202 }
13203
13204 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13205 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13206 }
13207 if (out == NULL((void*)0)) {
13208 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13209 }
13210 proto_item_append_text(item, "%s: %s", hf->name, out);
13211 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13212 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13213 }
13214 first = false0;
13215 }
13216
13217 break;
13218
13219 case FT_BOOLEAN:
13220 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13221 /* If we have true/false strings, emit full - otherwise messages
13222 might look weird */
13223 const struct true_false_string *tfs =
13224 (const struct true_false_string *)hf->strings;
13225
13226 if (tmpval) {
13227 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13228 hf->name, tfs->true_string);
13229 first = false0;
13230 } else if (!(flags & BMT_NO_FALSE0x04)) {
13231 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13232 hf->name, tfs->false_string);
13233 first = false0;
13234 }
13235 } else if (hf->bitmask & value) {
13236 /* If the flag is set, show the name */
13237 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13238 first = false0;
13239 }
13240 break;
13241 default:
13242 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))
13243 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))
13244 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))
13245 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))
;
13246 break;
13247 }
13248
13249 fields++;
13250 }
13251
13252 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13253 * but then again most dissectors don't set the bitmask field for
13254 * the higher level bitmask hfi, so calculate the bitmask from the
13255 * fields present. */
13256 if (item) {
13257 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13258 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13259 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)
;
13260 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)
;
13261 }
13262 return first;
13263}
13264
13265/* This function will dissect a sequence of bytes that describe a
13266 * bitmask and supply the value of that sequence through a pointer.
13267 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13268 * to be dissected.
13269 * This field will form an expansion under which the individual fields of the
13270 * bitmask is dissected and displayed.
13271 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13272 *
13273 * fields is an array of pointers to int that lists all the fields of the
13274 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13275 * or another integer of the same type/size as hf_hdr with a mask specified.
13276 * This array is terminated by a NULL entry.
13277 *
13278 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13279 * FT_integer fields that have a value_string attached will have the
13280 * matched string displayed on the expansion line.
13281 */
13282proto_item *
13283proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13284 const unsigned offset, const int hf_hdr,
13285 const int ett, int * const *fields,
13286 const unsigned encoding, uint64_t *retval)
13287{
13288 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);
13289}
13290
13291/* This function will dissect a sequence of bytes that describe a
13292 * bitmask.
13293 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13294 * to be dissected.
13295 * This field will form an expansion under which the individual fields of the
13296 * bitmask is dissected and displayed.
13297 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13298 *
13299 * fields is an array of pointers to int that lists all the fields of the
13300 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13301 * or another integer of the same type/size as hf_hdr with a mask specified.
13302 * This array is terminated by a NULL entry.
13303 *
13304 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13305 * FT_integer fields that have a value_string attached will have the
13306 * matched string displayed on the expansion line.
13307 */
13308proto_item *
13309proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13310 const unsigned offset, const int hf_hdr,
13311 const int ett, int * const *fields,
13312 const unsigned encoding)
13313{
13314 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13315}
13316
13317/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13318 * what data is appended to the header.
13319 */
13320proto_item *
13321proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13322 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13323 uint64_t *retval)
13324{
13325 proto_item *item = NULL((void*)0);
13326 header_field_info *hf;
13327 unsigned len;
13328 uint64_t value;
13329
13330 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", 13330, __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", 13330
, "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", 13330, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13331 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", 13331, (hf)->abbrev)))
;
13332 len = ftype_wire_size(hf->type);
13333 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13334
13335 if (parent_tree) {
13336 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13337 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13338 flags, false0, false0, NULL((void*)0), value);
13339 }
13340
13341 *retval = value;
13342 if (hf->bitmask) {
13343 /* Mask out irrelevant portions */
13344 *retval &= hf->bitmask;
13345 /* Shift bits */
13346 *retval >>= hfinfo_bitshift(hf);
13347 }
13348
13349 return item;
13350}
13351
13352/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13353 * what data is appended to the header.
13354 */
13355proto_item *
13356proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13357 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13358{
13359 proto_item *item = NULL((void*)0);
13360 header_field_info *hf;
13361 unsigned len;
13362 uint64_t value;
13363
13364 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", 13364, __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", 13364
, "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", 13364, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13365 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", 13365, (hf)->abbrev)))
;
13366
13367 if (parent_tree) {
13368 len = ftype_wire_size(hf->type);
13369 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13370 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13371 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13372 flags, false0, false0, NULL((void*)0), value);
13373 }
13374
13375 return item;
13376}
13377
13378/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13379 can't be retrieved directly from tvb) */
13380proto_item *
13381proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13382 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13383{
13384 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13385 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13386}
13387
13388/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13389WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13390proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13391 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13392{
13393 proto_item *item = NULL((void*)0);
13394 header_field_info *hf;
13395 unsigned len;
13396
13397 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", 13397, __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", 13397
, "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", 13397, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13398 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", 13398, (hf)->abbrev)))
;
13399 /* the proto_tree_add_uint/_uint64() calls below
13400 will fail if tvb==NULL and len!=0 */
13401 len = tvb ? ftype_wire_size(hf->type) : 0;
13402
13403 if (parent_tree) {
13404 if (len <= 4)
13405 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13406 else
13407 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13408
13409 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13410 flags, false0, false0, NULL((void*)0), value);
13411 }
13412
13413 return item;
13414}
13415
13416/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13417void
13418proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13419 const unsigned len, int * const *fields, const unsigned encoding)
13420{
13421 uint64_t value;
13422
13423 if (tree) {
13424 value = get_uint64_value(tree, tvb, offset, len, encoding);
13425 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13426 BMT_NO_APPEND0x01, false0, true1, tree, value);
13427 }
13428}
13429
13430WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13431proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13432 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13433{
13434 uint64_t value;
13435
13436 value = get_uint64_value(tree, tvb, offset, len, encoding);
13437 if (tree) {
13438 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13439 BMT_NO_APPEND0x01, false0, true1, tree, value);
13440 }
13441 if (retval) {
13442 *retval = value;
13443 }
13444}
13445
13446WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13447proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13448 const unsigned len, int * const *fields, const uint64_t value)
13449{
13450 if (tree) {
13451 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13452 BMT_NO_APPEND0x01, false0, true1, tree, value);
13453 }
13454}
13455
13456
13457/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13458 * This is intended to support bitmask fields whose lengths can vary, perhaps
13459 * as the underlying standard evolves over time.
13460 * With this API there is the possibility of being called to display more or
13461 * less data than the dissector was coded to support.
13462 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13463 * Thus when presented with "too much" or "too little" data, MSbits will be
13464 * ignored or MSfields sacrificed.
13465 *
13466 * Only fields for which all defined bits are available are displayed.
13467 */
13468proto_item *
13469proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13470 const unsigned offset, const unsigned len, const int hf_hdr,
13471 const int ett, int * const *fields, struct expert_field* exp,
13472 const unsigned encoding)
13473{
13474 proto_item *item = NULL((void*)0);
13475 header_field_info *hf;
13476 unsigned decodable_len;
13477 unsigned decodable_offset;
13478 uint32_t decodable_value;
13479 uint64_t value;
13480
13481 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", 13481, __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", 13481
, "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", 13481, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13482 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", 13482, (hf)->abbrev)))
;
13483
13484 decodable_offset = offset;
13485 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13486
13487 /* If we are ftype_wire_size-limited,
13488 * make sure we decode as many LSBs as possible.
13489 */
13490 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13491 decodable_offset += (len - decodable_len);
13492 }
13493
13494 if (parent_tree) {
13495 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13496 decodable_len, encoding);
13497
13498 /* The root item covers all the bytes even if we can't decode them all */
13499 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13500 decodable_value);
13501 }
13502
13503 if (decodable_len < len) {
13504 /* Dissector likely requires updating for new protocol revision */
13505 expert_add_info_format(NULL((void*)0), item, exp,
13506 "Only least-significant %d of %d bytes decoded",
13507 decodable_len, len);
13508 }
13509
13510 if (item) {
13511 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13512 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13513 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13514 }
13515
13516 return item;
13517}
13518
13519/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13520proto_item *
13521proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13522 const unsigned offset, const unsigned len,
13523 const char *name, const char *fallback,
13524 const int ett, int * const *fields,
13525 const unsigned encoding, const int flags)
13526{
13527 proto_item *item = NULL((void*)0);
13528 uint64_t value;
13529
13530 if (parent_tree) {
13531 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13532 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13533 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13534 flags, true1, false0, NULL((void*)0), value) && fallback) {
13535 /* Still at first item - append 'fallback' text if any */
13536 proto_item_append_text(item, "%s", fallback);
13537 }
13538 }
13539
13540 return item;
13541}
13542
13543proto_item *
13544proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13545 const unsigned bit_offset, const int no_of_bits,
13546 const unsigned encoding)
13547{
13548 header_field_info *hfinfo;
13549 int octet_length;
13550 unsigned octet_offset;
13551
13552 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", 13552, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13552
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13552, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13553
13554 if (no_of_bits < 0) {
13555 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13556 }
13557 octet_length = (no_of_bits + 7) >> 3;
13558 octet_offset = bit_offset >> 3;
13559 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13560
13561 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13562 * but only after doing a bunch more work (which we can, in the common
13563 * case, shortcut here).
13564 */
13565 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13566 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", 13566
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13566, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13566, "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", 13566, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13567
13568 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13569}
13570
13571/*
13572 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13573 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13574 * Offset should be given in bits from the start of the tvb.
13575 */
13576
13577static proto_item *
13578_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13579 const unsigned bit_offset, const int no_of_bits,
13580 uint64_t *return_value, const unsigned encoding)
13581{
13582 unsigned offset;
13583 unsigned length;
13584 uint8_t tot_no_bits;
13585 char *bf_str;
13586 char lbl_str[ITEM_LABEL_LENGTH240];
13587 uint64_t value = 0;
13588 uint8_t *bytes = NULL((void*)0);
13589 size_t bytes_length = 0;
13590
13591 proto_item *pi;
13592 header_field_info *hf_field;
13593
13594 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13595 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", 13595, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13595
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13595, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13596
13597 if (hf_field->bitmask != 0) {
13598 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)
13599 " 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)
13600 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)
;
13601 }
13602
13603 if (no_of_bits < 0) {
13604 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13605 } else if (no_of_bits == 0) {
13606 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)
13607 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)
;
13608 }
13609
13610 /* Byte align offset */
13611 offset = bit_offset>>3;
13612
13613 /*
13614 * Calculate the number of octets used to hold the bits
13615 */
13616 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13617 length = (tot_no_bits + 7) >> 3;
13618
13619 if (no_of_bits < 65) {
13620 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13621 } else if (hf_field->type != FT_BYTES) {
13622 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)
13623 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)
;
13624 return NULL((void*)0);
13625 }
13626
13627 /* Sign extend for signed types */
13628 switch (hf_field->type) {
13629 case FT_INT8:
13630 case FT_INT16:
13631 case FT_INT24:
13632 case FT_INT32:
13633 case FT_INT40:
13634 case FT_INT48:
13635 case FT_INT56:
13636 case FT_INT64:
13637 value = ws_sign_ext64(value, no_of_bits);
13638 break;
13639
13640 default:
13641 break;
13642 }
13643
13644 if (return_value) {
13645 *return_value = value;
13646 }
13647
13648 /* Coast clear. Try and fake it */
13649 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13650 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", 13650
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13650, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13650, "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", 13650, __func__, "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); } } }
;
13651
13652 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13653
13654 switch (hf_field->type) {
13655 case FT_BOOLEAN:
13656 /* Boolean field */
13657 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13658 "%s = %s: %s",
13659 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13660 break;
13661
13662 case FT_CHAR:
13663 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13664 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13665 break;
13666
13667 case FT_UINT8:
13668 case FT_UINT16:
13669 case FT_UINT24:
13670 case FT_UINT32:
13671 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13672 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13673 break;
13674
13675 case FT_INT8:
13676 case FT_INT16:
13677 case FT_INT24:
13678 case FT_INT32:
13679 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13680 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13681 break;
13682
13683 case FT_UINT40:
13684 case FT_UINT48:
13685 case FT_UINT56:
13686 case FT_UINT64:
13687 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13688 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13689 break;
13690
13691 case FT_INT40:
13692 case FT_INT48:
13693 case FT_INT56:
13694 case FT_INT64:
13695 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13696 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13697 break;
13698
13699 case FT_BYTES:
13700 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13701 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13702 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13703 proto_item_set_text(pi, "%s", lbl_str);
13704 return pi;
13705
13706 /* TODO: should handle FT_UINT_BYTES ? */
13707
13708 default:
13709 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))
13710 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))
13711 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))
13712 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))
;
13713 return NULL((void*)0);
13714 }
13715
13716 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13717 return pi;
13718}
13719
13720proto_item *
13721proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13722 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13723 uint64_t *return_value)
13724{
13725 proto_item *pi;
13726 int no_of_bits;
13727 unsigned octet_offset;
13728 unsigned mask_initial_bit_offset;
13729 unsigned mask_greatest_bit_offset;
13730 unsigned octet_length;
13731 uint8_t i;
13732 char bf_str[256];
13733 char lbl_str[ITEM_LABEL_LENGTH240];
13734 uint64_t value;
13735 uint64_t composite_bitmask;
13736 uint64_t composite_bitmap;
13737
13738 header_field_info *hf_field;
13739
13740 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13741 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", 13741, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13741
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13741, "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
13742
13743 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13744 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)
13745 " 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)
13746 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)
;
13747 }
13748
13749 mask_initial_bit_offset = bit_offset % 8;
13750
13751 no_of_bits = 0;
13752 value = 0;
13753 i = 0;
13754 mask_greatest_bit_offset = 0;
13755 composite_bitmask = 0;
13756 composite_bitmap = 0;
13757
13758 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
13759 uint64_t crumb_mask, crumb_value;
13760 uint8_t crumb_end_bit_offset;
13761
13762 crumb_value = tvb_get_bits64(tvb,
13763 bit_offset + crumb_spec[i].crumb_bit_offset,
13764 crumb_spec[i].crumb_bit_length,
13765 ENC_BIG_ENDIAN0x00000000);
13766 value += crumb_value;
13767 no_of_bits += crumb_spec[i].crumb_bit_length;
13768 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", 13768
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13769
13770 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13771 octet containing the initial offset.
13772 If the mask is beyond 32 bits, then give up on bit map display.
13773 This could be improved in future, probably showing a table
13774 of 32 or 64 bits per row */
13775 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13776 crumb_end_bit_offset = mask_initial_bit_offset
13777 + crumb_spec[i].crumb_bit_offset
13778 + crumb_spec[i].crumb_bit_length;
13779 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'
13780
13781 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13782 mask_greatest_bit_offset = crumb_end_bit_offset;
13783 }
13784 /* Currently the bitmap of the crumbs are only shown if
13785 * smaller than 32 bits. Do not bother calculating the
13786 * mask if it is larger than that. */
13787 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13788 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'
13789 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13790 }
13791 }
13792 /* Shift left for the next segment */
13793 value <<= crumb_spec[++i].crumb_bit_length;
13794 }
13795
13796 /* Sign extend for signed types */
13797 switch (hf_field->type) {
13798 case FT_INT8:
13799 case FT_INT16:
13800 case FT_INT24:
13801 case FT_INT32:
13802 case FT_INT40:
13803 case FT_INT48:
13804 case FT_INT56:
13805 case FT_INT64:
13806 value = ws_sign_ext64(value, no_of_bits);
13807 break;
13808 default:
13809 break;
13810 }
13811
13812 if (return_value) {
13813 *return_value = value;
13814 }
13815
13816 /* Coast clear. Try and fake it */
13817 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13818 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", 13818
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13818, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13818, "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", 13818, __func__, "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); } } }
;
13819
13820 /* initialise the format string */
13821 bf_str[0] = '\0';
13822
13823 octet_offset = bit_offset >> 3;
13824
13825 /* Round up mask length to nearest octet */
13826 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13827 mask_greatest_bit_offset = octet_length << 3;
13828
13829 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13830 It would be a useful enhancement to eliminate this restriction. */
13831 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13832 other_decode_bitfield_value(bf_str,
13833 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13834 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13835 mask_greatest_bit_offset);
13836 } else {
13837 /* If the bitmask is too large, try to describe its contents. */
13838 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13839 }
13840
13841 switch (hf_field->type) {
13842 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13843 /* Boolean field */
13844 return proto_tree_add_boolean_format(tree, hfindex,
13845 tvb, octet_offset, octet_length, value,
13846 "%s = %s: %s",
13847 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13848 break;
13849
13850 case FT_CHAR:
13851 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13852 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13853 break;
13854
13855 case FT_UINT8:
13856 case FT_UINT16:
13857 case FT_UINT24:
13858 case FT_UINT32:
13859 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13860 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13861 break;
13862
13863 case FT_INT8:
13864 case FT_INT16:
13865 case FT_INT24:
13866 case FT_INT32:
13867 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13868 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13869 break;
13870
13871 case FT_UINT40:
13872 case FT_UINT48:
13873 case FT_UINT56:
13874 case FT_UINT64:
13875 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13876 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13877 break;
13878
13879 case FT_INT40:
13880 case FT_INT48:
13881 case FT_INT56:
13882 case FT_INT64:
13883 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13884 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13885 break;
13886
13887 default:
13888 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))
13889 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))
13890 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))
13891 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))
;
13892 return NULL((void*)0);
13893 }
13894 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13895 return pi;
13896}
13897
13898void
13899proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13900 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13901{
13902 header_field_info *hfinfo;
13903 unsigned start = bit_offset >> 3;
13904 unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13905
13906 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13907 * so that we can use the tree's memory scope in calculating the string */
13908 tvb_ensure_bytes_exist(tvb, start, length);
13909 if (!tree) return;
13910
13911 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", 13911, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13911
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13911, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13912 proto_tree_add_text_internal(tree, tvb, start, length,
13913 "%s crumb %d of %s (decoded above)",
13914 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13915 tvb_get_bits32(tvb,
13916 bit_offset,
13917 crumb_spec[crumb_index].crumb_bit_length,
13918 ENC_BIG_ENDIAN0x00000000),
13919 ENC_BIG_ENDIAN0x00000000),
13920 crumb_index,
13921 hfinfo->name);
13922}
13923
13924proto_item *
13925proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13926 const unsigned bit_offset, const int no_of_bits,
13927 uint64_t *return_value, const unsigned encoding)
13928{
13929 proto_item *item;
13930
13931 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13932 bit_offset, no_of_bits,
13933 return_value, encoding))) {
13934 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)
;
13935 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)
;
13936 }
13937 return item;
13938}
13939
13940static proto_item *
13941_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13942 tvbuff_t *tvb, const unsigned bit_offset,
13943 const int no_of_bits, void *value_ptr,
13944 const unsigned encoding, char *value_str)
13945{
13946 unsigned offset;
13947 unsigned length;
13948 uint8_t tot_no_bits;
13949 char *str;
13950 uint64_t value = 0;
13951 header_field_info *hf_field;
13952
13953 /* We do not have to return a value, try to fake it as soon as possible */
13954 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13955 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", 13955
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13955, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13955, "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", 13955, __func__, "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); } } }
;
13956
13957 if (hf_field->bitmask != 0) {
13958 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)
13959 " 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)
13960 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)
;
13961 }
13962
13963 if (no_of_bits < 0) {
13964 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13965 } else if (no_of_bits == 0) {
13966 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)
13967 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)
;
13968 }
13969
13970 /* Byte align offset */
13971 offset = bit_offset>>3;
13972
13973 /*
13974 * Calculate the number of octets used to hold the bits
13975 */
13976 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13977 length = tot_no_bits>>3;
13978 /* If we are using part of the next octet, increase length by 1 */
13979 if (tot_no_bits & 0x07)
13980 length++;
13981
13982 if (no_of_bits < 65) {
13983 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13984 } else {
13985 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)
13986 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)
;
13987 return NULL((void*)0);
13988 }
13989
13990 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13991
13992 (void) g_strlcat(str, " = ", 256+64);
13993 (void) g_strlcat(str, hf_field->name, 256+64);
13994
13995 /*
13996 * This function does not receive an actual value but a dimensionless pointer to that value.
13997 * For this reason, the type of the header field is examined in order to determine
13998 * what kind of value we should read from this address.
13999 * The caller of this function must make sure that for the specific header field type the address of
14000 * a compatible value is provided.
14001 */
14002 switch (hf_field->type) {
14003 case FT_BOOLEAN:
14004 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14005 "%s: %s", str, value_str);
14006 break;
14007
14008 case FT_CHAR:
14009 case FT_UINT8:
14010 case FT_UINT16:
14011 case FT_UINT24:
14012 case FT_UINT32:
14013 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
14014 "%s: %s", str, value_str);
14015 break;
14016
14017 case FT_UINT40:
14018 case FT_UINT48:
14019 case FT_UINT56:
14020 case FT_UINT64:
14021 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14022 "%s: %s", str, value_str);
14023 break;
14024
14025 case FT_INT8:
14026 case FT_INT16:
14027 case FT_INT24:
14028 case FT_INT32:
14029 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
14030 "%s: %s", str, value_str);
14031 break;
14032
14033 case FT_INT40:
14034 case FT_INT48:
14035 case FT_INT56:
14036 case FT_INT64:
14037 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14038 "%s: %s", str, value_str);
14039 break;
14040
14041 case FT_FLOAT:
14042 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14043 "%s: %s", str, value_str);
14044 break;
14045
14046 default:
14047 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))
14048 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))
14049 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))
14050 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))
;
14051 return NULL((void*)0);
14052 }
14053}
14054
14055static proto_item *
14056proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14057 tvbuff_t *tvb, const unsigned bit_offset,
14058 const int no_of_bits, void *value_ptr,
14059 const unsigned encoding, char *value_str)
14060{
14061 proto_item *item;
14062
14063 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14064 tvb, bit_offset, no_of_bits,
14065 value_ptr, encoding, value_str))) {
14066 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)
;
14067 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)
;
14068 }
14069 return item;
14070}
14071
14072#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);
\
14073 va_start(ap, format)__builtin_va_start(ap, format); \
14074 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14075 va_end(ap)__builtin_va_end(ap);
14076
14077proto_item *
14078proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14079 tvbuff_t *tvb, const unsigned bit_offset,
14080 const int no_of_bits, uint32_t value,
14081 const unsigned encoding,
14082 const char *format, ...)
14083{
14084 va_list ap;
14085 char *dst;
14086 header_field_info *hf_field;
14087
14088 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14089
14090 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", 14090
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14090, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14090, "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", 14090, __func__, "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); } } }
;
14091
14092 switch (hf_field->type) {
14093 case FT_UINT8:
14094 case FT_UINT16:
14095 case FT_UINT24:
14096 case FT_UINT32:
14097 break;
14098
14099 default:
14100 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)
14101 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)
;
14102 return NULL((void*)0);
14103 }
14104
14105 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);
;
14106
14107 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14108}
14109
14110proto_item *
14111proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14112 tvbuff_t *tvb, const unsigned bit_offset,
14113 const int no_of_bits, uint64_t value,
14114 const unsigned encoding,
14115 const char *format, ...)
14116{
14117 va_list ap;
14118 char *dst;
14119 header_field_info *hf_field;
14120
14121 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14122
14123 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", 14123
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14123, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14123, "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", 14123, __func__, "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); } } }
;
14124
14125 switch (hf_field->type) {
14126 case FT_UINT40:
14127 case FT_UINT48:
14128 case FT_UINT56:
14129 case FT_UINT64:
14130 break;
14131
14132 default:
14133 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)
14134 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)
;
14135 return NULL((void*)0);
14136 }
14137
14138 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);
;
14139
14140 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14141}
14142
14143proto_item *
14144proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14145 tvbuff_t *tvb, const unsigned bit_offset,
14146 const int no_of_bits, float value,
14147 const unsigned encoding,
14148 const char *format, ...)
14149{
14150 va_list ap;
14151 char *dst;
14152 header_field_info *hf_field;
14153
14154 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14155
14156 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", 14156
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14156, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14156, "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", 14156, __func__, "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); } } }
;
14157
14158 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",
14158, ((hf_field))->abbrev))))
;
14159
14160 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);
;
14161
14162 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14163}
14164
14165proto_item *
14166proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14167 tvbuff_t *tvb, const unsigned bit_offset,
14168 const int no_of_bits, int32_t value,
14169 const unsigned encoding,
14170 const char *format, ...)
14171{
14172 va_list ap;
14173 char *dst;
14174 header_field_info *hf_field;
14175
14176 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14177
14178 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", 14178
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14178, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14178, "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", 14178, __func__, "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); } } }
;
14179
14180 switch (hf_field->type) {
14181 case FT_INT8:
14182 case FT_INT16:
14183 case FT_INT24:
14184 case FT_INT32:
14185 break;
14186
14187 default:
14188 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)
14189 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)
;
14190 return NULL((void*)0);
14191 }
14192
14193 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);
;
14194
14195 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14196}
14197
14198proto_item *
14199proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14200 tvbuff_t *tvb, const unsigned bit_offset,
14201 const int no_of_bits, int64_t value,
14202 const unsigned encoding,
14203 const char *format, ...)
14204{
14205 va_list ap;
14206 char *dst;
14207 header_field_info *hf_field;
14208
14209 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14210
14211 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", 14211
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14211, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14211, "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", 14211, __func__, "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); } } }
;
14212
14213 switch (hf_field->type) {
14214 case FT_INT40:
14215 case FT_INT48:
14216 case FT_INT56:
14217 case FT_INT64:
14218 break;
14219
14220 default:
14221 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)
14222 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)
;
14223 return NULL((void*)0);
14224 }
14225
14226 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);
;
14227
14228 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14229}
14230
14231proto_item *
14232proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14233 tvbuff_t *tvb, const unsigned bit_offset,
14234 const int no_of_bits, uint64_t value,
14235 const unsigned encoding,
14236 const char *format, ...)
14237{
14238 va_list ap;
14239 char *dst;
14240 header_field_info *hf_field;
14241
14242 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14243
14244 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", 14244
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14244, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14244, "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", 14244, __func__, "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); } } }
;
14245
14246 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"
, 14246, ((hf_field))->abbrev))))
;
14247
14248 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);
;
14249
14250 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14251}
14252
14253proto_item *
14254proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14255 const unsigned bit_offset, const int no_of_chars)
14256{
14257 proto_item *pi;
14258 header_field_info *hfinfo;
14259 int byte_length;
14260 unsigned byte_offset;
14261 char *string;
14262
14263 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14264
14265 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", 14265
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14265, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14265, "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", 14265, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14266
14267 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"
, 14267, ((hfinfo))->abbrev))))
;
14268
14269 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14270 byte_offset = bit_offset >> 3;
14271
14272 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14273
14274 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14275 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14275, "byte_length >= 0"
))))
;
14276 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14277
14278 return pi;
14279}
14280
14281proto_item *
14282proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14283 const unsigned bit_offset, const int no_of_chars)
14284{
14285 proto_item *pi;
14286 header_field_info *hfinfo;
14287 int byte_length;
14288 unsigned byte_offset;
14289 char *string;
14290
14291 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14292
14293 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", 14293
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14293, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14293, "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", 14293, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14294
14295 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"
, 14295, ((hfinfo))->abbrev))))
;
14296
14297 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14298 byte_offset = bit_offset >> 3;
14299
14300 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14301
14302 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14303 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14303, "byte_length >= 0"
))))
;
14304 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14305
14306 return pi;
14307}
14308
14309const value_string proto_checksum_vals[] = {
14310 { PROTO_CHECKSUM_E_BAD, "Bad" },
14311 { PROTO_CHECKSUM_E_GOOD, "Good" },
14312 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14313 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14314 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14315
14316 { 0, NULL((void*)0) }
14317};
14318
14319#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14320
14321proto_item *
14322proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14323 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14324 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14325{
14326 header_field_info *hfinfo;
14327 uint32_t checksum;
14328 uint32_t len;
14329 proto_item* ti = NULL((void*)0);
14330 proto_item* ti2;
14331 bool_Bool incorrect_checksum = true1;
14332
14333 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", 14333, __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", 14333
, "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", 14333, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14334
14335 switch (hfinfo->type) {
14336 case FT_UINT8:
14337 len = 1;
14338 break;
14339 case FT_UINT16:
14340 len = 2;
14341 break;
14342 case FT_UINT24:
14343 len = 3;
14344 break;
14345 case FT_UINT32:
14346 len = 4;
14347 break;
14348 default:
14349 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)
14350 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14351 }
14352
14353 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14354 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14355 proto_item_set_generated(ti);
14356 // Backward compatible with use of -1
14357 if (hf_checksum_status > 0) {
14358 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14359 proto_item_set_generated(ti2);
14360 }
14361 return ti;
14362 }
14363
14364 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14365 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14366 proto_item_set_generated(ti);
14367 } else {
14368 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14369 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14370 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14371 if (computed_checksum == 0) {
14372 proto_item_append_text(ti, " [correct]");
14373 // Backward compatible with use of -1
14374 if (hf_checksum_status > 0) {
14375 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14376 proto_item_set_generated(ti2);
14377 }
14378 incorrect_checksum = false0;
14379 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14380 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14381 /* XXX - This can't distinguish between "shouldbe"
14382 * 0x0000 and 0xFFFF unless we know whether there
14383 * were any nonzero bits (other than the checksum).
14384 * Protocols should not use this path if they might
14385 * have an all zero packet.
14386 * Some implementations put the wrong zero; maybe
14387 * we should have a special expert info for that?
14388 */
14389 }
14390 } else {
14391 if (checksum == computed_checksum) {
14392 proto_item_append_text(ti, " [correct]");
14393 // Backward compatible with use of -1
14394 if (hf_checksum_status > 0) {
14395 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14396 proto_item_set_generated(ti2);
14397 }
14398 incorrect_checksum = false0;
14399 }
14400 }
14401
14402 if (incorrect_checksum) {
14403 // Backward compatible with use of -1
14404 if (hf_checksum_status > 0) {
14405 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14406 proto_item_set_generated(ti2);
14407 }
14408 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14409 proto_item_append_text(ti, " [incorrect]");
14410 if (bad_checksum_expert != NULL((void*)0))
14411 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14412 } else {
14413 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14414 if (bad_checksum_expert != NULL((void*)0))
14415 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);
14416 }
14417 }
14418 } else {
14419 // Backward compatible with use of -1
14420 if (hf_checksum_status > 0) {
14421 proto_item_append_text(ti, " [unverified]");
14422 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14423 proto_item_set_generated(ti2);
14424 }
14425 }
14426 }
14427
14428 return ti;
14429}
14430
14431proto_item *
14432proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14433 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14434 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14435{
14436 header_field_info *hfinfo;
14437 uint8_t *checksum = NULL((void*)0);
14438 proto_item* ti = NULL((void*)0);
14439 proto_item* ti2;
14440 bool_Bool incorrect_checksum = true1;
14441
14442 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", 14442, __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", 14442
, "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", 14442, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14443
14444 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",
14444, ((hfinfo))->abbrev))))
;
14445
14446 /* Make sure a NULL computed_checksum isn't dereferenced.
14447 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14448 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14449 * cases the behavior is unexpected and still a programmer error;
14450 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14451 * _NOT_PRESENT nor _GENERATED is correct.
14452 */
14453 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", 14453, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14454
14455 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14456 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14457 proto_item_set_generated(ti);
14458 // Backward compatible with use of -1
14459 if (hf_checksum_status > 0) {
14460 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14461 proto_item_set_generated(ti2);
14462 }
14463 return ti;
14464 }
14465
14466 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14467 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14468 proto_item_set_generated(ti);
14469 return ti;
14470 }
14471
14472 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14473 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14474 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14475 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14476 bool_Bool non_zero_flag = false0;
14477 for (size_t index = 0; index < checksum_len; index++) {
14478 if (computed_checksum[index]) {
14479 non_zero_flag = true1;
14480 break;
14481 }
14482 }
14483 if (!non_zero_flag) {
14484 proto_item_append_text(ti, " [correct]");
14485 // Backward compatible with use of -1
14486 if (hf_checksum_status > 0) {
14487 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14488 proto_item_set_generated(ti2);
14489 }
14490 incorrect_checksum = false0;
14491 }
14492 } else {
14493 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14494 proto_item_append_text(ti, " [correct]");
14495 // Backward compatible with use of -1
14496 if (hf_checksum_status > 0) {
14497 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14498 proto_item_set_generated(ti2);
14499 }
14500 incorrect_checksum = false0;
14501 }
14502 }
14503
14504 if (incorrect_checksum) {
14505 // Backward compatible with use of -1
14506 if (hf_checksum_status > 0) {
14507 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14508 proto_item_set_generated(ti2);
14509 }
14510 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14511 proto_item_append_text(ti, " [incorrect]");
14512 if (bad_checksum_expert != NULL((void*)0))
14513 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14514 } else {
14515 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14516 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14517 if (bad_checksum_expert != NULL((void*)0))
14518 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14519 }
14520 }
14521 } else {
14522 // Backward compatible with use of -1
14523 if (hf_checksum_status > 0) {
14524 proto_item_append_text(ti, " [unverified]");
14525 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14526 proto_item_set_generated(ti2);
14527 }
14528 }
14529
14530 return ti;
14531}
14532
14533unsigned char
14534proto_check_field_name(const char *field_name)
14535{
14536 return module_check_valid_name(field_name, false0);
14537}
14538
14539unsigned char
14540proto_check_field_name_lower(const char *field_name)
14541{
14542 return module_check_valid_name(field_name, true1);
14543}
14544
14545bool_Bool
14546tree_expanded(int tree_type)
14547{
14548 if (tree_type <= 0) {
14549 return false0;
14550 }
14551 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", 14551, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14552 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14553}
14554
14555void
14556tree_expanded_set(int tree_type, bool_Bool value)
14557{
14558 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", 14558, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14559
14560 if (value)
14561 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14562 else
14563 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14564}
14565
14566/*
14567 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14568 *
14569 * Local variables:
14570 * c-basic-offset: 8
14571 * tab-width: 8
14572 * indent-tabs-mode: t
14573 * End:
14574 *
14575 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14576 * :indentSize=8:tabSize=8:noTabs=false:
14577 */