Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13683, 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-06-05-100346-3529-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <[email protected]>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const int start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 int start, int *length);
300
301static void
302proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303static void
304proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305
306static void
307proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308static void
309proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310static void
311proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
312static void
313proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314static void
315proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316static void
317proto_tree_set_string(field_info *fi, const char* value);
318static void
319proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_vines(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ether(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
330static void
331proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332static void
333proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334static void
335proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336static void
337proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
338static void
339proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342static void
343proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
344static void
345proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350static void
351proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
352static void
353proto_tree_set_boolean(field_info *fi, uint64_t value);
354static void
355proto_tree_set_float(field_info *fi, float value);
356static void
357proto_tree_set_double(field_info *fi, double value);
358static void
359proto_tree_set_uint(field_info *fi, uint32_t value);
360static void
361proto_tree_set_int(field_info *fi, int32_t value);
362static void
363proto_tree_set_uint64(field_info *fi, uint64_t value);
364static void
365proto_tree_set_int64(field_info *fi, int64_t value);
366static void
367proto_tree_set_eui64(field_info *fi, const uint64_t value);
368static void
369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
370
371/* Handle type length mismatch (now filterable) expert info */
372static int proto_type_length_mismatch;
373static expert_field ei_type_length_mismatch_error;
374static expert_field ei_type_length_mismatch_warn;
375static void register_type_length_mismatch(void);
376
377/* Handle byte array string decoding errors with expert info */
378static int proto_byte_array_string_decoding_error;
379static expert_field ei_byte_array_string_decoding_failed_error;
380static void register_byte_array_string_decodinws_error(void);
381
382/* Handle date and time string decoding errors with expert info */
383static int proto_date_time_string_decoding_error;
384static expert_field ei_date_time_string_decoding_failed_error;
385static void register_date_time_string_decodinws_error(void);
386
387/* Handle string errors expert info */
388static int proto_string_errors;
389static expert_field ei_string_trailing_characters;
390static void register_string_errors(void);
391
392static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393
394/* special-case header field used within proto.c */
395static header_field_info hfi_text_only =
396 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
397int hf_text_only;
398
399/* Structure for information about a protocol */
400struct _protocol {
401 const char *name; /* long description */
402 const char *short_name; /* short description */
403 const char *filter_name; /* name of this protocol in filters */
404 GPtrArray *fields; /* fields for this protocol */
405 int proto_id; /* field ID for this protocol */
406 bool_Bool is_enabled; /* true if protocol is enabled */
407 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
408 bool_Bool can_toggle; /* true if is_enabled can be changed */
409 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
410 For dissectors that need a protocol name so they
411 can be added to a dissector table, but use the
412 parent_proto_id for things like enable/disable */
413 GList *heur_list; /* Heuristic dissectors associated with this protocol */
414};
415
416/* List of all protocols */
417static GList *protocols;
418
419/* Structure stored for deregistered g_slice */
420struct g_slice_data {
421 size_t block_size;
422 void *mem_block;
423};
424
425/* Deregistered fields */
426static GPtrArray *deregistered_fields;
427static GPtrArray *deregistered_data;
428static GPtrArray *deregistered_slice;
429
430/* indexed by prefix, contains initializers */
431static GHashTable* prefixes;
432
433/* Contains information about a field when a dissector calls
434 * proto_tree_add_item. */
435#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
436#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
437
438/* Contains the space for proto_nodes. */
439#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
440 node->first_child = NULL((void*)0); \
441 node->last_child = NULL((void*)0); \
442 node->next = NULL((void*)0);
443
444#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
445 wmem_free(pool, node)
446
447/* String space for protocol and field items for the GUI */
448#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
449 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
450 il->value_pos = 0; \
451 il->value_len = 0;
452#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
453 wmem_free(pool, il);
454
455#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 455, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
456 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 457
, __func__, "Unregistered hf! index=%d", hfindex)
; \
458 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 458, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
459 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
460 hfinfo = gpa_hfinfo.hfi[hfindex];
461
462#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
463
464/* List which stores protocols and fields that have been registered */
465typedef struct _gpa_hfinfo_t {
466 uint32_t len;
467 uint32_t allocated_len;
468 header_field_info **hfi;
469} gpa_hfinfo_t;
470
471static gpa_hfinfo_t gpa_hfinfo;
472
473/* Hash table of abbreviations and IDs */
474static wmem_map_t *gpa_name_map;
475static header_field_info *same_name_hfinfo;
476
477/* Hash table protocol aliases. const char * -> const char * */
478static GHashTable *gpa_protocol_aliases;
479
480/*
481 * We're called repeatedly with the same field name when sorting a column.
482 * Cache our last gpa_name_map hit for faster lookups.
483 */
484static char *last_field_name;
485static header_field_info *last_hfinfo;
486
487/* Points to the first element of an array of bits, indexed by
488 a subtree item type; that array element is true if subtrees of
489 an item of that type are to be expanded. */
490static uint32_t *tree_is_expanded;
491
492/* Number of elements in that array. The entry with index 0 is not used. */
493int num_tree_types = 1;
494
495/* Name hashtables for fast detection of duplicate names */
496static GHashTable* proto_names;
497static GHashTable* proto_short_names;
498static GHashTable* proto_filter_names;
499
500static const char * const reserved_filter_names[] = {
501 /* Display filter keywords. */
502 "eq",
503 "ne",
504 "all_eq",
505 "any_eq",
506 "all_ne",
507 "any_ne",
508 "gt",
509 "ge",
510 "lt",
511 "le",
512 "bitand",
513 "bitwise_and",
514 "contains",
515 "matches",
516 "not",
517 "and",
518 "or",
519 "xor",
520 "in",
521 "any",
522 "all",
523 "true",
524 "false",
525 "nan",
526 "inf",
527 "infinity",
528 NULL((void*)0)
529};
530
531static GHashTable *proto_reserved_filter_names;
532static GQueue* saved_dir_queue;
533
534static int
535proto_compare_name(const void *p1_arg, const void *p2_arg)
536{
537 const protocol_t *p1 = (const protocol_t *)p1_arg;
538 const protocol_t *p2 = (const protocol_t *)p2_arg;
539
540 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541}
542
543static GSList *dissector_plugins;
544
545#ifdef HAVE_PLUGINS1
546void
547proto_register_plugin(const proto_plugin *plug)
548{
549 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550}
551#else /* HAVE_PLUGINS */
552void
553proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
554{
555 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 555, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
556}
557#endif /* HAVE_PLUGINS */
558
559static void
560call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
561{
562 proto_plugin *plug = (proto_plugin *)data;
563
564 if (plug->register_protoinfo) {
565 plug->register_protoinfo();
566 }
567}
568
569static void
570call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
571{
572 proto_plugin *plug = (proto_plugin *)data;
573
574 if (plug->register_handoff) {
575 plug->register_handoff();
576 }
577}
578
579void proto_pre_init(void)
580{
581 saved_dir_queue = g_queue_new();
582
583 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586
587 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 /* GHashTable has no key destructor so the cast is safe. */
590 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591 }
592
593 gpa_hfinfo.len = 0;
594 gpa_hfinfo.allocated_len = 0;
595 gpa_hfinfo.hfi = NULL((void*)0);
596 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
598 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599 deregistered_fields = g_ptr_array_new();
600 deregistered_data = g_ptr_array_new();
601 deregistered_slice = g_ptr_array_new();
602}
603
604/* initialize data structures and register protocols and fields */
605void
606proto_init(GSList *register_all_plugin_protocols_list,
607 GSList *register_all_plugin_handoffs_list,
608 register_entity_func register_func, register_entity_func handoff_func,
609 register_cb cb,
610 void *client_data)
611{
612 /* Initialize the ftype subsystem */
613 ftypes_initialize();
614
615 /* Initialize the address type subsystem */
616 address_types_initialize();
617
618 /* Register one special-case FT_TEXT_ONLY field for use when
619 converting wireshark to new-style proto_tree. These fields
620 are merely strings on the GUI tree; they are not filterable */
621 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622
623 /* Register the pseudo-protocols used for exceptions. */
624 register_show_exception();
625 register_type_length_mismatch();
626 register_byte_array_string_decodinws_error();
627 register_date_time_string_decodinws_error();
628 register_string_errors();
629 ftypes_register_pseudofields();
630 col_register_protocol();
631
632 /* Have each built-in dissector register its protocols, fields,
633 dissector tables, and dissectors to be called through a
634 handle, and do whatever one-time initialization it needs to
635 do. */
636 if (register_func != NULL((void*)0))
637 register_func(cb, client_data);
638
639 /* Now call the registration routines for all epan plugins. */
640 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
641 ((void (*)(register_cb, void *))l->data)(cb, client_data);
642 }
643
644 /* Now call the registration routines for all dissector plugins. */
645 if (cb)
646 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
647 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
648
649 /* Now call the "handoff registration" routines of all built-in
650 dissectors; those routines register the dissector in other
651 dissectors' handoff tables, and fetch any dissector handles
652 they need. */
653 if (handoff_func != NULL((void*)0))
654 handoff_func(cb, client_data);
655
656 /* Now do the same with epan plugins. */
657 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
658 ((void (*)(register_cb, void *))l->data)(cb, client_data);
659 }
660
661 /* Now do the same with dissector plugins. */
662 if (cb)
663 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
664 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
665
666 /* sort the protocols by protocol name */
667 protocols = g_list_sort(protocols, proto_compare_name);
668
669 /* sort the dissector handles in dissector tables (for -G reports
670 * and -d error messages. The GUI sorts the handles itself.) */
671 packet_all_tables_sort_handles();
672
673 /* We've assigned all the subtree type values; allocate the array
674 for them, and zero it out. */
675 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
676}
677
678static void
679proto_cleanup_base(void)
680{
681 protocol_t *protocol;
682 header_field_info *hfinfo;
683
684 /* Free the abbrev/ID hash table */
685 if (gpa_name_map) {
686 // XXX - We don't have a wmem_map_destroy, but
687 // it does get cleaned up when epan scope is
688 // destroyed
689 //g_hash_table_destroy(gpa_name_map);
690 gpa_name_map = NULL((void*)0);
691 }
692 if (gpa_protocol_aliases) {
693 g_hash_table_destroy(gpa_protocol_aliases);
694 gpa_protocol_aliases = NULL((void*)0);
695 }
696 g_free(last_field_name)(__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)
;
697 last_field_name = NULL((void*)0);
698
699 while (protocols) {
700 protocol = (protocol_t *)protocols->data;
701 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 701
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 701, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 701, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
702 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 702, "protocol->proto_id == hfinfo->id"
))))
;
703
704 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
705 if (protocol->parent_proto_id != -1) {
706 // pino protocol
707 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 707, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
708 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 708, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
709 } else {
710 if (protocol->fields) {
711 g_ptr_array_free(protocol->fields, true1);
712 }
713 g_list_free(protocol->heur_list);
714 }
715 protocols = g_list_remove(protocols, protocol);
716 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
717 }
718
719 if (proto_names) {
720 g_hash_table_destroy(proto_names);
721 proto_names = NULL((void*)0);
722 }
723
724 if (proto_short_names) {
725 g_hash_table_destroy(proto_short_names);
726 proto_short_names = NULL((void*)0);
727 }
728
729 if (proto_filter_names) {
730 g_hash_table_destroy(proto_filter_names);
731 proto_filter_names = NULL((void*)0);
732 }
733
734 if (proto_reserved_filter_names) {
735 g_hash_table_destroy(proto_reserved_filter_names);
736 proto_reserved_filter_names = NULL((void*)0);
737 }
738
739 if (gpa_hfinfo.allocated_len) {
740 gpa_hfinfo.len = 0;
741 gpa_hfinfo.allocated_len = 0;
742 g_free(gpa_hfinfo.hfi)(__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)
;
743 gpa_hfinfo.hfi = NULL((void*)0);
744 }
745
746 if (deregistered_fields) {
747 g_ptr_array_free(deregistered_fields, true1);
748 deregistered_fields = NULL((void*)0);
749 }
750
751 if (deregistered_data) {
752 g_ptr_array_free(deregistered_data, true1);
753 deregistered_data = NULL((void*)0);
754 }
755
756 if (deregistered_slice) {
757 g_ptr_array_free(deregistered_slice, true1);
758 deregistered_slice = NULL((void*)0);
759 }
760
761 g_free(tree_is_expanded)(__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)
;
762 tree_is_expanded = NULL((void*)0);
763
764 if (prefixes)
765 g_hash_table_destroy(prefixes);
766
767 if (saved_dir_queue != NULL((void*)0)) {
768 g_queue_clear_full(saved_dir_queue, g_free);
769 g_queue_free(saved_dir_queue);
770 saved_dir_queue = NULL((void*)0);
771 }
772}
773
774void
775proto_cleanup(void)
776{
777 proto_free_deregistered_fields();
778 proto_cleanup_base();
779
780 g_slist_free(dissector_plugins);
781 dissector_plugins = NULL((void*)0);
782}
783
784static bool_Bool
785ws_pushd(const char* dir)
786{
787 //Save the current working directory
788 const char* save_wd = get_current_working_dir();
789 if (save_wd != NULL((void*)0))
790 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
791
792 //Change to the new one
793#ifdef _WIN32
794 SetCurrentDirectory(utf_8to16(dir));
795 return true1;
796#else
797 return (chdir(dir) == 0);
798#endif
799}
800
801static bool_Bool
802ws_popd(void)
803{
804 int ret = 0;
805 char* saved_wd = g_queue_pop_head(saved_dir_queue);
806 if (saved_wd == NULL((void*)0))
807 return false0;
808
809 //Restore the previous one
810#ifdef _WIN32
811 SetCurrentDirectory(utf_8to16(saved_wd));
812#else
813 ret = chdir(saved_wd);
814#endif
815 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
816 return (ret == 0);
817}
818
819void
820proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
821{
822 if (ws_pushd(dir))
823 {
824 func(param);
825 ws_popd();
826 }
827}
828
829static bool_Bool
830// NOLINTNEXTLINE(misc-no-recursion)
831proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
832 void *data)
833{
834 proto_node *pnode = tree;
835 proto_node *child;
836 proto_node *current;
837
838 if (func(pnode, data))
839 return true1;
840
841 child = pnode->first_child;
842 while (child != NULL((void*)0)) {
843 /*
844 * The routine we call might modify the child, e.g. by
845 * freeing it, so we get the child's successor before
846 * calling that routine.
847 */
848 current = child;
849 child = current->next;
850 // We recurse here, but we're limited by prefs.gui_max_tree_depth
851 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
852 return true1;
853 }
854
855 return false0;
856}
857
858void
859proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
860 void *data)
861{
862 proto_node *node = tree;
863 proto_node *current;
864
865 if (!node)
866 return;
867
868 node = node->first_child;
869 while (node != NULL((void*)0)) {
870 current = node;
871 node = current->next;
872 func((proto_tree *)current, data);
873 }
874}
875
876static void
877free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
878{
879 GPtrArray *ptrs = (GPtrArray *)value;
880 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
881 header_field_info *hfinfo;
882
883 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 883, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 883, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 883, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
884 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
885 /* when a field is referenced by a filter this also
886 affects the refcount for the parent protocol so we need
887 to adjust the refcount for the parent as well
888 */
889 if (hfinfo->parent != -1) {
890 header_field_info *parent_hfinfo;
891 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 891
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 891, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 891, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
892 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
893 }
894 hfinfo->ref_type = HF_REF_TYPE_NONE;
895 }
896
897 g_ptr_array_free(ptrs, true1);
898}
899
900static void
901proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
902{
903 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
904
905 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
906
907 if (finfo) {
908 fvalue_free(finfo->value);
909 finfo->value = NULL((void*)0);
910 }
911}
912
913void
914proto_tree_reset(proto_tree *tree)
915{
916 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
917
918 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
919
920 /* free tree data */
921 if (tree_data->interesting_hfids) {
922 /* Free all the GPtrArray's in the interesting_hfids hash. */
923 g_hash_table_foreach(tree_data->interesting_hfids,
924 free_GPtrArray_value, NULL((void*)0));
925
926 /* And then remove all values. */
927 g_hash_table_remove_all(tree_data->interesting_hfids);
928 }
929
930 /* Reset track of the number of children */
931 tree_data->count = 0;
932
933 /* Reset our loop checks */
934 tree_data->idle_count_ds_tvb = NULL((void*)0);
935 tree_data->max_start = 0;
936 tree_data->start_idle_count = 0;
937
938 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
939}
940
941/* frees the resources that the dissection a proto_tree uses */
942void
943proto_tree_free(proto_tree *tree)
944{
945 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
946
947 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
948
949 /* free tree data */
950 if (tree_data->interesting_hfids) {
951 /* Free all the GPtrArray's in the interesting_hfids hash. */
952 g_hash_table_foreach(tree_data->interesting_hfids,
953 free_GPtrArray_value, NULL((void*)0));
954
955 /* And then destroy the hash. */
956 g_hash_table_destroy(tree_data->interesting_hfids);
957 }
958
959 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
960
961 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
962}
963
964/* Is the parsing being done for a visible proto_tree or an invisible one?
965 * By setting this correctly, the proto_tree creation is sped up by not
966 * having to call vsnprintf and copy strings around.
967 */
968bool_Bool
969proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
970{
971 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
972
973 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
974
975 return old_visible;
976}
977
978void
979proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
980{
981 if (tree)
982 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
983}
984
985/* Assume dissector set only its protocol fields.
986 This function is called by dissectors and allows the speeding up of filtering
987 in wireshark; if this function returns false it is safe to reset tree to NULL
988 and thus skip calling most of the expensive proto_tree_add_...()
989 functions.
990 If the tree is visible we implicitly assume the field is referenced.
991*/
992bool_Bool
993proto_field_is_referenced(proto_tree *tree, int proto_id)
994{
995 register header_field_info *hfinfo;
996
997
998 if (!tree)
999 return false0;
1000
1001 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1002 return true1;
1003
1004 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1004, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1004,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1004, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1005 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1006 return true1;
1007
1008 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1009 return true1;
1010
1011 return false0;
1012}
1013
1014
1015/* Finds a record in the hfinfo array by id. */
1016header_field_info *
1017proto_registrar_get_nth(unsigned hfindex)
1018{
1019 register header_field_info *hfinfo;
1020
1021 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1021, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1021,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1021, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1022 return hfinfo;
1023}
1024
1025
1026/* Prefix initialization
1027 * this allows for a dissector to register a display filter name prefix
1028 * so that it can delay the initialization of the hf array as long as
1029 * possible.
1030 */
1031
1032/* compute a hash for the part before the dot of a display filter */
1033static unsigned
1034prefix_hash (const void *key) {
1035 /* end the string at the dot and compute its hash */
1036 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1037 char* c = copy;
1038 unsigned tmp;
1039
1040 for (; *c; c++) {
1041 if (*c == '.') {
1042 *c = 0;
1043 break;
1044 }
1045 }
1046
1047 tmp = wmem_str_hash(copy);
1048 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1049 return tmp;
1050}
1051
1052/* are both strings equal up to the end or the dot? */
1053static gboolean
1054prefix_equal (const void *ap, const void *bp) {
1055 const char* a = (const char *)ap;
1056 const char* b = (const char *)bp;
1057
1058 do {
1059 char ac = *a++;
1060 char bc = *b++;
1061
1062 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1063
1064 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1065 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1066
1067 if (ac != bc) return FALSE(0);
1068 } while (1);
1069
1070 return FALSE(0);
1071}
1072
1073/* Register a new prefix for "delayed" initialization of field arrays */
1074void
1075proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1076 if (! prefixes ) {
1077 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1078 }
1079
1080 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1081}
1082
1083/* helper to call all prefix initializers */
1084static gboolean
1085initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1086 ((prefix_initializer_t)v)((const char *)k);
1087 return TRUE(!(0));
1088}
1089
1090/** Initialize every remaining uninitialized prefix. */
1091void
1092proto_initialize_all_prefixes(void) {
1093 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1094}
1095
1096/* Finds a record in the hfinfo array by name.
1097 * If it fails to find it in the already registered fields,
1098 * it tries to find and call an initializer in the prefixes
1099 * table and if so it looks again.
1100 */
1101
1102header_field_info *
1103proto_registrar_get_byname(const char *field_name)
1104{
1105 header_field_info *hfinfo;
1106 prefix_initializer_t pi;
1107
1108 if (!field_name)
1109 return NULL((void*)0);
1110
1111 if (g_strcmp0(field_name, last_field_name) == 0) {
1112 return last_hfinfo;
1113 }
1114
1115 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1116
1117 if (hfinfo) {
1118 g_free(last_field_name)(__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)
;
1119 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1120 last_hfinfo = hfinfo;
1121 return hfinfo;
1122 }
1123
1124 if (!prefixes)
1125 return NULL((void*)0);
1126
1127 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1128 pi(field_name);
1129 g_hash_table_remove(prefixes, field_name);
1130 } else {
1131 return NULL((void*)0);
1132 }
1133
1134 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1135
1136 if (hfinfo) {
1137 g_free(last_field_name)(__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)
;
1138 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1139 last_hfinfo = hfinfo;
1140 }
1141 return hfinfo;
1142}
1143
1144header_field_info*
1145proto_registrar_get_byalias(const char *alias_name)
1146{
1147 if (!alias_name) {
1148 return NULL((void*)0);
1149 }
1150
1151 /* Find our aliased protocol. */
1152 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1153 char *dot = strchr(an_copy, '.');
1154 if (dot) {
1155 *dot = '\0';
1156 }
1157 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1158 if (!proto_pfx) {
1159 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1160 return NULL((void*)0);
1161 }
1162
1163 /* Construct our aliased field and look it up. */
1164 GString *filter_name = g_string_new(proto_pfx);
1165 if (dot) {
1166 g_string_append_printf(filter_name, ".%s", dot+1);
1167 }
1168 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1169 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1170 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1171
1172 return hfinfo;
1173}
1174
1175int
1176proto_registrar_get_id_byname(const char *field_name)
1177{
1178 header_field_info *hfinfo;
1179
1180 hfinfo = proto_registrar_get_byname(field_name);
1181
1182 if (!hfinfo)
1183 return -1;
1184
1185 return hfinfo->id;
1186}
1187
1188static int
1189label_strcat_flags(const header_field_info *hfinfo)
1190{
1191 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1192 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1193
1194 return 0;
1195}
1196
1197static char *
1198format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1199 const uint8_t *bytes, unsigned length, size_t max_str_len)
1200{
1201 char *str = NULL((void*)0);
1202 const uint8_t *p;
1203 bool_Bool is_printable;
1204
1205 if (bytes) {
1206 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1207 /*
1208 * If all bytes are valid and printable UTF-8, show the
1209 * bytes as a string - in quotes to indicate that it's
1210 * a string.
1211 */
1212 if (isprint_utf8_string((const char*)bytes, length)) {
1213 str = wmem_strdup_printf(scope, "\"%.*s\"",
1214 (int)length, bytes);
1215 return str;
1216 }
1217 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1218 /*
1219 * Check whether all bytes are printable.
1220 */
1221 is_printable = true1;
1222 for (p = bytes; p < bytes+length; p++) {
1223 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1224 /* Not printable. */
1225 is_printable = false0;
1226 break;
1227 }
1228 }
1229
1230 /*
1231 * If all bytes are printable ASCII, show the bytes
1232 * as a string - in quotes to indicate that it's
1233 * a string.
1234 */
1235 if (is_printable) {
1236 str = wmem_strdup_printf(scope, "\"%.*s\"",
1237 (int)length, bytes);
1238 return str;
1239 }
1240 }
1241
1242 /*
1243 * Either it's not printable ASCII, or we don't care whether
1244 * it's printable ASCII; show it as hex bytes.
1245 */
1246 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1247 case SEP_DOT:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1249 break;
1250 case SEP_DASH:
1251 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1252 break;
1253 case SEP_COLON:
1254 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1255 break;
1256 case SEP_SPACE:
1257 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1258 break;
1259 case BASE_NONE:
1260 default:
1261 if (prefs.display_byte_fields_with_spaces) {
1262 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1263 } else {
1264 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1265 }
1266 break;
1267 }
1268 }
1269 else {
1270 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1271 str = wmem_strdup(scope, "<none>");
1272 } else {
1273 str = wmem_strdup(scope, "<MISSING>");
1274 }
1275 }
1276 return str;
1277}
1278
1279static char *
1280format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1281 const uint8_t *bytes, unsigned length)
1282{
1283 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1284}
1285
1286static void
1287ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1288{
1289 subtree_lvl *pushed_tree;
1290
1291 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1291, "ptvc->pushed_tree_max <= 256-8"))))
;
1292 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1293
1294 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1295 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1295, "pushed_tree != ((void*)0)"
))))
;
1296 ptvc->pushed_tree = pushed_tree;
1297}
1298
1299static void
1300ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1301{
1302 ptvc->pushed_tree = NULL((void*)0);
1303 ptvc->pushed_tree_max = 0;
1304 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1304, "ptvc->pushed_tree_index == 0"
))))
;
1305 ptvc->pushed_tree_index = 0;
1306}
1307
1308/* Allocates an initializes a ptvcursor_t with 3 variables:
1309 * proto_tree, tvbuff, and offset. */
1310ptvcursor_t *
1311ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1312{
1313 ptvcursor_t *ptvc;
1314
1315 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1316 ptvc->scope = scope;
1317 ptvc->tree = tree;
1318 ptvc->tvb = tvb;
1319 ptvc->offset = offset;
1320 ptvc->pushed_tree = NULL((void*)0);
1321 ptvc->pushed_tree_max = 0;
1322 ptvc->pushed_tree_index = 0;
1323 return ptvc;
1324}
1325
1326
1327/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1328void
1329ptvcursor_free(ptvcursor_t *ptvc)
1330{
1331 ptvcursor_free_subtree_levels(ptvc);
1332 wmem_free(ptvc->scope, ptvc);
1333}
1334
1335/* Returns tvbuff. */
1336tvbuff_t *
1337ptvcursor_tvbuff(ptvcursor_t *ptvc)
1338{
1339 return ptvc->tvb;
1340}
1341
1342/* Returns current offset. */
1343unsigned
1344ptvcursor_current_offset(ptvcursor_t *ptvc)
1345{
1346 return ptvc->offset;
1347}
1348
1349proto_tree *
1350ptvcursor_tree(ptvcursor_t *ptvc)
1351{
1352 if (!ptvc)
1353 return NULL((void*)0);
1354
1355 return ptvc->tree;
1356}
1357
1358void
1359ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1360{
1361 ptvc->tree = tree;
1362}
1363
1364/* creates a subtree, sets it as the working tree and pushes the old working tree */
1365proto_tree *
1366ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1367{
1368 subtree_lvl *subtree;
1369 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1370 ptvcursor_new_subtree_levels(ptvc);
1371
1372 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1373 subtree->tree = ptvc->tree;
1374 subtree->it= NULL((void*)0);
1375 ptvc->pushed_tree_index++;
1376 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1377}
1378
1379/* pops a subtree */
1380void
1381ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1382{
1383 subtree_lvl *subtree;
1384
1385 if (ptvc->pushed_tree_index <= 0)
1386 return;
1387
1388 ptvc->pushed_tree_index--;
1389 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1390 if (subtree->it != NULL((void*)0))
1391 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1392
1393 ptvc->tree = subtree->tree;
1394}
1395
1396/* saves the current tvb offset and the item in the current subtree level */
1397static void
1398ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1399{
1400 subtree_lvl *subtree;
1401
1402 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1402, "ptvc->pushed_tree_index > 0"
))))
;
1403
1404 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1405 subtree->it = it;
1406 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1407}
1408
1409/* Creates a subtree and adds it to the cursor as the working tree but does not
1410 * save the old working tree */
1411proto_tree *
1412ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1413{
1414 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1415 return ptvc->tree;
1416}
1417
1418static proto_tree *
1419ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1420{
1421 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1422 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1423 ptvcursor_subtree_set_item(ptvc, it);
1424 return ptvcursor_tree(ptvc);
1425}
1426
1427/* Add an item to the tree and create a subtree
1428 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1429 * In this case, when the subtree will be closed, the parent item length will
1430 * be equal to the advancement of the cursor since the creation of the subtree.
1431 */
1432proto_tree *
1433ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1434 const unsigned encoding, int ett_subtree)
1435{
1436 proto_item *it;
1437
1438 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1439 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1440}
1441
1442static proto_item *
1443proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1444
1445/* Add a text node to the tree and create a subtree
1446 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447 * In this case, when the subtree will be closed, the item length will be equal
1448 * to the advancement of the cursor since the creation of the subtree.
1449 */
1450proto_tree *
1451ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452 int ett_subtree, const char *format, ...)
1453{
1454 proto_item *pi;
1455 va_list ap;
1456 header_field_info *hfinfo;
1457 proto_tree *tree;
1458
1459 tree = ptvcursor_tree(ptvc);
1460
1461 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1462
1463 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1464
1465 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466 ptvcursor_current_offset(ptvc), length);
1467
1468 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1469
1470 va_start(ap, format)__builtin_va_start(ap, format);
1471 proto_tree_set_representation(pi, format, ap);
1472 va_end(ap)__builtin_va_end(ap);
1473
1474 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475}
1476
1477/* Add a text-only node, leaving it to our caller to fill the text in */
1478static proto_item *
1479proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1480{
1481 proto_item *pi;
1482
1483 if (tree == NULL((void*)0))
1484 return NULL((void*)0);
1485
1486 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487
1488 return pi;
1489}
1490
1491/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492proto_item *
1493proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1494 const char *format, ...)
1495{
1496 proto_item *pi;
1497 va_list ap;
1498 header_field_info *hfinfo;
1499
1500 if (length == -1) {
1501 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502 } else {
1503 tvb_ensure_bytes_exist(tvb, start, length);
1504 }
1505
1506 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507
1508 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1509
1510 pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1513
1514 va_start(ap, format)__builtin_va_start(ap, format);
1515 proto_tree_set_representation(pi, format, ap);
1516 va_end(ap)__builtin_va_end(ap);
1517
1518 return pi;
1519}
1520
1521/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522proto_item *
1523proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1524 int length, const char *format, va_list ap)
1525{
1526 proto_item *pi;
1527 header_field_info *hfinfo;
1528
1529 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 * the length to be what's in the tvbuff if length is -1, and the
1532 * minimum of length and what's in the tvbuff if not.
1533 */
1534
1535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536
1537 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1538
1539 pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1542
1543 proto_tree_set_representation(pi, format, ap);
1544
1545 return pi;
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1552{
1553 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554}
1555
1556/* Add a text-only node that creates a subtree underneath.
1557 */
1558proto_tree *
1559proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560{
1561 proto_tree *pt;
1562 proto_item *pi;
1563 va_list ap;
1564
1565 va_start(ap, format)__builtin_va_start(ap, format);
1566 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567 va_end(ap)__builtin_va_end(ap);
1568
1569 if (tree_item != NULL((void*)0))
1570 *tree_item = pi;
1571
1572 pt = proto_item_add_subtree(pi, idx);
1573
1574 return pt;
1575}
1576
1577/* Add a text-only node for debugging purposes. The caller doesn't need
1578 * to worry about tvbuff, start, or length. Debug message gets sent to
1579 * STDOUT, too */
1580proto_item *
1581proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582{
1583 proto_item *pi;
1584 va_list ap;
1585
1586 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1587
1588 if (pi) {
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 proto_tree_set_representation(pi, format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 }
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 vprintf(format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 printf("\n");
1597
1598 return pi;
1599}
1600
1601proto_item *
1602proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1603{
1604 proto_item *pi;
1605 header_field_info *hfinfo;
1606
1607 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1608
1609 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1610
1611 pi = proto_tree_add_text_node(tree, tvb, start, length);
1612
1613 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1613, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1614
1615 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616
1617 return pi;
1618}
1619
1620proto_item *
1621proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1622{
1623 proto_item *pi;
1624 header_field_info *hfinfo;
1625 char *str;
1626
1627 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1628
1629 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1630
1631 pi = proto_tree_add_text_node(tree, tvb, start, length);
1632
1633 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1633, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1634
1635 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1636 proto_item_set_text(pi, "%s", str);
1637 wmem_free(NULL((void*)0), str);
1638
1639 return pi;
1640}
1641
1642void proto_report_dissector_bug(const char *format, ...)
1643{
1644 va_list args;
1645
1646 if (wireshark_abort_on_dissector_bug) {
1647 /*
1648 * Try to have the error message show up in the crash
1649 * information.
1650 */
1651 va_start(args, format)__builtin_va_start(args, format);
1652 ws_vadd_crash_info(format, args);
1653 va_end(args)__builtin_va_end(args);
1654
1655 /*
1656 * Print the error message.
1657 */
1658 va_start(args, format)__builtin_va_start(args, format);
1659 vfprintf(stderrstderr, format, args);
1660 va_end(args)__builtin_va_end(args);
1661 putc('\n', stderrstderr);
1662
1663 /*
1664 * And crash.
1665 */
1666 abort();
1667 } else {
1668 va_start(args, format)__builtin_va_start(args, format);
1669 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1670 va_end(args)__builtin_va_end(args);
1671 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1671
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1672 }
1673}
1674
1675/* We could probably get away with changing is_error to a minimum length value. */
1676static void
1677report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1678{
1679 if (is_error) {
1680 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681 } else {
1682 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683 }
1684
1685 if (is_error) {
1686 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1687 }
1688}
1689
1690static uint32_t
1691get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692{
1693 uint32_t value;
1694 bool_Bool length_error;
1695
1696 switch (length) {
1697
1698 case 1:
1699 value = tvb_get_uint8(tvb, offset);
1700 if (encoding & ENC_ZIGBEE0x40000000) {
1701 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702 value = 0;
1703 }
1704 }
1705 break;
1706
1707 case 2:
1708 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1709 : tvb_get_ntohs(tvb, offset);
1710 if (encoding & ENC_ZIGBEE0x40000000) {
1711 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712 value = 0;
1713 }
1714 }
1715 break;
1716
1717 case 3:
1718 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1719 : tvb_get_ntoh24(tvb, offset);
1720 break;
1721
1722 case 4:
1723 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 : tvb_get_ntohl(tvb, offset);
1725 break;
1726
1727 default:
1728 if (length < 1) {
1729 length_error = true1;
1730 value = 0;
1731 } else {
1732 length_error = false0;
1733 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1734 : tvb_get_ntohl(tvb, offset);
1735 }
1736 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737 break;
1738 }
1739 return value;
1740}
1741
1742static inline uint64_t
1743get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1744{
1745 uint64_t value;
1746
1747 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748
1749 if (length < 1 || length > 8) {
1750 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751 }
1752
1753 return value;
1754}
1755
1756static int32_t
1757get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1758{
1759 int32_t value;
1760 bool_Bool length_error;
1761
1762 switch (length) {
1763
1764 case 1:
1765 value = tvb_get_int8(tvb, offset);
1766 break;
1767
1768 case 2:
1769 value = encoding ? tvb_get_letohis(tvb, offset)
1770 : tvb_get_ntohis(tvb, offset);
1771 break;
1772
1773 case 3:
1774 value = encoding ? tvb_get_letohi24(tvb, offset)
1775 : tvb_get_ntohi24(tvb, offset);
1776 break;
1777
1778 case 4:
1779 value = encoding ? tvb_get_letohil(tvb, offset)
1780 : tvb_get_ntohil(tvb, offset);
1781 break;
1782
1783 default:
1784 if (length < 1) {
1785 length_error = true1;
1786 value = 0;
1787 } else {
1788 length_error = false0;
1789 value = encoding ? tvb_get_letohil(tvb, offset)
1790 : tvb_get_ntohil(tvb, offset);
1791 }
1792 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793 break;
1794 }
1795 return value;
1796}
1797
1798/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799 * be cast-able as a int64_t. This is weird, but what the code has always done.
1800 */
1801static inline uint64_t
1802get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1803{
1804 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805
1806 switch (length) {
1807 case 7:
1808 value = ws_sign_ext64(value, 56);
1809 break;
1810 case 6:
1811 value = ws_sign_ext64(value, 48);
1812 break;
1813 case 5:
1814 value = ws_sign_ext64(value, 40);
1815 break;
1816 case 4:
1817 value = ws_sign_ext64(value, 32);
1818 break;
1819 case 3:
1820 value = ws_sign_ext64(value, 24);
1821 break;
1822 case 2:
1823 value = ws_sign_ext64(value, 16);
1824 break;
1825 case 1:
1826 value = ws_sign_ext64(value, 8);
1827 break;
1828 }
1829
1830 return value;
1831}
1832
1833/* For FT_STRING */
1834static inline const uint8_t *
1835get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1836 int length, int *ret_length, const unsigned encoding)
1837{
1838 if (length == -1) {
1839 length = tvb_ensure_captured_length_remaining(tvb, start);
1840 }
1841 *ret_length = length;
1842 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843}
1844
1845/* For FT_STRINGZ */
1846static inline const uint8_t *
1847get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848 int start, int length, int *ret_length, const unsigned encoding)
1849{
1850 const uint8_t *value;
1851
1852 if (length < -1) {
1853 report_type_length_mismatch(tree, "a string", length, true1);
1854 }
1855
1856 /* XXX - Ideally, every "null-terminated string which fits into a
1857 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860 * as unknown length as well (since there is a trailing '\0', the real
1861 * length is never zero), allowing switching to unsigned lengths.
1862 */
1863 if (length == -1) {
1864 /* This can throw an exception */
1865 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866 } else {
1867 /* In this case, length signifies the length of the string.
1868 *
1869 * This could either be a null-padded string, which doesn't
1870 * necessarily have a '\0' at the end, or a null-terminated
1871 * string, with a trailing '\0'. (Yes, there are cases
1872 * where you have a string that's both counted and null-
1873 * terminated.)
1874 *
1875 * In the first case, we must allocate a buffer of length
1876 * "length+1", to make room for a trailing '\0'.
1877 *
1878 * In the second case, we don't assume that there is a
1879 * trailing '\0' there, as the packet might be malformed.
1880 * (XXX - should we throw an exception if there's no
1881 * trailing '\0'?) Therefore, we allocate a buffer of
1882 * length "length+1", and put in a trailing '\0', just to
1883 * be safe.
1884 *
1885 * (XXX - this would change if we made string values counted
1886 * rather than null-terminated.)
1887 */
1888 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889 }
1890 *ret_length = length;
1891 return value;
1892}
1893
1894/* For FT_UINT_STRING */
1895static inline const uint8_t *
1896get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897 tvbuff_t *tvb, int start, int length, int *ret_length,
1898 const unsigned encoding)
1899{
1900 uint32_t n;
1901 const uint8_t *value;
1902
1903 /* I believe it's ok if this is called with a NULL tree */
1904 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1905 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906 length += n;
1907 *ret_length = length;
1908 return value;
1909}
1910
1911/* For FT_STRINGZPAD */
1912static inline const uint8_t *
1913get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1914 int length, int *ret_length, const unsigned encoding)
1915{
1916 /*
1917 * XXX - currently, string values are null-
1918 * terminated, so a "zero-padded" string
1919 * isn't special. If we represent string
1920 * values as something that includes a counted
1921 * array of bytes, we'll need to strip the
1922 * trailing NULs.
1923 */
1924 if (length == -1) {
1925 length = tvb_ensure_captured_length_remaining(tvb, start);
1926 }
1927 *ret_length = length;
1928 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929}
1930
1931/* For FT_STRINGZTRUNC */
1932static inline const uint8_t *
1933get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1934 int length, int *ret_length, const unsigned encoding)
1935{
1936 /*
1937 * XXX - currently, string values are null-
1938 * terminated, so a "zero-truncated" string
1939 * isn't special. If we represent string
1940 * values as something that includes a counted
1941 * array of bytes, we'll need to strip everything
1942 * starting with the terminating NUL.
1943 */
1944 if (length == -1) {
1945 length = tvb_ensure_captured_length_remaining(tvb, start);
1946 }
1947 *ret_length = length;
1948 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949}
1950
1951/*
1952 * Deltas between the epochs for various non-UN*X time stamp formats and
1953 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954 * stamp format.
1955 */
1956
1957/*
1958 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959 * XXX - if it's OK if this is unsigned, can we just use
1960 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961 */
1962#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1963
1964/*
1965 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966 */
1967#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1968
1969/* this can be called when there is no tree, so tree may be null */
1970static void
1971get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1972 const int length, const unsigned encoding, nstime_t *time_stamp,
1973 const bool_Bool is_relative)
1974{
1975 uint32_t tmpsecs;
1976 uint64_t tmp64secs;
1977 uint64_t todusecs;
1978
1979 switch (encoding) {
1980
1981 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1982 /*
1983 * If the length is 16, 8-byte seconds, followed
1984 * by 8-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 12, 8-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 8, 4-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * For absolute times, the seconds are seconds
1996 * since the UN*X epoch.
1997 */
1998 if (length == 16) {
1999 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2000 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001 } else if (length == 12) {
2002 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2003 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004 } else if (length == 8) {
2005 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2006 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007 } else if (length == 4) {
2008 /*
2009 * Backwards compatibility.
2010 * ENC_TIME_SECS_NSECS is 0; using
2011 * ENC_BIG_ENDIAN by itself with a 4-byte
2012 * time-in-seconds value was done in the
2013 * past.
2014 */
2015 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2016 time_stamp->nsecs = 0;
2017 } else {
2018 time_stamp->secs = 0;
2019 time_stamp->nsecs = 0;
2020 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021 }
2022 break;
2023
2024 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2025 /*
2026 * If the length is 16, 8-byte seconds, followed
2027 * by 8-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 12, 8-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 8, 4-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * For absolute times, the seconds are seconds
2039 * since the UN*X epoch.
2040 */
2041 if (length == 16) {
2042 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2043 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044 } else if (length == 12) {
2045 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2046 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047 } else if (length == 8) {
2048 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2049 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050 } else if (length == 4) {
2051 /*
2052 * Backwards compatibility.
2053 * ENC_TIME_SECS_NSECS is 0; using
2054 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055 * time-in-seconds value was done in the
2056 * past.
2057 */
2058 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2059 time_stamp->nsecs = 0;
2060 } else {
2061 time_stamp->secs = 0;
2062 time_stamp->nsecs = 0;
2063 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064 }
2065 break;
2066
2067 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2068 /*
2069 * NTP time stamp, big-endian.
2070 * Only supported for absolute times.
2071 */
2072 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2072, "!is_relative"
))))
;
2073
2074 /* We need a temporary variable here so the unsigned math
2075 * works correctly (for years > 2036 according to RFC 2030
2076 * chapter 3).
2077 *
2078 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080 * If bit 0 is not set, the time is in the range 2036-2104 and
2081 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082 */
2083 tmpsecs = tvb_get_ntohl(tvb, start);
2084 if ((tmpsecs & 0x80000000) != 0)
2085 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2086 else
2087 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2088
2089 if (length == 8) {
2090 tmp64secs = tvb_get_ntoh64(tvb, start);
2091 if (tmp64secs == 0) {
2092 //This is "NULL" time
2093 time_stamp->secs = 0;
2094 time_stamp->nsecs = 0;
2095 } else {
2096 /*
2097 * Convert 1/2^32s of a second to
2098 * nanoseconds.
2099 */
2100 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 }
2102 } else if (length == 4) {
2103 /*
2104 * Backwards compatibility.
2105 */
2106 if (tmpsecs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 }
2110 time_stamp->nsecs = 0;
2111 } else {
2112 time_stamp->secs = 0;
2113 time_stamp->nsecs = 0;
2114 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115 }
2116 break;
2117
2118 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2119 /*
2120 * NTP time stamp, little-endian.
2121 * Only supported for absolute times.
2122 *
2123 * NTP doesn't use this, because it's an Internet format
2124 * and hence big-endian. Any implementation must decide
2125 * whether the NTP timestamp is a 64-bit unsigned fixed
2126 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127 * with a 32-bit unsigned seconds field followed by a
2128 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129 * the previous two).
2130 *
2131 * XXX: We do the latter, but no dissector uses this format.
2132 * OTOH, ERF timestamps do the former, so perhaps we
2133 * should switch the interpretation so that packet-erf.c
2134 * could use this directly?
2135 */
2136 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative"
))))
;
2137
2138 /* We need a temporary variable here so the unsigned math
2139 * works correctly (for years > 2036 according to RFC 2030
2140 * chapter 3).
2141 *
2142 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144 * If bit 0 is not set, the time is in the range 2036-2104 and
2145 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146 */
2147 tmpsecs = tvb_get_letohl(tvb, start);
2148 if ((tmpsecs & 0x80000000) != 0)
2149 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2150 else
2151 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2152
2153 if (length == 8) {
2154 tmp64secs = tvb_get_letoh64(tvb, start);
2155 if (tmp64secs == 0) {
2156 //This is "NULL" time
2157 time_stamp->secs = 0;
2158 time_stamp->nsecs = 0;
2159 } else {
2160 /*
2161 * Convert 1/2^32s of a second to
2162 * nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165 }
2166 } else if (length == 4) {
2167 /*
2168 * Backwards compatibility.
2169 */
2170 if (tmpsecs == 0) {
2171 //This is "NULL" time
2172 time_stamp->secs = 0;
2173 }
2174 time_stamp->nsecs = 0;
2175 } else {
2176 time_stamp->secs = 0;
2177 time_stamp->nsecs = 0;
2178 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179 }
2180 break;
2181
2182 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2183 /*
2184 * S/3x0 and z/Architecture TOD clock time stamp,
2185 * big-endian. The epoch is January 1, 1900,
2186 * 00:00:00 (proleptic?) UTC.
2187 *
2188 * Only supported for absolute times.
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "length == 8"
))))
;
2192
2193 if (length == 8) {
2194 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2195 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2196 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2197 } else {
2198 time_stamp->secs = 0;
2199 time_stamp->nsecs = 0;
2200 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201 }
2202 break;
2203
2204 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2205 /*
2206 * S/3x0 and z/Architecture TOD clock time stamp,
2207 * little-endian. The epoch is January 1, 1900,
2208 * 00:00:00 (proleptic?) UTC.
2209 *
2210 * Only supported for absolute times.
2211 */
2212 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2212, "!is_relative"
))))
;
2213
2214 if (length == 8) {
2215 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2216 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2217 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2218 } else {
2219 time_stamp->secs = 0;
2220 time_stamp->nsecs = 0;
2221 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222 }
2223 break;
2224
2225 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2226 /*
2227 * Time stamp using the same seconds/fraction format
2228 * as NTP, but with the origin of the time stamp being
2229 * the UNIX epoch rather than the NTP epoch; big-
2230 * endian.
2231 *
2232 * Only supported for absolute times.
2233 */
2234 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2234, "!is_relative"
))))
;
2235
2236 if (length == 8) {
2237 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238 /*
2239 * Convert 1/2^32s of a second to nanoseconds.
2240 */
2241 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242 } else {
2243 time_stamp->secs = 0;
2244 time_stamp->nsecs = 0;
2245 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246 }
2247 break;
2248
2249 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2250 /*
2251 * Time stamp using the same seconds/fraction format
2252 * as NTP, but with the origin of the time stamp being
2253 * the UNIX epoch rather than the NTP epoch; little-
2254 * endian.
2255 *
2256 * Only supported for absolute times.
2257 *
2258 * The RTPS specification explicitly supports Little
2259 * Endian encoding. In one place, it states that its
2260 * Time_t representation "is the one defined by ...
2261 * RFC 1305", but in another explicitly defines it as
2262 * a struct consisting of an 32 bit unsigned seconds
2263 * field and a 32 bit unsigned fraction field, not a 64
2264 * bit fixed point, so we do that here.
2265 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266 */
2267 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2267, "!is_relative"
))))
;
2268
2269 if (length == 8) {
2270 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271 /*
2272 * Convert 1/2^32s of a second to nanoseconds.
2273 */
2274 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275 } else {
2276 time_stamp->secs = 0;
2277 time_stamp->nsecs = 0;
2278 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279 }
2280 break;
2281
2282 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2283 /*
2284 * MIP6 time stamp, big-endian.
2285 * A 64-bit unsigned integer field containing a timestamp. The
2286 * value indicates the number of seconds since January 1, 1970,
2287 * 00:00 UTC, by using a fixed point format. In this format, the
2288 * integer number of seconds is contained in the first 48 bits of
2289 * the field, and the remaining 16 bits indicate the number of
2290 * 1/65536 fractions of a second.
2291
2292 * Only supported for absolute times.
2293 */
2294 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2294, "!is_relative"
))))
;
2295
2296 if (length == 8) {
2297 /* We need a temporary variable here so the casting and fractions
2298 * of a second work correctly.
2299 */
2300 tmp64secs = tvb_get_ntoh48(tvb, start);
2301 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302 tmpsecs <<= 16;
2303
2304 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305 //This is "NULL" time
2306 time_stamp->secs = 0;
2307 time_stamp->nsecs = 0;
2308 } else {
2309 time_stamp->secs = (time_t)tmp64secs;
2310 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311 }
2312 } else {
2313 time_stamp->secs = 0;
2314 time_stamp->nsecs = 0;
2315 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316 }
2317 break;
2318
2319 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2320 /*
2321 * If the length is 16, 8-byte seconds, followed
2322 * by 8-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 12, 8-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 8, 4-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * For absolute times, the seconds are seconds
2334 * since the UN*X epoch.
2335 */
2336 if (length == 16) {
2337 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2338 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339 } else if (length == 12) {
2340 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2341 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342 } else if (length == 8) {
2343 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2344 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345 } else {
2346 time_stamp->secs = 0;
2347 time_stamp->nsecs = 0;
2348 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349 }
2350 break;
2351
2352 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2353 /*
2354 * If the length is 16, 8-byte seconds, followed
2355 * by 8-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 12, 8-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 8, 4-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * For absolute times, the seconds are seconds
2367 * since the UN*X epoch.
2368 */
2369 if (length == 16) {
2370 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2371 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372 } else if (length == 12) {
2373 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2374 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375 } else if (length == 8) {
2376 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2377 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378 } else {
2379 time_stamp->secs = 0;
2380 time_stamp->nsecs = 0;
2381 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382 }
2383 break;
2384
2385 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2386 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2387 /*
2388 * Seconds, 1 to 8 bytes.
2389 * For absolute times, it's seconds since the
2390 * UN*X epoch.
2391 */
2392 if (length >= 1 && length <= 8) {
2393 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394 time_stamp->nsecs = 0;
2395 } else {
2396 time_stamp->secs = 0;
2397 time_stamp->nsecs = 0;
2398 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399 }
2400 break;
2401
2402 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2403 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2404 /*
2405 * Milliseconds, 1 to 8 bytes.
2406 * For absolute times, it's milliseconds since the
2407 * UN*X epoch.
2408 */
2409 if (length >= 1 && length <= 8) {
2410 uint64_t msecs;
2411
2412 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413 time_stamp->secs = (time_t)(msecs / 1000);
2414 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415 } else {
2416 time_stamp->secs = 0;
2417 time_stamp->nsecs = 0;
2418 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419 }
2420 break;
2421
2422 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2423 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2424 /*
2425 * Microseconds, 1 to 8 bytes.
2426 * For absolute times, it's microseconds since the
2427 * UN*X epoch.
2428 */
2429 if (length >= 1 && length <= 8) {
2430 uint64_t usecs;
2431
2432 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433 time_stamp->secs = (time_t)(usecs / 1000000);
2434 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435 } else {
2436 time_stamp->secs = 0;
2437 time_stamp->nsecs = 0;
2438 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439 }
2440 break;
2441
2442 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2443 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2444 /*
2445 * nanoseconds, 1 to 8 bytes.
2446 * For absolute times, it's nanoseconds since the
2447 * UN*X epoch.
2448 */
2449
2450 if (length >= 1 && length <= 8) {
2451 uint64_t nsecs;
2452
2453 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454 time_stamp->secs = (time_t)(nsecs / 1000000000);
2455 time_stamp->nsecs = (int)(nsecs % 1000000000);
2456 } else {
2457 time_stamp->secs = 0;
2458 time_stamp->nsecs = 0;
2459 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460 }
2461 break;
2462
2463 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2464 /*
2465 * 1/64ths of a second since the UN*X epoch,
2466 * big-endian.
2467 *
2468 * Only supported for absolute times.
2469 */
2470 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2470, "!is_relative"
))))
;
2471
2472 if (length == 8) {
2473 /*
2474 * The upper 48 bits are seconds since the
2475 * UN*X epoch.
2476 */
2477 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2478 /*
2479 * The lower 16 bits are 1/2^16s of a second;
2480 * convert them to nanoseconds.
2481 *
2482 * XXX - this may give the impression of higher
2483 * precision than you actually get.
2484 */
2485 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486 } else {
2487 time_stamp->secs = 0;
2488 time_stamp->nsecs = 0;
2489 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490 }
2491 break;
2492
2493 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2494 /*
2495 * 1/64ths of a second since the UN*X epoch,
2496 * little-endian.
2497 *
2498 * Only supported for absolute times.
2499 */
2500 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2500, "!is_relative"
))))
;
2501
2502 if (length == 8) {
2503 /*
2504 * XXX - this is assuming that, if anybody
2505 * were ever to use this format - RFC 3971
2506 * doesn't, because that's an Internet
2507 * protocol, and those use network byte
2508 * order, i.e. big-endian - they'd treat it
2509 * as a 64-bit count of 1/2^16s of a second,
2510 * putting the upper 48 bits at the end.
2511 *
2512 * The lower 48 bits are seconds since the
2513 * UN*X epoch.
2514 */
2515 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2516 /*
2517 * The upper 16 bits are 1/2^16s of a second;
2518 * convert them to nanoseconds.
2519 *
2520 * XXX - this may give the impression of higher
2521 * precision than you actually get.
2522 */
2523 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524 } else {
2525 time_stamp->secs = 0;
2526 time_stamp->nsecs = 0;
2527 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528 }
2529 break;
2530
2531 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2532 /*
2533 * NTP time stamp, with 1-second resolution (i.e.,
2534 * seconds since the NTP epoch), big-endian.
2535 * Only supported for absolute times.
2536 */
2537 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2537, "!is_relative"
))))
;
2538
2539 if (length == 4) {
2540 /*
2541 * We need a temporary variable here so the unsigned math
2542 * works correctly (for years > 2036 according to RFC 2030
2543 * chapter 3).
2544 *
2545 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547 * If bit 0 is not set, the time is in the range 2036-2104 and
2548 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549 */
2550 tmpsecs = tvb_get_ntohl(tvb, start);
2551 if ((tmpsecs & 0x80000000) != 0)
2552 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2553 else
2554 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2555 time_stamp->nsecs = 0;
2556 } else {
2557 time_stamp->secs = 0;
2558 time_stamp->nsecs = 0;
2559 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560 }
2561 break;
2562
2563 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2564 /*
2565 * NTP time stamp, with 1-second resolution (i.e.,
2566 * seconds since the NTP epoch), little-endian.
2567 * Only supported for absolute times.
2568 */
2569 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2569, "!is_relative"
))))
;
2570
2571 /*
2572 * We need a temporary variable here so the unsigned math
2573 * works correctly (for years > 2036 according to RFC 2030
2574 * chapter 3).
2575 *
2576 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578 * If bit 0 is not set, the time is in the range 2036-2104 and
2579 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580 */
2581 if (length == 4) {
2582 tmpsecs = tvb_get_letohl(tvb, start);
2583 if ((tmpsecs & 0x80000000) != 0)
2584 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2585 else
2586 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2587 time_stamp->nsecs = 0;
2588 } else {
2589 time_stamp->secs = 0;
2590 time_stamp->nsecs = 0;
2591 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592 }
2593 break;
2594
2595 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2596 /*
2597 * Milliseconds, 6 to 8 bytes.
2598 * For absolute times, it's milliseconds since the
2599 * NTP epoch.
2600 *
2601 * ETSI TS 129.274 8.119 defines this as:
2602 * "a 48 bit unsigned integer in network order format
2603 * ...encoded as the number of milliseconds since
2604 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605 * rounded value of 1000 x the value of the 64-bit
2606 * timestamp (Seconds + (Fraction / (1<<32))) defined
2607 * in clause 6 of IETF RFC 5905."
2608 *
2609 * Taken literally, the part after "i.e." would
2610 * mean that the value rolls over before reaching
2611 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612 * when the 64 bit timestamp rolls over, and we have
2613 * to pick an NTP Era equivalence class to support
2614 * (such as 1968-01-20 to 2104-02-06).
2615 *
2616 * OTOH, the extra room might be used to store Era
2617 * information instead, in which case times until
2618 * 10819-08-03 can be represented with 6 bytes without
2619 * ambiguity. We handle both implementations, and assume
2620 * that times before 1968-01-20 are not represented.
2621 *
2622 * Only 6 bytes or more makes sense as an absolute
2623 * time. 5 bytes or fewer could express a span of
2624 * less than 35 years, either 1900-1934 or 2036-2070.
2625 */
2626 if (length >= 6 && length <= 8) {
2627 uint64_t msecs;
2628
2629 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630 tmp64secs = (msecs / 1000);
2631 /*
2632 * Assume that times in the first half of NTP
2633 * Era 0 really represent times in the NTP
2634 * Era 1.
2635 */
2636 if (tmp64secs >= 0x80000000)
2637 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2638 else
2639 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2640 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641 }
2642 else {
2643 time_stamp->secs = 0;
2644 time_stamp->nsecs = 0;
2645 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646 }
2647 break;
2648
2649 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2650 /*
2651 * MP4 file time stamps, big-endian.
2652 * Only supported for absolute times.
2653 */
2654 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2654, "!is_relative"
))))
;
2655
2656 if (length == 8) {
2657 tmp64secs = tvb_get_ntoh64(tvb, start);
2658 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else if (length == 4) {
2661 tmpsecs = tvb_get_ntohl(tvb, start);
2662 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else {
2665 time_stamp->secs = 0;
2666 time_stamp->nsecs = 0;
2667 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668 }
2669 break;
2670
2671 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2672 /*
2673 * Zigbee ZCL time stamps, big-endian.
2674 * Only supported for absolute times.
2675 */
2676 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2676, "!is_relative"
))))
;
2677
2678 if (length == 8) {
2679 tmp64secs = tvb_get_ntoh64(tvb, start);
2680 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else if (length == 4) {
2683 tmpsecs = tvb_get_ntohl(tvb, start);
2684 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 time_stamp->nsecs = 0;
2686 } else {
2687 time_stamp->secs = 0;
2688 time_stamp->nsecs = 0;
2689 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690 }
2691 break;
2692
2693 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2694 /*
2695 * Zigbee ZCL time stamps, little-endian.
2696 * Only supported for absolute times.
2697 */
2698 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2698, "!is_relative"
))))
;
2699
2700 if (length == 8) {
2701 tmp64secs = tvb_get_letoh64(tvb, start);
2702 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else if (length == 4) {
2705 tmpsecs = tvb_get_letohl(tvb, start);
2706 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 time_stamp->nsecs = 0;
2708 } else {
2709 time_stamp->secs = 0;
2710 time_stamp->nsecs = 0;
2711 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 }
2713 break;
2714
2715 default:
2716 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2716))
;
2717 break;
2718 }
2719}
2720
2721static void
2722tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723{
2724 const header_field_info *hfinfo = fi->hfinfo;
2725
2726 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727 GPtrArray *ptrs = NULL((void*)0);
2728
2729 if (tree_data->interesting_hfids == NULL((void*)0)) {
2730 /* Initialize the hash because we now know that it is needed */
2731 tree_data->interesting_hfids =
2732 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2733 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2736 }
2737
2738 if (!ptrs) {
2739 /* First element triggers the creation of pointer array */
2740 ptrs = g_ptr_array_new();
2741 g_hash_table_insert(tree_data->interesting_hfids,
2742 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2743 }
2744
2745 g_ptr_array_add(ptrs, fi);
2746 }
2747}
2748
2749
2750/*
2751 * Validates that field length bytes are available starting from
2752 * start (pos/neg). Throws an exception if they aren't.
2753 */
2754static void
2755test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756 int start, int length, const unsigned encoding)
2757{
2758 int size = length;
2759
2760 if (!tvb)
2761 return;
2762
2763 if ((hfinfo->type == FT_STRINGZ) ||
2764 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2765 (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
))) {
2766 /* If we're fetching until the end of the TVB, only validate
2767 * that the offset is within range.
2768 */
2769 if (length == -1)
2770 size = 0;
2771 }
2772
2773 tvb_ensure_bytes_exist(tvb, start, size);
2774}
2775
2776static void
2777detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778{
2779 bool_Bool found_stray_character = false0;
2780
2781 if (!string)
2782 return;
2783
2784 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2785 case ENC_ASCII0x00000000:
2786 case ENC_UTF_80x00000002:
2787 for (int i = (int)strlen(string); i < length; i++) {
2788 if (string[i] != '\0') {
2789 found_stray_character = true1;
2790 break;
2791 }
2792 }
2793 break;
2794
2795 default:
2796 break;
2797 }
2798
2799 if (found_stray_character) {
2800 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2801 }
2802}
2803
2804static void
2805free_fvalue_cb(void *data)
2806{
2807 fvalue_t *fv = (fvalue_t*)data;
2808 fvalue_free(fv);
2809}
2810
2811/* Add an item to a proto_tree, using the text label registered to that item;
2812 the item is extracted from the tvbuff handed to it. */
2813static proto_item *
2814proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815 tvbuff_t *tvb, int start, int length,
2816 unsigned encoding)
2817{
2818 proto_item *pi;
2819 uint32_t value, n;
2820 uint64_t value64;
2821 ws_in4_addr ipv4_value;
2822 float floatval;
2823 double doubleval;
2824 const char *stringval = NULL((void*)0);
2825 nstime_t time_stamp;
2826 bool_Bool length_error;
2827
2828 /* Ensure that the newly created fvalue_t is freed if we throw an
2829 * exception before adding it to the tree. (gcc creates clobbering
2830 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831 * XXX: Move the new_field_info() call inside here?
2832 */
2833 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2834
2835 switch (new_fi->hfinfo->type) {
2836 case FT_NONE:
2837 /* no value to set for FT_NONE */
2838 break;
2839
2840 case FT_PROTOCOL:
2841 /* XXX - Why does this not create a subset tvb or otherwise take
2842 * start into account? Compare proto_tree_add_protocol_format,
2843 * which can throw an exception but this never throws an
2844 * exception. (But we perhaps don't want to throw an exception
2845 * here or there, see the IPv4 dissector.) */
2846 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2847 break;
2848
2849 case FT_BYTES:
2850 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2851 break;
2852
2853 case FT_UINT_BYTES:
2854 n = get_uint_value(tree, tvb, start, length, encoding);
2855 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2856
2857 /* Instead of calling proto_item_set_len(), since we don't yet
2858 * have a proto_item, we set the field_info's length ourselves. */
2859 new_fi->length = n + length;
2860 break;
2861
2862 case FT_BOOLEAN:
2863 /*
2864 * Map all non-zero values to little-endian for
2865 * backwards compatibility.
2866 */
2867 if (encoding)
2868 encoding = ENC_LITTLE_ENDIAN0x80000000;
2869 proto_tree_set_boolean(new_fi,
2870 get_uint64_value(tree, tvb, start, length, encoding));
2871 break;
2872
2873 case FT_CHAR:
2874 /* XXX - make these just FT_UINT? */
2875 case FT_UINT8:
2876 case FT_UINT16:
2877 case FT_UINT24:
2878 case FT_UINT32:
2879 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2880 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2881 value = (uint32_t)value64;
2882 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2883 new_fi->flags |= FI_VARINT0x00040000;
2884 }
2885 }
2886 else {
2887 /*
2888 * Map all non-zero values to little-endian for
2889 * backwards compatibility.
2890 */
2891 if (encoding)
2892 encoding = ENC_LITTLE_ENDIAN0x80000000;
2893
2894 value = get_uint_value(tree, tvb, start, length, encoding);
2895 }
2896 proto_tree_set_uint(new_fi, value);
2897 break;
2898
2899 case FT_UINT40:
2900 case FT_UINT48:
2901 case FT_UINT56:
2902 case FT_UINT64:
2903 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2904 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2905 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2906 new_fi->flags |= FI_VARINT0x00040000;
2907 }
2908 }
2909 else {
2910 /*
2911 * Map all other non-zero values to little-endian for
2912 * backwards compatibility.
2913 */
2914 if (encoding)
2915 encoding = ENC_LITTLE_ENDIAN0x80000000;
2916
2917 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2918 }
2919 proto_tree_set_uint64(new_fi, value64);
2920 break;
2921
2922 /* XXX - make these just FT_INT? */
2923 case FT_INT8:
2924 case FT_INT16:
2925 case FT_INT24:
2926 case FT_INT32:
2927 /*
2928 * Map all non-zero values to little-endian for
2929 * backwards compatibility.
2930 */
2931 if (encoding)
2932 encoding = ENC_LITTLE_ENDIAN0x80000000;
2933 proto_tree_set_int(new_fi,
2934 get_int_value(tree, tvb, start, length, encoding));
2935 break;
2936
2937 case FT_INT40:
2938 case FT_INT48:
2939 case FT_INT56:
2940 case FT_INT64:
2941 /*
2942 * Map all non-zero values to little-endian for
2943 * backwards compatibility.
2944 */
2945 if (encoding)
2946 encoding = ENC_LITTLE_ENDIAN0x80000000;
2947 proto_tree_set_int64(new_fi,
2948 get_int64_value(tree, tvb, start, length, encoding));
2949 break;
2950
2951 case FT_IPv4:
2952 /*
2953 * Map all non-zero values to little-endian for
2954 * backwards compatibility.
2955 */
2956 if (encoding)
2957 encoding = ENC_LITTLE_ENDIAN0x80000000;
2958 if (length != FT_IPv4_LEN4) {
2959 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2960 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2961 }
2962 ipv4_value = tvb_get_ipv4(tvb, start);
2963 /*
2964 * NOTE: to support code written when
2965 * proto_tree_add_item() took a bool as its
2966 * last argument, with false meaning "big-endian"
2967 * and true meaning "little-endian", we treat any
2968 * non-zero value of "encoding" as meaning
2969 * "little-endian".
2970 */
2971 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);
2972 break;
2973
2974 case FT_IPXNET:
2975 if (length != FT_IPXNET_LEN4) {
2976 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2977 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2978 }
2979 proto_tree_set_ipxnet(new_fi,
2980 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2981 break;
2982
2983 case FT_IPv6:
2984 if (length != FT_IPv6_LEN16) {
2985 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2986 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2987 }
2988 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2989 break;
2990
2991 case FT_FCWWN:
2992 if (length != FT_FCWWN_LEN8) {
2993 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2994 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2995 }
2996 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2997 break;
2998
2999 case FT_AX25:
3000 if (length != 7) {
3001 length_error = length < 7 ? true1 : false0;
3002 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3003 }
3004 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3005 break;
3006
3007 case FT_VINES:
3008 if (length != VINES_ADDR_LEN6) {
3009 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3010 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3011 }
3012 proto_tree_set_vines_tvb(new_fi, tvb, start);
3013 break;
3014
3015 case FT_ETHER:
3016 if (length != FT_ETHER_LEN6) {
3017 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3018 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3019 }
3020 proto_tree_set_ether_tvb(new_fi, tvb, start);
3021 break;
3022
3023 case FT_EUI64:
3024 /*
3025 * Map all non-zero values to little-endian for
3026 * backwards compatibility.
3027 */
3028 if (encoding)
3029 encoding = ENC_LITTLE_ENDIAN0x80000000;
3030 if (length != FT_EUI64_LEN8) {
3031 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3032 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3033 }
3034 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3035 break;
3036 case FT_GUID:
3037 /*
3038 * Map all non-zero values to little-endian for
3039 * backwards compatibility.
3040 */
3041 if (encoding)
3042 encoding = ENC_LITTLE_ENDIAN0x80000000;
3043 if (length != FT_GUID_LEN16) {
3044 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3045 report_type_length_mismatch(tree, "a GUID", length, length_error);
3046 }
3047 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3048 break;
3049
3050 case FT_OID:
3051 case FT_REL_OID:
3052 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3053 break;
3054
3055 case FT_SYSTEM_ID:
3056 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3057 break;
3058
3059 case FT_FLOAT:
3060 /*
3061 * NOTE: to support code written when
3062 * proto_tree_add_item() took a bool as its
3063 * last argument, with false meaning "big-endian"
3064 * and true meaning "little-endian", we treat any
3065 * non-zero value of "encoding" as meaning
3066 * "little-endian".
3067 *
3068 * At some point in the future, we might
3069 * support non-IEEE-binary floating-point
3070 * formats in the encoding as well
3071 * (IEEE decimal, System/3x0, VAX).
3072 */
3073 if (encoding)
3074 encoding = ENC_LITTLE_ENDIAN0x80000000;
3075 if (length != 4) {
3076 length_error = length < 4 ? true1 : false0;
3077 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3078 }
3079 if (encoding)
3080 floatval = tvb_get_letohieee_float(tvb, start);
3081 else
3082 floatval = tvb_get_ntohieee_float(tvb, start);
3083 proto_tree_set_float(new_fi, floatval);
3084 break;
3085
3086 case FT_DOUBLE:
3087 /*
3088 * NOTE: to support code written when
3089 * proto_tree_add_item() took a bool as its
3090 * last argument, with false meaning "big-endian"
3091 * and true meaning "little-endian", we treat any
3092 * non-zero value of "encoding" as meaning
3093 * "little-endian".
3094 *
3095 * At some point in the future, we might
3096 * support non-IEEE-binary floating-point
3097 * formats in the encoding as well
3098 * (IEEE decimal, System/3x0, VAX).
3099 */
3100 if (encoding == true1)
3101 encoding = ENC_LITTLE_ENDIAN0x80000000;
3102 if (length != 8) {
3103 length_error = length < 8 ? true1 : false0;
3104 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3105 }
3106 if (encoding)
3107 doubleval = tvb_get_letohieee_double(tvb, start);
3108 else
3109 doubleval = tvb_get_ntohieee_double(tvb, start);
3110 proto_tree_set_double(new_fi, doubleval);
3111 break;
3112
3113 case FT_STRING:
3114 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3115 tvb, start, length, &length, encoding);
3116 proto_tree_set_string(new_fi, stringval);
3117
3118 /* Instead of calling proto_item_set_len(), since we
3119 * don't yet have a proto_item, we set the
3120 * field_info's length ourselves.
3121 *
3122 * XXX - our caller can't use that length to
3123 * advance an offset unless they arrange that
3124 * there always be a protocol tree into which
3125 * we're putting this item.
3126 */
3127 new_fi->length = length;
3128 break;
3129
3130 case FT_STRINGZ:
3131 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3132 tree, tvb, start, length, &length, encoding);
3133 proto_tree_set_string(new_fi, stringval);
3134
3135 /* Instead of calling proto_item_set_len(),
3136 * since we don't yet have a proto_item, we
3137 * set the field_info's length ourselves.
3138 *
3139 * XXX - our caller can't use that length to
3140 * advance an offset unless they arrange that
3141 * there always be a protocol tree into which
3142 * we're putting this item.
3143 */
3144 new_fi->length = length;
3145 break;
3146
3147 case FT_UINT_STRING:
3148 /*
3149 * NOTE: to support code written when
3150 * proto_tree_add_item() took a bool as its
3151 * last argument, with false meaning "big-endian"
3152 * and true meaning "little-endian", if the
3153 * encoding value is true, treat that as
3154 * ASCII with a little-endian length.
3155 *
3156 * This won't work for code that passes
3157 * arbitrary non-zero values; that code
3158 * will need to be fixed.
3159 */
3160 if (encoding == true1)
3161 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3162 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3163 tree, tvb, start, length, &length, encoding);
3164 proto_tree_set_string(new_fi, stringval);
3165
3166 /* Instead of calling proto_item_set_len(), since we
3167 * don't yet have a proto_item, we set the
3168 * field_info's length ourselves.
3169 *
3170 * XXX - our caller can't use that length to
3171 * advance an offset unless they arrange that
3172 * there always be a protocol tree into which
3173 * we're putting this item.
3174 */
3175 new_fi->length = length;
3176 break;
3177
3178 case FT_STRINGZPAD:
3179 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3180 tvb, start, length, &length, encoding);
3181 proto_tree_set_string(new_fi, stringval);
3182
3183 /* Instead of calling proto_item_set_len(), since we
3184 * don't yet have a proto_item, we set the
3185 * field_info's length ourselves.
3186 *
3187 * XXX - our caller can't use that length to
3188 * advance an offset unless they arrange that
3189 * there always be a protocol tree into which
3190 * we're putting this item.
3191 */
3192 new_fi->length = length;
3193 break;
3194
3195 case FT_STRINGZTRUNC:
3196 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3197 tvb, start, length, &length, encoding);
3198 proto_tree_set_string(new_fi, stringval);
3199
3200 /* Instead of calling proto_item_set_len(), since we
3201 * don't yet have a proto_item, we set the
3202 * field_info's length ourselves.
3203 *
3204 * XXX - our caller can't use that length to
3205 * advance an offset unless they arrange that
3206 * there always be a protocol tree into which
3207 * we're putting this item.
3208 */
3209 new_fi->length = length;
3210 break;
3211
3212 case FT_ABSOLUTE_TIME:
3213 /*
3214 * Absolute times can be in any of a number of
3215 * formats, and they can be big-endian or
3216 * little-endian.
3217 *
3218 * Historically FT_TIMEs were only timespecs;
3219 * the only question was whether they were stored
3220 * in big- or little-endian format.
3221 *
3222 * For backwards compatibility, we interpret an
3223 * encoding of 1 as meaning "little-endian timespec",
3224 * so that passing true is interpreted as that.
3225 */
3226 if (encoding == true1)
3227 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3228
3229 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3230
3231 proto_tree_set_time(new_fi, &time_stamp);
3232 break;
3233
3234 case FT_RELATIVE_TIME:
3235 /*
3236 * Relative times can be in any of a number of
3237 * formats, and they can be big-endian or
3238 * little-endian.
3239 *
3240 * Historically FT_TIMEs were only timespecs;
3241 * the only question was whether they were stored
3242 * in big- or little-endian format.
3243 *
3244 * For backwards compatibility, we interpret an
3245 * encoding of 1 as meaning "little-endian timespec",
3246 * so that passing true is interpreted as that.
3247 */
3248 if (encoding == true1)
3249 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3250
3251 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3252
3253 proto_tree_set_time(new_fi, &time_stamp);
3254 break;
3255 case FT_IEEE_11073_SFLOAT:
3256 if (encoding)
3257 encoding = ENC_LITTLE_ENDIAN0x80000000;
3258 if (length != 2) {
3259 length_error = length < 2 ? true1 : false0;
3260 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3261 }
3262
3263 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3264
3265 break;
3266 case FT_IEEE_11073_FLOAT:
3267 if (encoding)
3268 encoding = ENC_LITTLE_ENDIAN0x80000000;
3269 if (length != 4) {
3270 length_error = length < 4 ? true1 : false0;
3271 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3272 }
3273 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3274
3275 break;
3276 default:
3277 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))
3278 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))
3279 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))
3280 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))
;
3281 break;
3282 }
3283 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)
;
3284
3285 /* Don't add new node to proto_tree until now so that any exceptions
3286 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3287 /* XXX. wouldn't be better to add this item to tree, with some special
3288 * flag (FI_EXCEPTION?) to know which item caused exception? For
3289 * strings and bytes, we would have to set new_fi->value to something
3290 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3291 * could handle NULL values. */
3292 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3293 pi = proto_tree_add_node(tree, new_fi);
3294
3295 switch (new_fi->hfinfo->type) {
3296
3297 case FT_STRING:
3298 /* XXX: trailing stray character detection should be done
3299 * _before_ conversion to UTF-8, because conversion can change
3300 * the length, or else get_string_length should return a value
3301 * for the "length in bytes of the string after conversion
3302 * including internal nulls." (Noting that we do, for other
3303 * reasons, still need the "length in bytes in the field",
3304 * especially for FT_STRINGZ.)
3305 *
3306 * This is true even for ASCII and UTF-8, because
3307 * substituting REPLACEMENT CHARACTERS for illegal characters
3308 * can also do so (and for UTF-8 possibly even make the
3309 * string _shorter_).
3310 */
3311 detect_trailing_stray_characters(encoding, stringval, length, pi);
3312 break;
3313
3314 default:
3315 break;
3316 }
3317
3318 return pi;
3319}
3320
3321proto_item *
3322proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3323 const int start, int length,
3324 const unsigned encoding, int32_t *retval)
3325{
3326 header_field_info *hfinfo;
3327 field_info *new_fi;
3328 int32_t value;
3329
3330 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", 3330, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3330,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3330, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3331
3332 switch (hfinfo->type) {
3333 case FT_INT8:
3334 case FT_INT16:
3335 case FT_INT24:
3336 case FT_INT32:
3337 break;
3338 case FT_INT64:
3339 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)
3340 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3341 default:
3342 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)
3343 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3344 }
3345
3346 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3347 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3348 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3349 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3350 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3351 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3352 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3353
3354 if (encoding & ENC_STRING0x07000000) {
3355 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3356 }
3357 /* I believe it's ok if this is called with a NULL tree */
3358 value = get_int_value(tree, tvb, start, length, encoding);
3359
3360 if (retval) {
3361 int no_of_bits;
3362 *retval = value;
3363 if (hfinfo->bitmask) {
3364 /* Mask out irrelevant portions */
3365 *retval &= (uint32_t)(hfinfo->bitmask);
3366 /* Shift bits */
3367 *retval >>= hfinfo_bitshift(hfinfo);
3368 }
3369 no_of_bits = ws_count_ones(hfinfo->bitmask);
3370 *retval = ws_sign_ext32(*retval, no_of_bits);
3371 }
3372
3373 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3374
3375 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", 3375
, __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", 3375, "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", 3375, "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", 3375, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3376
3377 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3378
3379 proto_tree_set_int(new_fi, value);
3380
3381 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3382
3383 return proto_tree_add_node(tree, new_fi);
3384}
3385
3386proto_item *
3387proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3388 const int start, int length,
3389 const unsigned encoding, uint32_t *retval)
3390{
3391 header_field_info *hfinfo;
3392 field_info *new_fi;
3393 uint32_t value;
3394
3395 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", 3395, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3395,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3395, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3396
3397 switch (hfinfo->type) {
3398 case FT_CHAR:
3399 case FT_UINT8:
3400 case FT_UINT16:
3401 case FT_UINT24:
3402 case FT_UINT32:
3403 break;
3404 default:
3405 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)
3406 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)
;
3407 }
3408
3409 if (length == 0) {
3410 if (retval) {
3411 *retval = 0;
3412 }
3413 return NULL((void*)0);
3414 }
3415
3416 if (encoding & ENC_STRING0x07000000) {
3417 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3418 }
3419 /* I believe it's ok if this is called with a NULL tree */
3420 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3421 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3422 uint64_t temp64;
3423 tvb_get_varint(tvb, start, length, &temp64, encoding);
3424 value = (uint32_t)temp64;
3425 } else {
3426 value = get_uint_value(tree, tvb, start, length, encoding);
3427 }
3428
3429 if (retval) {
3430 *retval = value;
3431 if (hfinfo->bitmask) {
3432 /* Mask out irrelevant portions */
3433 *retval &= (uint32_t)(hfinfo->bitmask);
3434 /* Shift bits */
3435 *retval >>= hfinfo_bitshift(hfinfo);
3436 }
3437 }
3438
3439 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3440
3441 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", 3441
, __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", 3441, "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", 3441, "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", 3441, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3442
3443 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3444
3445 proto_tree_set_uint(new_fi, value);
3446
3447 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3448 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3449 new_fi->flags |= FI_VARINT0x00040000;
3450 }
3451 return proto_tree_add_node(tree, new_fi);
3452}
3453
3454proto_item *
3455proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3456 const int start, int length,
3457 const unsigned encoding, uint32_t *retval)
3458{
3459 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3460}
3461
3462proto_item *
3463proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3464 const int start, int length,
3465 const unsigned encoding, uint8_t *retval)
3466{
3467 /* TODO: further restrict by hfinfo->type ? */
3468 uint32_t val32;
3469 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3470 *retval = (uint8_t)val32;
3471 return item;
3472}
3473
3474proto_item *
3475proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3476 const int start, int length,
3477 const unsigned encoding, uint16_t *retval)
3478{
3479 /* TODO: further restrict by hfinfo->type ? */
3480 uint32_t val32;
3481 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3482 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3483 return item;
3484}
3485
3486
3487/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3488 * and returns proto_item* and uint value retrieved*/
3489proto_item *
3490ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3491 const unsigned encoding, uint32_t *retval)
3492{
3493 field_info *new_fi;
3494 header_field_info *hfinfo;
3495 unsigned item_length;
3496 unsigned offset;
3497 uint32_t value;
3498
3499 offset = ptvc->offset;
3500 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", 3500, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3500,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3500, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3501
3502 switch (hfinfo->type) {
3503 case FT_CHAR:
3504 case FT_UINT8:
3505 case FT_UINT16:
3506 case FT_UINT24:
3507 case FT_UINT32:
3508 break;
3509 default:
3510 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)
3511 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)
;
3512 }
3513
3514 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3515 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3516
3517 /* I believe it's ok if this is called with a NULL tree */
3518 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3519 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3520
3521 if (retval) {
3522 *retval = value;
3523 if (hfinfo->bitmask) {
3524 /* Mask out irrelevant portions */
3525 *retval &= (uint32_t)(hfinfo->bitmask);
3526 /* Shift bits */
3527 *retval >>= hfinfo_bitshift(hfinfo);
3528 }
3529 }
3530
3531 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3532
3533 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3534
3535 /* Coast clear. Try and fake it */
3536 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", 3536
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3536, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3536, "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", 3536, __func__, "Adding %s would put more than %d 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); } } }
;
3537
3538 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3539
3540 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3541 offset, length, encoding);
3542}
3543
3544/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3545 * and returns proto_item* and int value retrieved*/
3546proto_item *
3547ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3548 const unsigned encoding, int32_t *retval)
3549{
3550 field_info *new_fi;
3551 header_field_info *hfinfo;
3552 unsigned item_length;
3553 unsigned offset;
3554 uint32_t value;
3555
3556 offset = ptvc->offset;
3557 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", 3557, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3557,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3557, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3558
3559 switch (hfinfo->type) {
3560 case FT_INT8:
3561 case FT_INT16:
3562 case FT_INT24:
3563 case FT_INT32:
3564 break;
3565 default:
3566 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)
3567 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3568 }
3569
3570 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3571 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3572
3573 /* I believe it's ok if this is called with a NULL tree */
3574 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3575 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3576
3577 if (retval) {
3578 int no_of_bits;
3579 *retval = value;
3580 if (hfinfo->bitmask) {
3581 /* Mask out irrelevant portions */
3582 *retval &= (uint32_t)(hfinfo->bitmask);
3583 /* Shift bits */
3584 *retval >>= hfinfo_bitshift(hfinfo);
3585 }
3586 no_of_bits = ws_count_ones(hfinfo->bitmask);
3587 *retval = ws_sign_ext32(*retval, no_of_bits);
3588 }
3589
3590 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3591
3592 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3593
3594 /* Coast clear. Try and fake it */
3595 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", 3595
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3595, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3595, "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", 3595, __func__, "Adding %s would put more than %d 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); } } }
;
3596
3597 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3598
3599 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3600 offset, length, encoding);
3601}
3602
3603/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3604 * and returns proto_item* and string value retrieved */
3605proto_item*
3606ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3607{
3608 header_field_info *hfinfo;
3609 field_info *new_fi;
3610 const uint8_t *value;
3611 unsigned item_length;
3612 unsigned offset;
3613
3614 offset = ptvc->offset;
3615
3616 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", 3616
, __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", 3616, "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", 3616, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3617
3618 switch (hfinfo->type) {
3619 case FT_STRING:
3620 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3621 break;
3622 case FT_STRINGZ:
3623 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3624 break;
3625 case FT_UINT_STRING:
3626 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3627 break;
3628 case FT_STRINGZPAD:
3629 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3630 break;
3631 case FT_STRINGZTRUNC:
3632 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3633 break;
3634 default:
3635 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)
3636 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)
;
3637 }
3638
3639 if (retval)
3640 *retval = value;
3641
3642 ptvcursor_advance(ptvc, item_length);
3643
3644 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3645
3646 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", 3646, __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", 3646,
"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", 3646, "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", 3646
, __func__, "Adding %s would put more than %d 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); } } }
;
3647
3648 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3649
3650 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3651 offset, length, encoding);
3652}
3653
3654/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3655 * and returns proto_item* and boolean value retrieved */
3656proto_item*
3657ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3658{
3659 header_field_info *hfinfo;
3660 field_info *new_fi;
3661 unsigned item_length;
3662 unsigned offset;
3663 uint64_t value, bitval;
3664
3665 offset = ptvc->offset;
3666 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", 3666, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3666,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3666, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3667
3668 if (hfinfo->type != FT_BOOLEAN) {
3669 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)
3670 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3671 }
3672
3673 if (length == 0) {
3674 if (retval) {
3675 *retval = 0;
3676 }
3677 return NULL((void*)0);
3678 }
3679 if (encoding & ENC_STRING0x07000000) {
3680 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3681 }
3682
3683 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3684 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3685
3686 /* I believe it's ok if this is called with a NULL tree */
3687 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3688
3689 if (retval) {
3690 bitval = value;
3691 if (hfinfo->bitmask) {
3692 /* Mask out irrelevant portions */
3693 bitval &= hfinfo->bitmask;
3694 }
3695 *retval = (bitval != 0);
3696 }
3697
3698 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3699
3700 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3701
3702 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", 3702, __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", 3702,
"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", 3702, "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", 3702
, __func__, "Adding %s would put more than %d 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); } } }
;
3703
3704 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3705
3706 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3707 offset, length, encoding);
3708}
3709
3710proto_item *
3711proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3712 const int start, int length, const unsigned encoding, uint64_t *retval)
3713{
3714 header_field_info *hfinfo;
3715 field_info *new_fi;
3716 uint64_t value;
3717
3718 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", 3718, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3718,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3718, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3719
3720 switch (hfinfo->type) {
3721 case FT_UINT40:
3722 case FT_UINT48:
3723 case FT_UINT56:
3724 case FT_UINT64:
3725 break;
3726 default:
3727 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)
3728 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3729 }
3730
3731 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3732 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3733 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3734 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3735 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3736 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3737 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3738
3739 if (encoding & ENC_STRING0x07000000) {
3740 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3741 }
3742 /* I believe it's ok if this is called with a NULL tree */
3743 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3744 tvb_get_varint(tvb, start, length, &value, encoding);
3745 } else {
3746 value = get_uint64_value(tree, tvb, start, length, encoding);
3747 }
3748
3749 if (retval) {
3750 *retval = value;
3751 if (hfinfo->bitmask) {
3752 /* Mask out irrelevant portions */
3753 *retval &= hfinfo->bitmask;
3754 /* Shift bits */
3755 *retval >>= hfinfo_bitshift(hfinfo);
3756 }
3757 }
3758
3759 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3760
3761 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", 3761
, __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", 3761, "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", 3761, "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", 3761, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3762
3763 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3764
3765 proto_tree_set_uint64(new_fi, value);
3766
3767 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3768 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3769 new_fi->flags |= FI_VARINT0x00040000;
3770 }
3771
3772 return proto_tree_add_node(tree, new_fi);
3773}
3774
3775proto_item *
3776proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3777 const int start, int length, const unsigned encoding, int64_t *retval)
3778{
3779 header_field_info *hfinfo;
3780 field_info *new_fi;
3781 int64_t value;
3782
3783 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", 3783, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3783,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3783, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3784
3785 switch (hfinfo->type) {
3786 case FT_INT40:
3787 case FT_INT48:
3788 case FT_INT56:
3789 case FT_INT64:
3790 break;
3791 default:
3792 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)
3793 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3794 }
3795
3796 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3797 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3798 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3799 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3800 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3801 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3802 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3803
3804 if (encoding & ENC_STRING0x07000000) {
3805 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3806 }
3807 /* I believe it's ok if this is called with a NULL tree */
3808 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3809 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3810 }
3811 else {
3812 value = get_int64_value(tree, tvb, start, length, encoding);
3813 }
3814
3815 if (retval) {
3816 *retval = value;
3817 }
3818
3819 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3820
3821 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", 3821
, __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", 3821, "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", 3821, "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", 3821, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3822
3823 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3824
3825 proto_tree_set_int64(new_fi, value);
3826
3827 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3828 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3829 new_fi->flags |= FI_VARINT0x00040000;
3830 }
3831
3832 return proto_tree_add_node(tree, new_fi);
3833}
3834
3835proto_item *
3836proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3837 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3838{
3839 header_field_info *hfinfo;
3840 field_info *new_fi;
3841 uint64_t value;
3842
3843 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", 3843, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3843,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3843, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3844
3845 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
))
)) {
3846 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)
3847 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3848 }
3849
3850 /* length validation for native number encoding caught by get_uint64_value() */
3851 /* length has to be -1 or > 0 regardless of encoding */
3852 if (length == 0)
3853 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
3854 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3855
3856 if (encoding & ENC_STRING0x07000000) {
3857 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3858 }
3859
3860 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3861
3862 if (retval) {
3863 *retval = value;
3864 if (hfinfo->bitmask) {
3865 /* Mask out irrelevant portions */
3866 *retval &= hfinfo->bitmask;
3867 /* Shift bits */
3868 *retval >>= hfinfo_bitshift(hfinfo);
3869 }
3870 }
3871
3872 if (lenretval) {
3873 *lenretval = length;
3874 }
3875
3876 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3877
3878 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", 3878
, __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", 3878, "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", 3878, "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", 3878, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3879
3880 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3881
3882 proto_tree_set_uint64(new_fi, value);
3883
3884 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3885 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3886 new_fi->flags |= FI_VARINT0x00040000;
3887 }
3888
3889 return proto_tree_add_node(tree, new_fi);
3890
3891}
3892
3893proto_item *
3894proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3895 const int start, int length,
3896 const unsigned encoding, bool_Bool *retval)
3897{
3898 header_field_info *hfinfo;
3899 field_info *new_fi;
3900 uint64_t value, bitval;
3901
3902 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", 3902, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3902,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3902, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3903
3904 if (hfinfo->type != FT_BOOLEAN) {
3905 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)
3906 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3907 }
3908
3909 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3910 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3911 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3912 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3913 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3914 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3915 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3916
3917 if (encoding & ENC_STRING0x07000000) {
3918 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3919 }
3920 /* I believe it's ok if this is called with a NULL tree */
3921 value = get_uint64_value(tree, tvb, start, length, encoding);
3922
3923 if (retval) {
3924 bitval = value;
3925 if (hfinfo->bitmask) {
3926 /* Mask out irrelevant portions */
3927 bitval &= hfinfo->bitmask;
3928 }
3929 *retval = (bitval != 0);
3930 }
3931
3932 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3933
3934 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", 3934
, __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", 3934, "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", 3934, "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", 3934, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3935
3936 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3937
3938 proto_tree_set_boolean(new_fi, value);
3939
3940 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3941
3942 return proto_tree_add_node(tree, new_fi);
3943}
3944
3945proto_item *
3946proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3947 const int start, int length,
3948 const unsigned encoding, float *retval)
3949{
3950 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3951 field_info *new_fi;
3952 float value;
3953
3954 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", 3954,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3955
3956 if (hfinfo->type != FT_FLOAT) {
3957 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)
;
3958 }
3959
3960 if (length != 4) {
3961 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3962 }
3963
3964 /* treat any nonzero encoding as little endian for backwards compatibility */
3965 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3966 if (retval) {
3967 *retval = value;
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 if (encoding) {
3976 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3977 }
3978
3979 proto_tree_set_float(new_fi, value);
3980
3981 return proto_tree_add_node(tree, new_fi);
3982}
3983
3984proto_item *
3985proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3986 const int start, int length,
3987 const unsigned encoding, double *retval)
3988{
3989 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3990 field_info *new_fi;
3991 double value;
3992
3993 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", 3993,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3994
3995 if (hfinfo->type != FT_DOUBLE) {
3996 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)
;
3997 }
3998
3999 if (length != 8) {
4000 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4001 }
4002
4003 /* treat any nonzero encoding as little endian for backwards compatibility */
4004 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4005 if (retval) {
4006 *retval = value;
4007 }
4008
4009 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4010
4011 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", 4011
, __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", 4011, "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", 4011, "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", 4011, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4012
4013 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4014 if (encoding) {
4015 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4016 }
4017
4018 proto_tree_set_double(new_fi, value);
4019
4020 return proto_tree_add_node(tree, new_fi);
4021}
4022
4023proto_item *
4024proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4025 const int start, int length,
4026 const unsigned encoding, ws_in4_addr *retval)
4027{
4028 header_field_info *hfinfo;
4029 field_info *new_fi;
4030 ws_in4_addr value;
4031
4032 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", 4032, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4032,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4032, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4033
4034 switch (hfinfo->type) {
4035 case FT_IPv4:
4036 break;
4037 default:
4038 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)
4039 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4040 }
4041
4042 if (length != FT_IPv4_LEN4)
4043 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)
4044 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4045
4046 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4047 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4048 }
4049
4050 /*
4051 * NOTE: to support code written when proto_tree_add_item() took
4052 * a bool as its last argument, with false meaning "big-endian"
4053 * and true meaning "little-endian", we treat any non-zero value
4054 * of "encoding" as meaning "little-endian".
4055 */
4056 value = tvb_get_ipv4(tvb, start);
4057 if (encoding)
4058 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))))
;
4059
4060 if (retval) {
4061 *retval = value;
4062 }
4063
4064 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4065
4066 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", 4066
, __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", 4066, "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", 4066, "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", 4066, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4067
4068 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4069
4070 proto_tree_set_ipv4(new_fi, value);
4071
4072 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4073 return proto_tree_add_node(tree, new_fi);
4074}
4075
4076proto_item *
4077proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4078 const int start, int length,
4079 const unsigned encoding, ws_in6_addr *addr)
4080{
4081 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4082 field_info *new_fi;
4083
4084 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", 4084,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4085
4086 switch (hfinfo->type) {
4087 case FT_IPv6:
4088 break;
4089 default:
4090 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)
4091 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4092 }
4093
4094 if (length != FT_IPv6_LEN16)
4095 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)
4096 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4097
4098 if (encoding) {
4099 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"
)
;
4100 }
4101
4102 tvb_get_ipv6(tvb, start, addr);
4103
4104 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4105
4106 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", 4106
, __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", 4106, "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", 4106, "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", 4106, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4107
4108 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4109
4110 proto_tree_set_ipv6(new_fi, addr);
4111
4112 return proto_tree_add_node(tree, new_fi);
4113}
4114
4115proto_item *
4116proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4117 const int start, int length, const unsigned encoding, uint8_t *retval) {
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_ETHER:
4126 break;
4127 default:
4128 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)
4129 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4130 }
4131
4132 if (length != FT_ETHER_LEN6)
4133 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)
4134 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4135
4136 if (encoding) {
4137 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"
)
;
4138 }
4139
4140 tvb_memcpy(tvb, retval, start, length);
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_ether(new_fi, retval);
4149
4150 return proto_tree_add_node(tree, new_fi);
4151}
4152
4153
4154proto_item *
4155proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4156 tvbuff_t *tvb,
4157 const int start, int length,
4158 const unsigned encoding,
4159 wmem_allocator_t *scope,
4160 const uint8_t **retval,
4161 int *lenretval)
4162{
4163 proto_item *pi;
4164 header_field_info *hfinfo;
4165 field_info *new_fi;
4166 const uint8_t *value;
4167
4168 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", 4168, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4168,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4168, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4169
4170 switch (hfinfo->type) {
4171 case FT_STRING:
4172 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4173 break;
4174 case FT_STRINGZ:
4175 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4176 break;
4177 case FT_UINT_STRING:
4178 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4179 break;
4180 case FT_STRINGZPAD:
4181 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4182 break;
4183 case FT_STRINGZTRUNC:
4184 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4185 break;
4186 default:
4187 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)
4188 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)
;
4189 }
4190
4191 if (retval)
4192 *retval = value;
4193
4194 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4195
4196 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", 4196
, __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", 4196, "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", 4196, "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", 4196, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4197
4198 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4199
4200 proto_tree_set_string(new_fi, (const char*)value);
4201
4202 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4203
4204 pi = proto_tree_add_node(tree, new_fi);
4205
4206 switch (hfinfo->type) {
4207
4208 case FT_STRINGZ:
4209 case FT_STRINGZPAD:
4210 case FT_STRINGZTRUNC:
4211 case FT_UINT_STRING:
4212 break;
4213
4214 case FT_STRING:
4215 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4216 break;
4217
4218 default:
4219 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4219
, __func__, "assertion \"not reached\" failed")
;
4220 }
4221
4222 return pi;
4223}
4224
4225proto_item *
4226proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4227 const int start, int length,
4228 const unsigned encoding, wmem_allocator_t *scope,
4229 const uint8_t **retval)
4230{
4231 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4232 tvb, start, length, encoding, scope, retval, &length);
4233}
4234
4235proto_item *
4236proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4237 tvbuff_t *tvb,
4238 const int start, int length,
4239 const unsigned encoding,
4240 wmem_allocator_t *scope,
4241 char **retval,
4242 int *lenretval)
4243{
4244 proto_item *pi;
4245 header_field_info *hfinfo;
4246 field_info *new_fi;
4247 const uint8_t *value;
4248 uint32_t n = 0;
4249
4250 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", 4250, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4250,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4250, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4251
4252 switch (hfinfo->type) {
4253 case FT_STRING:
4254 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4255 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4256 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4257 break;
4258 case FT_STRINGZ:
4259 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4260 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4261 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4262 break;
4263 case FT_UINT_STRING:
4264 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4265 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4266 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4267 break;
4268 case FT_STRINGZPAD:
4269 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4270 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4271 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4272 break;
4273 case FT_STRINGZTRUNC:
4274 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4275 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4276 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4277 break;
4278 case FT_BYTES:
4279 tvb_ensure_bytes_exist(tvb, start, length);
4280 value = tvb_get_ptr(tvb, start, length);
4281 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4282 *lenretval = length;
4283 break;
4284 case FT_UINT_BYTES:
4285 n = get_uint_value(tree, tvb, start, length, encoding);
4286 tvb_ensure_bytes_exist(tvb, start + length, n);
4287 value = tvb_get_ptr(tvb, start + length, n);
4288 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4289 *lenretval = length + n;
4290 break;
4291 default:
4292 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)
4293 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)
;
4294 }
4295
4296 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4297
4298 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", 4298
, __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", 4298, "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", 4298, "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", 4298, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4299
4300 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4301
4302 switch (hfinfo->type) {
4303
4304 case FT_STRING:
4305 case FT_STRINGZ:
4306 case FT_UINT_STRING:
4307 case FT_STRINGZPAD:
4308 case FT_STRINGZTRUNC:
4309 proto_tree_set_string(new_fi, (const char*)value);
4310 break;
4311
4312 case FT_BYTES:
4313 proto_tree_set_bytes(new_fi, value, length);
4314 break;
4315
4316 case FT_UINT_BYTES:
4317 proto_tree_set_bytes(new_fi, value, n);
4318 break;
4319
4320 default:
4321 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4321
, __func__, "assertion \"not reached\" failed")
;
4322 }
4323
4324 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4325
4326 pi = proto_tree_add_node(tree, new_fi);
4327
4328 switch (hfinfo->type) {
4329
4330 case FT_STRINGZ:
4331 case FT_STRINGZPAD:
4332 case FT_STRINGZTRUNC:
4333 case FT_UINT_STRING:
4334 break;
4335
4336 case FT_STRING:
4337 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4338 break;
4339
4340 case FT_BYTES:
4341 case FT_UINT_BYTES:
4342 break;
4343
4344 default:
4345 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4345
, __func__, "assertion \"not reached\" failed")
;
4346 }
4347
4348 return pi;
4349}
4350
4351proto_item *
4352proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4353 tvbuff_t *tvb,
4354 const int start, int length,
4355 const unsigned encoding,
4356 wmem_allocator_t *scope,
4357 char **retval)
4358{
4359 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4360 tvb, start, length, encoding, scope, retval, &length);
4361}
4362
4363proto_item *
4364proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4365 tvbuff_t *tvb,
4366 const int start, int length, const unsigned encoding,
4367 wmem_allocator_t *scope, char **retval)
4368{
4369 header_field_info *hfinfo;
4370 field_info *new_fi;
4371 nstime_t time_stamp;
4372 int flags;
4373
4374 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", 4374, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4374,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4374, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4375
4376 switch (hfinfo->type) {
4377 case FT_ABSOLUTE_TIME:
4378 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4379 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4380 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4381 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4382 }
4383 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4384 break;
4385 case FT_RELATIVE_TIME:
4386 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4387 *retval = rel_time_to_secs_str(scope, &time_stamp);
4388 break;
4389 default:
4390 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)
4391 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4392 }
4393
4394 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4395
4396 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", 4396
, __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", 4396, "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", 4396, "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", 4396, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4397
4398 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4399
4400 switch (hfinfo->type) {
4401
4402 case FT_ABSOLUTE_TIME:
4403 case FT_RELATIVE_TIME:
4404 proto_tree_set_time(new_fi, &time_stamp);
4405 break;
4406 default:
4407 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "assertion \"not reached\" failed")
;
4408 }
4409
4410 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4411
4412 return proto_tree_add_node(tree, new_fi);
4413}
4414
4415/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4416 and returns proto_item* */
4417proto_item *
4418ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4419 const unsigned encoding)
4420{
4421 field_info *new_fi;
4422 header_field_info *hfinfo;
4423 int item_length;
4424 unsigned offset;
4425
4426 offset = ptvc->offset;
4427 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", 4427, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4427,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4427, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4428 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4429 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4430
4431 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4432
4433 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4434
4435 /* Coast clear. Try and fake it */
4436 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", 4436
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4436, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4436, "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", 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); ((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); } } }
;
4437
4438 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4439
4440 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4441 offset, length, encoding);
4442}
4443
4444/* Add an item to a proto_tree, using the text label registered to that item;
4445 the item is extracted from the tvbuff handed to it. */
4446proto_item *
4447proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4448 const int start, int length, const unsigned encoding)
4449{
4450 field_info *new_fi;
4451 int item_length;
4452
4453 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", 4453,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4454
4455 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4456 test_length(hfinfo, tvb, start, item_length, encoding);
4457
4458 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4459
4460 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", 4460
, __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", 4460, "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", 4460, "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", 4460, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4461
4462 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4463
4464 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4465}
4466
4467proto_item *
4468proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4469 const int start, int length, const unsigned encoding)
4470{
4471 register header_field_info *hfinfo;
4472
4473 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", 4473, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4473,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4473, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4474 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4475}
4476
4477/* Add an item to a proto_tree, using the text label registered to that item;
4478 the item is extracted from the tvbuff handed to it.
4479
4480 Return the length of the item through the pointer. */
4481proto_item *
4482proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4483 tvbuff_t *tvb, const int start,
4484 int length, const unsigned encoding,
4485 int *lenretval)
4486{
4487 field_info *new_fi;
4488 int item_length;
4489 proto_item *item;
4490
4491 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", 4491,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4492
4493 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4494 test_length(hfinfo, tvb, start, item_length, encoding);
4495
4496 if (!tree) {
4497 /*
4498 * We need to get the correct item length here.
4499 * That's normally done by proto_tree_new_item(),
4500 * but we won't be calling it.
4501 */
4502 *lenretval = get_full_length(hfinfo, tvb, start, length,
4503 item_length, encoding);
4504 return NULL((void*)0);
4505 }
4506
4507 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", 4514
, __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", 4514, "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", 4514, "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", 4514
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4508 /*((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", 4514
, __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", 4514, "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", 4514, "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", 4514
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4509 * 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", 4514
, __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", 4514, "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", 4514, "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", 4514
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4510 * 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", 4514
, __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", 4514, "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", 4514, "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", 4514
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4511 */((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", 4514
, __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", 4514, "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", 4514, "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", 4514
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4512 *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", 4514
, __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", 4514, "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", 4514, "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", 4514
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4513 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", 4514
, __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", 4514, "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", 4514, "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", 4514
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4514 })((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", 4514
, __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", 4514, "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", 4514, "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", 4514
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4515
4516 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4517
4518 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4519 *lenretval = new_fi->length;
4520 return item;
4521}
4522
4523proto_item *
4524proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4525 const int start, int length,
4526 const unsigned encoding, int *lenretval)
4527{
4528 register header_field_info *hfinfo;
4529
4530 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", 4530, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4530,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4530, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4531 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4532}
4533
4534/* which FT_ types can use proto_tree_add_bytes_item() */
4535static inline bool_Bool
4536validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4537{
4538 return (type == FT_BYTES ||
4539 type == FT_UINT_BYTES ||
4540 type == FT_OID ||
4541 type == FT_REL_OID ||
4542 type == FT_SYSTEM_ID );
4543}
4544
4545/* Note: this does no validation that the byte array of an FT_OID or
4546 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4547 so I think it's ok to continue not validating it?
4548 */
4549proto_item *
4550proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4551 const unsigned start, unsigned length,
4552 const unsigned encoding,
4553 GByteArray *retval, unsigned *endoff, int *err)
4554{
4555 field_info *new_fi;
4556 GByteArray *bytes = retval;
4557 GByteArray *created_bytes = NULL((void*)0);
4558 bool_Bool failed = false0;
4559 uint32_t n = 0;
4560 header_field_info *hfinfo;
4561 bool_Bool generate = (bytes || tree) ? true1 : false0;
4562
4563 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", 4563, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4563,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4563, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4564
4565 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", 4565,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4566
4567 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", 4568, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4568 "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", 4568, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4569
4570 if (length == 0) {
4571 return NULL((void*)0);
4572 }
4573
4574 if (encoding & ENC_STR_NUM0x01000000) {
4575 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"
)
;
4576 }
4577
4578 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4579 if (hfinfo->type == FT_UINT_BYTES) {
4580 /* can't decode FT_UINT_BYTES from strings */
4581 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")
4582 "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")
;
4583 }
4584
4585 unsigned hex_encoding = encoding;
4586 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4587 /* If none of the separator values are used,
4588 * assume no separator (the common case). */
4589 hex_encoding |= ENC_SEP_NONE0x00010000;
4590#if 0
4591 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")
4592 "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")
;
4593#endif
4594 }
4595
4596 if (!bytes) {
4597 /* caller doesn't care about return value, but we need it to
4598 call tvb_get_string_bytes() and set the tree later */
4599 bytes = created_bytes = g_byte_array_new();
4600 }
4601
4602 /*
4603 * bytes might be NULL after this, but can't add expert
4604 * error until later; if it's NULL, just note that
4605 * it failed.
4606 */
4607 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4608 if (bytes == NULL((void*)0))
4609 failed = true1;
4610 }
4611 else if (generate) {
4612 tvb_ensure_bytes_exist(tvb, start, length);
4613
4614 if (hfinfo->type == FT_UINT_BYTES) {
4615 n = length; /* n is now the "header" length */
4616 length = get_uint_value(tree, tvb, start, n, encoding);
4617 /* length is now the value's length; only store the value in the array */
4618 tvb_ensure_bytes_exist(tvb, start + n, length);
4619 if (!bytes) {
4620 /* caller doesn't care about return value, but
4621 * we may need it to set the tree later */
4622 bytes = created_bytes = g_byte_array_new();
4623 }
4624 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4625 }
4626 else if (length > 0) {
4627 if (!bytes) {
4628 /* caller doesn't care about return value, but
4629 * we may need it to set the tree later */
4630 bytes = created_bytes = g_byte_array_new();
4631 }
4632 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4633 }
4634
4635 if (endoff)
4636 *endoff = start + n + length;
4637 }
4638
4639 if (err)
4640 *err = failed ? EINVAL22 : 0;
4641
4642 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); }
4643 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4644 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); }
4645 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); }
4646 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); }
4647 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4648 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4649
4650 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", 4656
, __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", 4656, "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", 4656, "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", 4656
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4651 {((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4656
, __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", 4656, "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", 4656, "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", 4656
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4652 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", 4656
, __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", 4656, "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", 4656, "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", 4656
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4653 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", 4656
, __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", 4656, "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", 4656, "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", 4656
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4654 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", 4656
, __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", 4656, "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", 4656, "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", 4656
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4655 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", 4656
, __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", 4656, "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", 4656, "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", 4656
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4656 } )((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", 4656
, __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", 4656, "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", 4656, "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", 4656
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4657
4658 /* n will be zero except when it's a FT_UINT_BYTES */
4659 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4660
4661 if (encoding & ENC_STRING0x07000000) {
4662 if (failed)
4663 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4664
4665 if (bytes)
4666 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4667 else
4668 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4669
4670 if (created_bytes)
4671 g_byte_array_free(created_bytes, true1);
4672 }
4673 else {
4674 /* n will be zero except when it's a FT_UINT_BYTES */
4675 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4676
4677 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4678 * use the byte array created above in this case.
4679 */
4680 if (created_bytes)
4681 g_byte_array_free(created_bytes, true1);
4682
4683 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4684 (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)
;
4685 }
4686
4687 return proto_tree_add_node(tree, new_fi);
4688}
4689
4690
4691proto_item *
4692proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4693 const unsigned start, const unsigned length,
4694 const unsigned encoding,
4695 nstime_t *retval, unsigned *endoff, int *err)
4696{
4697 field_info *new_fi;
4698 nstime_t time_stamp;
4699 int saved_err = 0;
4700 header_field_info *hfinfo;
4701
4702 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", 4702, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4702,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4702, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4703
4704 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", 4704,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4705
4706 if (length == 0) {
4707 if(retval) {
4708 nstime_set_zero(retval);
4709 }
4710 return NULL((void*)0);
4711 }
4712
4713 nstime_set_zero(&time_stamp);
4714
4715 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4716 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", 4716, ((hfinfo))->abbrev))))
;
4717 /* The only string format that could be a relative time is
4718 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4719 * relative to "now" currently.
4720 */
4721 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4722 saved_err = EINVAL22;
4723 }
4724 else {
4725 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", 4725, ((hfinfo))->abbrev))))
;
4726 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4727
4728 tvb_ensure_bytes_exist(tvb, start, length);
4729 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4730 if (endoff) *endoff = start + length;
4731 }
4732
4733 if (err) *err = saved_err;
4734
4735 if (retval) {
4736 retval->secs = time_stamp.secs;
4737 retval->nsecs = time_stamp.nsecs;
4738 }
4739
4740 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4741
4742 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", 4742
, __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", 4742, "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", 4742, "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", 4742, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4743
4744 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4745
4746 proto_tree_set_time(new_fi, &time_stamp);
4747
4748 if (encoding & ENC_STRING0x07000000) {
4749 if (saved_err)
4750 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4751 }
4752 else {
4753 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4754 (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)
;
4755 }
4756
4757 return proto_tree_add_node(tree, new_fi);
4758}
4759
4760/* Add a FT_NONE to a proto_tree */
4761proto_item *
4762proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4763 const int start, int length, const char *format,
4764 ...)
4765{
4766 proto_item *pi;
4767 va_list ap;
4768 header_field_info *hfinfo;
4769
4770 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4771
4772 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", 4772
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4772, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4772, "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", 4772, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4773
4774 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", 4774
, ((hfinfo))->abbrev))))
;
4775
4776 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4777
4778 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4778, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4779
4780 va_start(ap, format)__builtin_va_start(ap, format);
4781 proto_tree_set_representation(pi, format, ap);
4782 va_end(ap)__builtin_va_end(ap);
4783
4784 /* no value to set for FT_NONE */
4785 return pi;
4786}
4787
4788/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4789 * offset, and returns proto_item* */
4790proto_item *
4791ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4792 const unsigned encoding)
4793{
4794 proto_item *item;
4795
4796 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4797 length, encoding);
4798
4799 return item;
4800}
4801
4802/* Advance the ptvcursor's offset within its tvbuff without
4803 * adding anything to the proto_tree. */
4804void
4805ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4806{
4807 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4808 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4809 }
4810}
4811
4812
4813static void
4814proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4815{
4816 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4816, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4817 /* proto_tree_set_bytes_tvb calls tvb_ensure_bytes_exist(tvb, offset, length);
4818 * Does it cause problems if fvalue_set_protocol is called with a length
4819 * greater than what's in the TVB? */
4820 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4821}
4822
4823/* Add a FT_PROTOCOL to a proto_tree */
4824proto_item *
4825proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4826 int start, int length, const char *format, ...)
4827{
4828 proto_item *pi;
4829 tvbuff_t *protocol_tvb;
4830 va_list ap;
4831 header_field_info *hfinfo;
4832 char* protocol_rep;
4833
4834 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4835
4836 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", 4836
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4836, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4836, "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", 4836, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4837
4838 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"
, 4838, ((hfinfo))->abbrev))))
;
4839
4840 /*
4841 * This can throw an exception, so do it before we allocate anything.
4842 */
4843 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4844
4845 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4846
4847 va_start(ap, format)__builtin_va_start(ap, format);
4848 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4849 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4850 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)
;
4851 va_end(ap)__builtin_va_end(ap);
4852
4853 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4853, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4854
4855 va_start(ap, format)__builtin_va_start(ap, format);
4856 proto_tree_set_representation(pi, format, ap);
4857 va_end(ap)__builtin_va_end(ap);
4858
4859 return pi;
4860}
4861
4862/* Add a FT_BYTES to a proto_tree */
4863proto_item *
4864proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4865 int length, const uint8_t *start_ptr)
4866{
4867 proto_item *pi;
4868 header_field_info *hfinfo;
4869 int item_length;
4870
4871 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", 4871, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4871,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4871, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4872 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4873 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4874
4875 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4876
4877 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", 4877
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4877, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4877, "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", 4877, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4878
4879 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",
4879, ((hfinfo))->abbrev))))
;
4880
4881 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4882 start_ptr = tvb_get_ptr(tvb, start, length);
4883
4884 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4885 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4886
4887 return pi;
4888}
4889
4890/* Add a FT_BYTES to a proto_tree */
4891proto_item *
4892proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4893 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4894{
4895 proto_item *pi;
4896 header_field_info *hfinfo;
4897 int item_length;
4898
4899 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", 4899, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4899,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4899, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4900 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4901 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4902
4903 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4904
4905 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", 4905
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4905, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4905, "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", 4905, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4906
4907 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",
4907, ((hfinfo))->abbrev))))
;
4908
4909 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4910 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4911
4912 return pi;
4913}
4914
4915proto_item *
4916proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4917 int start, int length,
4918 const uint8_t *start_ptr,
4919 const char *format, ...)
4920{
4921 proto_item *pi;
4922 va_list ap;
4923
4924 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4925
4926 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; }
;
4927
4928 va_start(ap, format)__builtin_va_start(ap, format);
4929 proto_tree_set_representation_value(pi, format, ap);
4930 va_end(ap)__builtin_va_end(ap);
4931
4932 return pi;
4933}
4934
4935proto_item *
4936proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4937 int start, int length, const uint8_t *start_ptr,
4938 const char *format, ...)
4939{
4940 proto_item *pi;
4941 va_list ap;
4942
4943 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4944
4945 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; }
;
4946
4947 va_start(ap, format)__builtin_va_start(ap, format);
4948 proto_tree_set_representation(pi, format, ap);
4949 va_end(ap)__builtin_va_end(ap);
4950
4951 return pi;
4952}
4953
4954static void
4955proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4956{
4957 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4957, "length >= 0"
))))
;
4958 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", 4958, "start_ptr != ((void*)0) || length == 0"
))))
;
4959
4960 fvalue_set_bytes_data(fi->value, start_ptr, length);
4961}
4962
4963
4964static void
4965proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4966{
4967 tvb_ensure_bytes_exist(tvb, offset, length);
4968 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4969}
4970
4971static void
4972proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4973{
4974 GByteArray *bytes;
4975
4976 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4976, "value != ((void*)0)"
))))
;
4977
4978 bytes = byte_array_dup(value);
4979
4980 fvalue_set_byte_array(fi->value, bytes);
4981}
4982
4983/* Add a FT_*TIME to a proto_tree */
4984proto_item *
4985proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4986 int length, const nstime_t *value_ptr)
4987{
4988 proto_item *pi;
4989 header_field_info *hfinfo;
4990
4991 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4992
4993 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", 4993
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4993, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4993, "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", 4993, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4994
4995 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", 4995, ((hfinfo))->abbrev))))
;
4996
4997 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4998 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4999
5000 return pi;
5001}
5002
5003proto_item *
5004proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5005 int start, int length, nstime_t *value_ptr,
5006 const char *format, ...)
5007{
5008 proto_item *pi;
5009 va_list ap;
5010
5011 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5012 if (pi != tree) {
5013 va_start(ap, format)__builtin_va_start(ap, format);
5014 proto_tree_set_representation_value(pi, format, ap);
5015 va_end(ap)__builtin_va_end(ap);
5016 }
5017
5018 return pi;
5019}
5020
5021proto_item *
5022proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5023 int start, int length, nstime_t *value_ptr,
5024 const char *format, ...)
5025{
5026 proto_item *pi;
5027 va_list ap;
5028
5029 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5030 if (pi != tree) {
5031 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5031, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5032
5033 va_start(ap, format)__builtin_va_start(ap, format);
5034 proto_tree_set_representation(pi, format, ap);
5035 va_end(ap)__builtin_va_end(ap);
5036 }
5037
5038 return pi;
5039}
5040
5041/* Set the FT_*TIME value */
5042static void
5043proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5044{
5045 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5045, "value_ptr != ((void*)0)"
))))
;
5046
5047 fvalue_set_time(fi->value, value_ptr);
5048}
5049
5050/* Add a FT_IPXNET to a proto_tree */
5051proto_item *
5052proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5053 int length, uint32_t value)
5054{
5055 proto_item *pi;
5056 header_field_info *hfinfo;
5057
5058 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5059
5060 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", 5060
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5060, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5060, "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", 5060, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5061
5062 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"
, 5062, ((hfinfo))->abbrev))))
;
5063
5064 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5065 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5066
5067 return pi;
5068}
5069
5070proto_item *
5071proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5072 int start, int length, uint32_t value,
5073 const char *format, ...)
5074{
5075 proto_item *pi;
5076 va_list ap;
5077
5078 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5079 if (pi != tree) {
5080 va_start(ap, format)__builtin_va_start(ap, format);
5081 proto_tree_set_representation_value(pi, format, ap);
5082 va_end(ap)__builtin_va_end(ap);
5083 }
5084
5085 return pi;
5086}
5087
5088proto_item *
5089proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5090 int start, int length, uint32_t value,
5091 const char *format, ...)
5092{
5093 proto_item *pi;
5094 va_list ap;
5095
5096 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5097 if (pi != tree) {
5098 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5098, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5099
5100 va_start(ap, format)__builtin_va_start(ap, format);
5101 proto_tree_set_representation(pi, format, ap);
5102 va_end(ap)__builtin_va_end(ap);
5103 }
5104
5105 return pi;
5106}
5107
5108/* Set the FT_IPXNET value */
5109static void
5110proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5111{
5112 fvalue_set_uinteger(fi->value, value);
5113}
5114
5115/* Add a FT_IPv4 to a proto_tree */
5116proto_item *
5117proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5118 int length, ws_in4_addr value)
5119{
5120 proto_item *pi;
5121 header_field_info *hfinfo;
5122
5123 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5124
5125 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", 5125
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5125, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5125, "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", 5125, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5126
5127 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", 5127
, ((hfinfo))->abbrev))))
;
5128
5129 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5130 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5131
5132 return pi;
5133}
5134
5135proto_item *
5136proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5137 int start, int length, ws_in4_addr value,
5138 const char *format, ...)
5139{
5140 proto_item *pi;
5141 va_list ap;
5142
5143 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5144 if (pi != tree) {
5145 va_start(ap, format)__builtin_va_start(ap, format);
5146 proto_tree_set_representation_value(pi, format, ap);
5147 va_end(ap)__builtin_va_end(ap);
5148 }
5149
5150 return pi;
5151}
5152
5153proto_item *
5154proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5155 int start, int length, ws_in4_addr value,
5156 const char *format, ...)
5157{
5158 proto_item *pi;
5159 va_list ap;
5160
5161 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5162 if (pi != tree) {
5163 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5163, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5164
5165 va_start(ap, format)__builtin_va_start(ap, format);
5166 proto_tree_set_representation(pi, format, ap);
5167 va_end(ap)__builtin_va_end(ap);
5168 }
5169
5170 return pi;
5171}
5172
5173/* Set the FT_IPv4 value */
5174static void
5175proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5176{
5177 ipv4_addr_and_mask ipv4;
5178 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5179 fvalue_set_ipv4(fi->value, &ipv4);
5180}
5181
5182/* Add a FT_IPv6 to a proto_tree */
5183proto_item *
5184proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5185 int length, const ws_in6_addr *value)
5186{
5187 proto_item *pi;
5188 header_field_info *hfinfo;
5189
5190 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5191
5192 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", 5192
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5192, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5192, "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", 5192, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5193
5194 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", 5194
, ((hfinfo))->abbrev))))
;
5195
5196 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5197 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5198
5199 return pi;
5200}
5201
5202proto_item *
5203proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5204 int start, int length,
5205 const ws_in6_addr *value_ptr,
5206 const char *format, ...)
5207{
5208 proto_item *pi;
5209 va_list ap;
5210
5211 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5212 if (pi != tree) {
5213 va_start(ap, format)__builtin_va_start(ap, format);
5214 proto_tree_set_representation_value(pi, format, ap);
5215 va_end(ap)__builtin_va_end(ap);
5216 }
5217
5218 return pi;
5219}
5220
5221proto_item *
5222proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5223 int start, int length,
5224 const ws_in6_addr *value_ptr,
5225 const char *format, ...)
5226{
5227 proto_item *pi;
5228 va_list ap;
5229
5230 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5231 if (pi != tree) {
5232 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5232, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5233
5234 va_start(ap, format)__builtin_va_start(ap, format);
5235 proto_tree_set_representation(pi, format, ap);
5236 va_end(ap)__builtin_va_end(ap);
5237 }
5238
5239 return pi;
5240}
5241
5242/* Set the FT_IPv6 value */
5243static void
5244proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5245{
5246 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5246, "value != ((void*)0)"
))))
;
5247 ipv6_addr_and_prefix ipv6;
5248 ipv6.addr = *value;
5249 ipv6.prefix = 128;
5250 fvalue_set_ipv6(fi->value, &ipv6);
5251}
5252
5253static void
5254proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5255{
5256 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5257}
5258
5259/* Set the FT_FCWWN value */
5260static void
5261proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5262{
5263 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5263, "value_ptr != ((void*)0)"
))))
;
5264 fvalue_set_fcwwn(fi->value, value_ptr);
5265}
5266
5267static void
5268proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5269{
5270 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5271}
5272
5273/* Add a FT_GUID to a proto_tree */
5274proto_item *
5275proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5276 int length, const e_guid_t *value_ptr)
5277{
5278 proto_item *pi;
5279 header_field_info *hfinfo;
5280
5281 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5282
5283 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", 5283
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5283, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5283, "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", 5283, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5284
5285 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", 5285
, ((hfinfo))->abbrev))))
;
5286
5287 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5288 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5289
5290 return pi;
5291}
5292
5293proto_item *
5294proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5295 int start, int length,
5296 const e_guid_t *value_ptr,
5297 const char *format, ...)
5298{
5299 proto_item *pi;
5300 va_list ap;
5301
5302 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5303 if (pi != tree) {
5304 va_start(ap, format)__builtin_va_start(ap, format);
5305 proto_tree_set_representation_value(pi, format, ap);
5306 va_end(ap)__builtin_va_end(ap);
5307 }
5308
5309 return pi;
5310}
5311
5312proto_item *
5313proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5314 int start, int length, const e_guid_t *value_ptr,
5315 const char *format, ...)
5316{
5317 proto_item *pi;
5318 va_list ap;
5319
5320 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5321 if (pi != tree) {
5322 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5322, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5323
5324 va_start(ap, format)__builtin_va_start(ap, format);
5325 proto_tree_set_representation(pi, format, ap);
5326 va_end(ap)__builtin_va_end(ap);
5327 }
5328
5329 return pi;
5330}
5331
5332/* Set the FT_GUID value */
5333static void
5334proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5335{
5336 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5336, "value_ptr != ((void*)0)"
))))
;
5337 fvalue_set_guid(fi->value, value_ptr);
5338}
5339
5340static void
5341proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5342 const unsigned encoding)
5343{
5344 e_guid_t guid;
5345
5346 tvb_get_guid(tvb, start, &guid, encoding);
5347 proto_tree_set_guid(fi, &guid);
5348}
5349
5350/* Add a FT_OID to a proto_tree */
5351proto_item *
5352proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5353 int length, const uint8_t* value_ptr)
5354{
5355 proto_item *pi;
5356 header_field_info *hfinfo;
5357
5358 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5359
5360 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", 5360
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5360, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5360, "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", 5360, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5361
5362 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", 5362
, ((hfinfo))->abbrev))))
;
5363
5364 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5365 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5366
5367 return pi;
5368}
5369
5370proto_item *
5371proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5372 int start, int length,
5373 const uint8_t* value_ptr,
5374 const char *format, ...)
5375{
5376 proto_item *pi;
5377 va_list ap;
5378
5379 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5380 if (pi != tree) {
5381 va_start(ap, format)__builtin_va_start(ap, format);
5382 proto_tree_set_representation_value(pi, format, ap);
5383 va_end(ap)__builtin_va_end(ap);
5384 }
5385
5386 return pi;
5387}
5388
5389proto_item *
5390proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5391 int start, int length, const uint8_t* value_ptr,
5392 const char *format, ...)
5393{
5394 proto_item *pi;
5395 va_list ap;
5396
5397 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5398 if (pi != tree) {
5399 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5399, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5400
5401 va_start(ap, format)__builtin_va_start(ap, format);
5402 proto_tree_set_representation(pi, format, ap);
5403 va_end(ap)__builtin_va_end(ap);
5404 }
5405
5406 return pi;
5407}
5408
5409/* Set the FT_OID value */
5410static void
5411proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5412{
5413 GByteArray *bytes;
5414
5415 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", 5415, "value_ptr != ((void*)0) || length == 0"
))))
;
5416
5417 bytes = g_byte_array_new();
5418 if (length > 0) {
5419 g_byte_array_append(bytes, value_ptr, length);
5420 }
5421 fvalue_set_byte_array(fi->value, bytes);
5422}
5423
5424static void
5425proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5426{
5427 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5428}
5429
5430/* Set the FT_SYSTEM_ID value */
5431static void
5432proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5433{
5434 GByteArray *bytes;
5435
5436 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", 5436, "value_ptr != ((void*)0) || length == 0"
))))
;
5437
5438 bytes = g_byte_array_new();
5439 if (length > 0) {
5440 g_byte_array_append(bytes, value_ptr, length);
5441 }
5442 fvalue_set_byte_array(fi->value, bytes);
5443}
5444
5445static void
5446proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5447{
5448 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5449}
5450
5451/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5452 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5453 * is destroyed. */
5454proto_item *
5455proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5456 int length, const char* value)
5457{
5458 proto_item *pi;
5459 header_field_info *hfinfo;
5460 int item_length;
5461
5462 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", 5462, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5462,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5462, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5463 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5464 /*
5465 * Special case - if the length is 0, skip the test, so that
5466 * we can have an empty string right after the end of the
5467 * packet. (This handles URL-encoded forms where the last field
5468 * has no value so the form ends right after the =.)
5469 *
5470 * XXX - length zero makes sense for FT_STRING, and more or less
5471 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5472 * for FT_STRINGZ (except that a number of fields that should be
5473 * one of the others are actually registered as FT_STRINGZ.)
5474 */
5475 if (item_length != 0)
5476 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5477
5478 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5479
5480 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", 5480
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5480, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5480, "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", 5480, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5481
5482 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", 5482, ((hfinfo))->abbrev))))
;
5483
5484 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5485 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5485, "length >= 0"
))))
;
5486
5487 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", 5487, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5488 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5489
5490 return pi;
5491}
5492
5493proto_item *
5494proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5495 int start, int length, const char* value,
5496 const char *format,
5497 ...)
5498{
5499 proto_item *pi;
5500 va_list ap;
5501
5502 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5503 if (pi != tree) {
5504 va_start(ap, format)__builtin_va_start(ap, format);
5505 proto_tree_set_representation_value(pi, format, ap);
5506 va_end(ap)__builtin_va_end(ap);
5507 }
5508
5509 return pi;
5510}
5511
5512proto_item *
5513proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5514 int start, int length, const char* value,
5515 const char *format, ...)
5516{
5517 proto_item *pi;
5518 va_list ap;
5519
5520 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5521 if (pi != tree) {
5522 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5522, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5523
5524 va_start(ap, format)__builtin_va_start(ap, format);
5525 proto_tree_set_representation(pi, format, ap);
5526 va_end(ap)__builtin_va_end(ap);
5527 }
5528
5529 return pi;
5530}
5531
5532/* Set the FT_STRING value */
5533static void
5534proto_tree_set_string(field_info *fi, const char* value)
5535{
5536 if (value) {
5537 fvalue_set_string(fi->value, value);
5538 } else {
5539 /*
5540 * XXX - why is a null value for a string field
5541 * considered valid?
5542 */
5543 fvalue_set_string(fi->value, "[ Null ]");
5544 }
5545}
5546
5547/* Set the FT_AX25 value */
5548static void
5549proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5550{
5551 fvalue_set_ax25(fi->value, value);
5552}
5553
5554static void
5555proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5556{
5557 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5558}
5559
5560/* Set the FT_VINES value */
5561static void
5562proto_tree_set_vines(field_info *fi, const uint8_t* value)
5563{
5564 fvalue_set_vines(fi->value, value);
5565}
5566
5567static void
5568proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5569{
5570 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5571}
5572
5573/* Add a FT_ETHER to a proto_tree */
5574proto_item *
5575proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5576 int length, const uint8_t* value)
5577{
5578 proto_item *pi;
5579 header_field_info *hfinfo;
5580
5581 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5582
5583 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", 5583
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5583, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5583, "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", 5583, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5584
5585 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",
5585, ((hfinfo))->abbrev))))
;
5586
5587 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5588 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5589
5590 return pi;
5591}
5592
5593proto_item *
5594proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5595 int start, int length, const uint8_t* value,
5596 const char *format, ...)
5597{
5598 proto_item *pi;
5599 va_list ap;
5600
5601 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5602 if (pi != tree) {
5603 va_start(ap, format)__builtin_va_start(ap, format);
5604 proto_tree_set_representation_value(pi, format, ap);
5605 va_end(ap)__builtin_va_end(ap);
5606 }
5607
5608 return pi;
5609}
5610
5611proto_item *
5612proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5613 int start, int length, const uint8_t* value,
5614 const char *format, ...)
5615{
5616 proto_item *pi;
5617 va_list ap;
5618
5619 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5620 if (pi != tree) {
5621 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5621, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5622
5623 va_start(ap, format)__builtin_va_start(ap, format);
5624 proto_tree_set_representation(pi, format, ap);
5625 va_end(ap)__builtin_va_end(ap);
5626 }
5627
5628 return pi;
5629}
5630
5631/* Set the FT_ETHER value */
5632static void
5633proto_tree_set_ether(field_info *fi, const uint8_t* value)
5634{
5635 fvalue_set_ether(fi->value, value);
5636}
5637
5638static void
5639proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5640{
5641 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5642}
5643
5644/* Add a FT_BOOLEAN to a proto_tree */
5645proto_item *
5646proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5647 int length, uint64_t value)
5648{
5649 proto_item *pi;
5650 header_field_info *hfinfo;
5651
5652 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5653
5654 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", 5654
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5654, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5654, "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", 5654, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5655
5656 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"
, 5656, ((hfinfo))->abbrev))))
;
5657
5658 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5659 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5660
5661 return pi;
5662}
5663
5664proto_item *
5665proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5666 tvbuff_t *tvb, int start, int length,
5667 uint64_t value, const char *format, ...)
5668{
5669 proto_item *pi;
5670 va_list ap;
5671
5672 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5673 if (pi != tree) {
5674 va_start(ap, format)__builtin_va_start(ap, format);
5675 proto_tree_set_representation_value(pi, format, ap);
5676 va_end(ap)__builtin_va_end(ap);
5677 }
5678
5679 return pi;
5680}
5681
5682proto_item *
5683proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5684 int start, int length, uint64_t value,
5685 const char *format, ...)
5686{
5687 proto_item *pi;
5688 va_list ap;
5689
5690 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5691 if (pi != tree) {
5692 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5692, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5693
5694 va_start(ap, format)__builtin_va_start(ap, format);
5695 proto_tree_set_representation(pi, format, ap);
5696 va_end(ap)__builtin_va_end(ap);
5697 }
5698
5699 return pi;
5700}
5701
5702/* Set the FT_BOOLEAN value */
5703static void
5704proto_tree_set_boolean(field_info *fi, uint64_t value)
5705{
5706 proto_tree_set_uint64(fi, value);
5707}
5708
5709/* Generate, into "buf", a string showing the bits of a bitfield.
5710 Return a pointer to the character after that string. */
5711static char *
5712other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5713{
5714 int i = 0;
5715 uint64_t bit;
5716 char *p;
5717
5718 p = buf;
5719
5720 /* This is a devel error. It is safer to stop here. */
5721 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5721, "width >= 1"
))))
;
5722
5723 bit = UINT64_C(1)1UL << (width - 1);
5724 for (;;) {
5725 if (mask & bit) {
5726 /* This bit is part of the field. Show its value. */
5727 if (val & bit)
5728 *p++ = '1';
5729 else
5730 *p++ = '0';
5731 } else {
5732 /* This bit is not part of the field. */
5733 *p++ = '.';
5734 }
5735 bit >>= 1;
5736 i++;
5737 if (i >= width)
5738 break;
5739 if (i % 4 == 0)
5740 *p++ = ' ';
5741 }
5742 *p = '\0';
5743 return p;
5744}
5745
5746static char *
5747decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5748{
5749 char *p;
5750
5751 p = other_decode_bitfield_value(buf, val, mask, width);
5752 p = g_stpcpy(p, " = ");
5753
5754 return p;
5755}
5756
5757static char *
5758other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5759{
5760 int i = 0;
5761 uint64_t bit;
5762 char *p;
5763
5764 p = buf;
5765
5766 /* This is a devel error. It is safer to stop here. */
5767 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5767, "width >= 1"
))))
;
5768
5769 bit = UINT64_C(1)1UL << (width - 1);
5770 for (;;) {
5771 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5772 (mask & bit)) {
5773 /* This bit is part of the field. Show its value. */
5774 if (val & bit)
5775 *p++ = '1';
5776 else
5777 *p++ = '0';
5778 } else {
5779 /* This bit is not part of the field. */
5780 *p++ = '.';
5781 }
5782 bit >>= 1;
5783 i++;
5784 if (i >= width)
5785 break;
5786 if (i % 4 == 0)
5787 *p++ = ' ';
5788 }
5789
5790 *p = '\0';
5791 return p;
5792}
5793
5794static char *
5795decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5796{
5797 char *p;
5798
5799 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5800 p = g_stpcpy(p, " = ");
5801
5802 return p;
5803}
5804
5805/* Add a FT_FLOAT to a proto_tree */
5806proto_item *
5807proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5808 int length, float value)
5809{
5810 proto_item *pi;
5811 header_field_info *hfinfo;
5812
5813 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5814
5815 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", 5815
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5815, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5815, "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", 5815, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5816
5817 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",
5817, ((hfinfo))->abbrev))))
;
5818
5819 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5820 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5821
5822 return pi;
5823}
5824
5825proto_item *
5826proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5827 int start, int length, float value,
5828 const char *format, ...)
5829{
5830 proto_item *pi;
5831 va_list ap;
5832
5833 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5834 if (pi != tree) {
5835 va_start(ap, format)__builtin_va_start(ap, format);
5836 proto_tree_set_representation_value(pi, format, ap);
5837 va_end(ap)__builtin_va_end(ap);
5838 }
5839
5840 return pi;
5841}
5842
5843proto_item *
5844proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5845 int start, int length, float value,
5846 const char *format, ...)
5847{
5848 proto_item *pi;
5849 va_list ap;
5850
5851 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5852 if (pi != tree) {
5853 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5853, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5854
5855 va_start(ap, format)__builtin_va_start(ap, format);
5856 proto_tree_set_representation(pi, format, ap);
5857 va_end(ap)__builtin_va_end(ap);
5858 }
5859
5860 return pi;
5861}
5862
5863/* Set the FT_FLOAT value */
5864static void
5865proto_tree_set_float(field_info *fi, float value)
5866{
5867 fvalue_set_floating(fi->value, value);
5868}
5869
5870/* Add a FT_DOUBLE to a proto_tree */
5871proto_item *
5872proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5873 int length, double value)
5874{
5875 proto_item *pi;
5876 header_field_info *hfinfo;
5877
5878 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5879
5880 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", 5880
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5880, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5880, "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", 5880, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5881
5882 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"
, 5882, ((hfinfo))->abbrev))))
;
5883
5884 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5885 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5886
5887 return pi;
5888}
5889
5890proto_item *
5891proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5892 int start, int length, double value,
5893 const char *format, ...)
5894{
5895 proto_item *pi;
5896 va_list ap;
5897
5898 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5899 if (pi != tree) {
5900 va_start(ap, format)__builtin_va_start(ap, format);
5901 proto_tree_set_representation_value(pi, format, ap);
5902 va_end(ap)__builtin_va_end(ap);
5903 }
5904
5905 return pi;
5906}
5907
5908proto_item *
5909proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5910 int start, int length, double value,
5911 const char *format, ...)
5912{
5913 proto_item *pi;
5914 va_list ap;
5915
5916 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5917 if (pi != tree) {
5918 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5918, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5919
5920 va_start(ap, format)__builtin_va_start(ap, format);
5921 proto_tree_set_representation(pi, format, ap);
5922 va_end(ap)__builtin_va_end(ap);
5923 }
5924
5925 return pi;
5926}
5927
5928/* Set the FT_DOUBLE value */
5929static void
5930proto_tree_set_double(field_info *fi, double value)
5931{
5932 fvalue_set_floating(fi->value, value);
5933}
5934
5935/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5936proto_item *
5937proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5938 int length, uint32_t value)
5939{
5940 proto_item *pi = NULL((void*)0);
5941 header_field_info *hfinfo;
5942
5943 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5944
5945 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", 5945
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5945, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5945, "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", 5945, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5946
5947 switch (hfinfo->type) {
5948 case FT_CHAR:
5949 case FT_UINT8:
5950 case FT_UINT16:
5951 case FT_UINT24:
5952 case FT_UINT32:
5953 case FT_FRAMENUM:
5954 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5955 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5956 break;
5957
5958 default:
5959 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)
5960 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)
;
5961 }
5962
5963 return pi;
5964}
5965
5966proto_item *
5967proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5968 int start, int length, uint32_t value,
5969 const char *format, ...)
5970{
5971 proto_item *pi;
5972 va_list ap;
5973
5974 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5975 if (pi != tree) {
5976 va_start(ap, format)__builtin_va_start(ap, format);
5977 proto_tree_set_representation_value(pi, format, ap);
5978 va_end(ap)__builtin_va_end(ap);
5979 }
5980
5981 return pi;
5982}
5983
5984proto_item *
5985proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5986 int start, int length, uint32_t value,
5987 const char *format, ...)
5988{
5989 proto_item *pi;
5990 va_list ap;
5991
5992 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5993 if (pi != tree) {
5994 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5994, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5995
5996 va_start(ap, format)__builtin_va_start(ap, format);
5997 proto_tree_set_representation(pi, format, ap);
5998 va_end(ap)__builtin_va_end(ap);
5999 }
6000
6001 return pi;
6002}
6003
6004/* Set the FT_UINT{8,16,24,32} value */
6005static void
6006proto_tree_set_uint(field_info *fi, uint32_t value)
6007{
6008 const header_field_info *hfinfo;
6009 uint32_t integer;
6010
6011 hfinfo = fi->hfinfo;
6012 integer = value;
6013
6014 if (hfinfo->bitmask) {
6015 /* Mask out irrelevant portions */
6016 integer &= (uint32_t)(hfinfo->bitmask);
6017
6018 /* Shift bits */
6019 integer >>= hfinfo_bitshift(hfinfo);
6020
6021 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6022 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)
;
6023 }
6024
6025 fvalue_set_uinteger(fi->value, integer);
6026}
6027
6028/* Add FT_UINT{40,48,56,64} to a proto_tree */
6029proto_item *
6030proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6031 int length, uint64_t value)
6032{
6033 proto_item *pi = NULL((void*)0);
6034 header_field_info *hfinfo;
6035
6036 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6037
6038 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", 6038
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6038, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6038, "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", 6038, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6039
6040 switch (hfinfo->type) {
6041 case FT_UINT40:
6042 case FT_UINT48:
6043 case FT_UINT56:
6044 case FT_UINT64:
6045 case FT_FRAMENUM:
6046 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6047 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6048 break;
6049
6050 default:
6051 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)
6052 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)
;
6053 }
6054
6055 return pi;
6056}
6057
6058proto_item *
6059proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6060 int start, int length, uint64_t value,
6061 const char *format, ...)
6062{
6063 proto_item *pi;
6064 va_list ap;
6065
6066 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6067 if (pi != tree) {
6068 va_start(ap, format)__builtin_va_start(ap, format);
6069 proto_tree_set_representation_value(pi, format, ap);
6070 va_end(ap)__builtin_va_end(ap);
6071 }
6072
6073 return pi;
6074}
6075
6076proto_item *
6077proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6078 int start, int length, uint64_t value,
6079 const char *format, ...)
6080{
6081 proto_item *pi;
6082 va_list ap;
6083
6084 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6085 if (pi != tree) {
6086 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6086, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6087
6088 va_start(ap, format)__builtin_va_start(ap, format);
6089 proto_tree_set_representation(pi, format, ap);
6090 va_end(ap)__builtin_va_end(ap);
6091 }
6092
6093 return pi;
6094}
6095
6096/* Set the FT_UINT{40,48,56,64} value */
6097static void
6098proto_tree_set_uint64(field_info *fi, uint64_t value)
6099{
6100 const header_field_info *hfinfo;
6101 uint64_t integer;
6102
6103 hfinfo = fi->hfinfo;
6104 integer = value;
6105
6106 if (hfinfo->bitmask) {
6107 /* Mask out irrelevant portions */
6108 integer &= hfinfo->bitmask;
6109
6110 /* Shift bits */
6111 integer >>= hfinfo_bitshift(hfinfo);
6112
6113 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6114 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)
;
6115 }
6116
6117 fvalue_set_uinteger64(fi->value, integer);
6118}
6119
6120/* Add FT_INT{8,16,24,32} to a proto_tree */
6121proto_item *
6122proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6123 int length, int32_t value)
6124{
6125 proto_item *pi = NULL((void*)0);
6126 header_field_info *hfinfo;
6127
6128 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6129
6130 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", 6130
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6130, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6130, "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", 6130, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6131
6132 switch (hfinfo->type) {
6133 case FT_INT8:
6134 case FT_INT16:
6135 case FT_INT24:
6136 case FT_INT32:
6137 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6138 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6139 break;
6140
6141 default:
6142 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)
6143 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6144 }
6145
6146 return pi;
6147}
6148
6149proto_item *
6150proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6151 int start, int length, int32_t value,
6152 const char *format, ...)
6153{
6154 proto_item *pi;
6155 va_list ap;
6156
6157 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6158 if (pi != tree) {
6159 va_start(ap, format)__builtin_va_start(ap, format);
6160 proto_tree_set_representation_value(pi, format, ap);
6161 va_end(ap)__builtin_va_end(ap);
6162 }
6163
6164 return pi;
6165}
6166
6167proto_item *
6168proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6169 int start, int length, int32_t value,
6170 const char *format, ...)
6171{
6172 proto_item *pi;
6173 va_list ap;
6174
6175 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6176 if (pi != tree) {
6177 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6177, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6178
6179 va_start(ap, format)__builtin_va_start(ap, format);
6180 proto_tree_set_representation(pi, format, ap);
6181 va_end(ap)__builtin_va_end(ap);
6182 }
6183
6184 return pi;
6185}
6186
6187/* Set the FT_INT{8,16,24,32} value */
6188static void
6189proto_tree_set_int(field_info *fi, int32_t value)
6190{
6191 const header_field_info *hfinfo;
6192 uint32_t integer;
6193 int no_of_bits;
6194
6195 hfinfo = fi->hfinfo;
6196 integer = (uint32_t) value;
6197
6198 if (hfinfo->bitmask) {
6199 /* Mask out irrelevant portions */
6200 integer &= (uint32_t)(hfinfo->bitmask);
6201
6202 /* Shift bits */
6203 integer >>= hfinfo_bitshift(hfinfo);
6204
6205 no_of_bits = ws_count_ones(hfinfo->bitmask);
6206 integer = ws_sign_ext32(integer, no_of_bits);
6207
6208 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6209 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)
;
6210 }
6211
6212 fvalue_set_sinteger(fi->value, integer);
6213}
6214
6215/* Add FT_INT{40,48,56,64} to a proto_tree */
6216proto_item *
6217proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6218 int length, int64_t value)
6219{
6220 proto_item *pi = NULL((void*)0);
6221 header_field_info *hfinfo;
6222
6223 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6224
6225 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", 6225
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6225, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6225, "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", 6225, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6226
6227 switch (hfinfo->type) {
6228 case FT_INT40:
6229 case FT_INT48:
6230 case FT_INT56:
6231 case FT_INT64:
6232 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6233 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6234 break;
6235
6236 default:
6237 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)
6238 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6239 }
6240
6241 return pi;
6242}
6243
6244proto_item *
6245proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6246 int start, int length, int64_t value,
6247 const char *format, ...)
6248{
6249 proto_item *pi;
6250 va_list ap;
6251
6252 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6253 if (pi != tree) {
6254 va_start(ap, format)__builtin_va_start(ap, format);
6255 proto_tree_set_representation_value(pi, format, ap);
6256 va_end(ap)__builtin_va_end(ap);
6257 }
6258
6259 return pi;
6260}
6261
6262/* Set the FT_INT{40,48,56,64} value */
6263static void
6264proto_tree_set_int64(field_info *fi, int64_t value)
6265{
6266 const header_field_info *hfinfo;
6267 uint64_t integer;
6268 int no_of_bits;
6269
6270 hfinfo = fi->hfinfo;
6271 integer = value;
6272
6273 if (hfinfo->bitmask) {
6274 /* Mask out irrelevant portions */
6275 integer &= hfinfo->bitmask;
6276
6277 /* Shift bits */
6278 integer >>= hfinfo_bitshift(hfinfo);
6279
6280 no_of_bits = ws_count_ones(hfinfo->bitmask);
6281 integer = ws_sign_ext64(integer, no_of_bits);
6282
6283 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6284 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)
;
6285 }
6286
6287 fvalue_set_sinteger64(fi->value, integer);
6288}
6289
6290proto_item *
6291proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6292 int start, int length, int64_t value,
6293 const char *format, ...)
6294{
6295 proto_item *pi;
6296 va_list ap;
6297
6298 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6299 if (pi != tree) {
6300 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6300, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6301
6302 va_start(ap, format)__builtin_va_start(ap, format);
6303 proto_tree_set_representation(pi, format, ap);
6304 va_end(ap)__builtin_va_end(ap);
6305 }
6306
6307 return pi;
6308}
6309
6310/* Add a FT_EUI64 to a proto_tree */
6311proto_item *
6312proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6313 int length, const uint64_t value)
6314{
6315 proto_item *pi;
6316 header_field_info *hfinfo;
6317
6318 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6319
6320 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", 6320
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6320, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6320, "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", 6320, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6321
6322 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",
6322, ((hfinfo))->abbrev))))
;
6323
6324 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6325 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6326
6327 return pi;
6328}
6329
6330proto_item *
6331proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6332 int start, int length, const uint64_t value,
6333 const char *format, ...)
6334{
6335 proto_item *pi;
6336 va_list ap;
6337
6338 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6339 if (pi != tree) {
6340 va_start(ap, format)__builtin_va_start(ap, format);
6341 proto_tree_set_representation_value(pi, format, ap);
6342 va_end(ap)__builtin_va_end(ap);
6343 }
6344
6345 return pi;
6346}
6347
6348proto_item *
6349proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6350 int start, int length, const uint64_t value,
6351 const char *format, ...)
6352{
6353 proto_item *pi;
6354 va_list ap;
6355
6356 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6357 if (pi != tree) {
6358 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6358, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6359
6360 va_start(ap, format)__builtin_va_start(ap, format);
6361 proto_tree_set_representation(pi, format, ap);
6362 va_end(ap)__builtin_va_end(ap);
6363 }
6364
6365 return pi;
6366}
6367
6368/* Set the FT_EUI64 value */
6369static void
6370proto_tree_set_eui64(field_info *fi, const uint64_t value)
6371{
6372 uint8_t v[FT_EUI64_LEN8];
6373 phtonu64(v, value);
6374 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6375}
6376
6377static void
6378proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6379{
6380 if (encoding)
6381 {
6382 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6383 } else {
6384 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6385 }
6386}
6387
6388proto_item *
6389proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6390 const mac_hf_list_t *list_generic,
6391 int idx, tvbuff_t *tvb,
6392 proto_tree *tree, int offset)
6393{
6394 uint8_t addr[6];
6395 const char *addr_name = NULL((void*)0);
6396 const char *oui_name = NULL((void*)0);
6397 proto_item *addr_item = NULL((void*)0);
6398 proto_tree *addr_tree = NULL((void*)0);
6399 proto_item *ret_val = NULL((void*)0);
6400
6401 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6402 return NULL((void*)0);
6403 }
6404
6405 /* Resolve what we can of the address */
6406 tvb_memcpy(tvb, addr, offset, sizeof addr);
6407 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6408 addr_name = get_ether_name(addr);
6409 }
6410 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6411 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6412 }
6413
6414 /* Add the item for the specific address type */
6415 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6416 if (idx >= 0) {
6417 addr_tree = proto_item_add_subtree(ret_val, idx);
6418 }
6419 else {
6420 addr_tree = tree;
6421 }
6422
6423 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6424 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6425 tvb, offset, 6, addr_name);
6426 proto_item_set_generated(addr_item);
6427 proto_item_set_hidden(addr_item);
6428 }
6429
6430 if (list_specific->hf_oui != NULL((void*)0)) {
6431 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6432 proto_item_set_generated(addr_item);
6433 proto_item_set_hidden(addr_item);
6434
6435 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6436 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6437 proto_item_set_generated(addr_item);
6438 proto_item_set_hidden(addr_item);
6439 }
6440 }
6441
6442 if (list_specific->hf_lg != NULL((void*)0)) {
6443 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6444 }
6445 if (list_specific->hf_ig != NULL((void*)0)) {
6446 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6447 }
6448
6449 /* Were we given a list for generic address fields? If not, stop here */
6450 if (list_generic == NULL((void*)0)) {
6451 return ret_val;
6452 }
6453
6454 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6455 proto_item_set_hidden(addr_item);
6456
6457 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6458 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6459 tvb, offset, 6, addr_name);
6460 proto_item_set_generated(addr_item);
6461 proto_item_set_hidden(addr_item);
6462 }
6463
6464 if (list_generic->hf_oui != NULL((void*)0)) {
6465 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6466 proto_item_set_generated(addr_item);
6467 proto_item_set_hidden(addr_item);
6468
6469 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6470 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6471 proto_item_set_generated(addr_item);
6472 proto_item_set_hidden(addr_item);
6473 }
6474 }
6475
6476 if (list_generic->hf_lg != NULL((void*)0)) {
6477 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6478 proto_item_set_hidden(addr_item);
6479 }
6480 if (list_generic->hf_ig != NULL((void*)0)) {
6481 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6482 proto_item_set_hidden(addr_item);
6483 }
6484 return ret_val;
6485}
6486
6487static proto_item *
6488proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6489{
6490 proto_node *pnode, *tnode, *sibling;
6491 field_info *tfi;
6492 unsigned depth = 1;
6493
6494 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6494, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6495
6496 /*
6497 * Restrict our depth. proto_tree_traverse_pre_order and
6498 * proto_tree_traverse_post_order (and possibly others) are recursive
6499 * so we need to be mindful of our stack size.
6500 */
6501 if (tree->first_child == NULL((void*)0)) {
6502 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6503 depth++;
6504 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6505 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__)), 6508)))
6506 "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__)), 6508)))
6507 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__)), 6508)))
6508 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__)), 6508)))
;
6509 }
6510 }
6511 }
6512
6513 /*
6514 * Make sure "tree" is ready to have subtrees under it, by
6515 * checking whether it's been given an ett_ value.
6516 *
6517 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6518 * node of the protocol tree. That node is not displayed,
6519 * so it doesn't need an ett_ value to remember whether it
6520 * was expanded.
6521 */
6522 tnode = tree;
6523 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6524 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6525 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"
, 6526)
6526 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"
, 6526)
;
6527 /* XXX - is it safe to continue here? */
6528 }
6529
6530 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6531 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6532 pnode->parent = tnode;
6533 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6534 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6535 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6536
6537 if (tnode->last_child != NULL((void*)0)) {
6538 sibling = tnode->last_child;
6539 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6539, "sibling->next == ((void*)0)"
))))
;
6540 sibling->next = pnode;
6541 } else
6542 tnode->first_child = pnode;
6543 tnode->last_child = pnode;
6544
6545 /* We should not be adding a fake node for an interesting field */
6546 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", 6546, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6547
6548 /* XXX - Should the proto_item have a header_field_info member, at least
6549 * for faked items, to know what hfi was faked? (Some dissectors look at
6550 * the tree items directly.)
6551 */
6552 return (proto_item *)pnode;
6553}
6554
6555/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6556static proto_item *
6557proto_tree_add_node(proto_tree *tree, field_info *fi)
6558{
6559 proto_node *pnode, *tnode, *sibling;
6560 field_info *tfi;
6561 unsigned depth = 1;
6562
6563 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6563, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6564
6565 /*
6566 * Restrict our depth. proto_tree_traverse_pre_order and
6567 * proto_tree_traverse_post_order (and possibly others) are recursive
6568 * so we need to be mindful of our stack size.
6569 */
6570 if (tree->first_child == NULL((void*)0)) {
6571 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6572 depth++;
6573 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6574 fvalue_free(fi->value);
6575 fi->value = NULL((void*)0);
6576 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__)), 6579)))
6577 "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__)), 6579)))
6578 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__)), 6579)))
6579 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__)), 6579)))
;
6580 }
6581 }
6582 }
6583
6584 /*
6585 * Make sure "tree" is ready to have subtrees under it, by
6586 * checking whether it's been given an ett_ value.
6587 *
6588 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6589 * node of the protocol tree. That node is not displayed,
6590 * so it doesn't need an ett_ value to remember whether it
6591 * was expanded.
6592 */
6593 tnode = tree;
6594 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6595 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6596 /* Since we are not adding fi to a node, its fvalue won't get
6597 * freed by proto_tree_free_node(), so free it now.
6598 */
6599 fvalue_free(fi->value);
6600 fi->value = NULL((void*)0);
6601 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", 6602)
6602 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", 6602)
;
6603 /* XXX - is it safe to continue here? */
6604 }
6605
6606 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6607 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6608 pnode->parent = tnode;
6609 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6610 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6611 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6612
6613 if (tnode->last_child != NULL((void*)0)) {
6614 sibling = tnode->last_child;
6615 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6615, "sibling->next == ((void*)0)"
))))
;
6616 sibling->next = pnode;
6617 } else
6618 tnode->first_child = pnode;
6619 tnode->last_child = pnode;
6620
6621 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6622
6623 return (proto_item *)pnode;
6624}
6625
6626
6627/* Generic way to allocate field_info and add to proto_tree.
6628 * Sets *pfi to address of newly-allocated field_info struct */
6629static proto_item *
6630proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6631 int *length)
6632{
6633 proto_item *pi;
6634 field_info *fi;
6635 int item_length;
6636
6637 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6638 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6639 pi = proto_tree_add_node(tree, fi);
6640
6641 return pi;
6642}
6643
6644
6645static void
6646get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6647 int *item_length, const unsigned encoding)
6648{
6649 int length_remaining;
6650
6651 /*
6652 * We only allow a null tvbuff if the item has a zero length,
6653 * i.e. if there's no data backing it.
6654 */
6655 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", 6655, "tvb != ((void*)0) || *length == 0"
))))
;
6656
6657 /*
6658 * XXX - in some protocols, there are 32-bit unsigned length
6659 * fields, so lengths in protocol tree and tvbuff routines
6660 * should really be unsigned. We should have, for those
6661 * field types for which "to the end of the tvbuff" makes sense,
6662 * additional routines that take no length argument and
6663 * add fields that run to the end of the tvbuff.
6664 */
6665 if (*length == -1) {
6666 /*
6667 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6668 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6669 * of -1 means "set the length to what remains in the
6670 * tvbuff".
6671 *
6672 * The assumption is either that
6673 *
6674 * 1) the length of the item can only be determined
6675 * by dissection (typically true of items with
6676 * subitems, which are probably FT_NONE or
6677 * FT_PROTOCOL)
6678 *
6679 * or
6680 *
6681 * 2) if the tvbuff is "short" (either due to a short
6682 * snapshot length or due to lack of reassembly of
6683 * fragments/segments/whatever), we want to display
6684 * what's available in the field (probably FT_BYTES
6685 * or FT_STRING) and then throw an exception later
6686 *
6687 * or
6688 *
6689 * 3) the field is defined to be "what's left in the
6690 * packet"
6691 *
6692 * so we set the length to what remains in the tvbuff so
6693 * that, if we throw an exception while dissecting, it
6694 * has what is probably the right value.
6695 *
6696 * For FT_STRINGZ, it means "the string is null-terminated,
6697 * not null-padded; set the length to the actual length
6698 * of the string", and if the tvbuff if short, we just
6699 * throw an exception.
6700 *
6701 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6702 * it means "find the end of the string",
6703 * and if the tvbuff if short, we just throw an exception.
6704 *
6705 * It's not valid for any other type of field. For those
6706 * fields, we treat -1 the same way we treat other
6707 * negative values - we assume the length is a Really
6708 * Big Positive Number, and throw a ReportedBoundsError
6709 * exception, under the assumption that the Really Big
6710 * Length would run past the end of the packet.
6711 */
6712 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
))
)) {
6713 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6714 /*
6715 * Leave the length as -1, so our caller knows
6716 * it was -1.
6717 */
6718 *item_length = *length;
6719 return;
6720 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6721 switch (tvb_get_uint8(tvb, start) >> 6)
6722 {
6723 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6724 *item_length = 1;
6725 break;
6726 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6727 *item_length = 2;
6728 break;
6729 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6730 *item_length = 4;
6731 break;
6732 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6733 *item_length = 8;
6734 break;
6735 }
6736 }
6737 }
6738
6739 switch (hfinfo->type) {
6740
6741 case FT_PROTOCOL:
6742 case FT_NONE:
6743 case FT_BYTES:
6744 case FT_STRING:
6745 case FT_STRINGZPAD:
6746 case FT_STRINGZTRUNC:
6747 /*
6748 * We allow FT_PROTOCOLs to be zero-length -
6749 * for example, an ONC RPC NULL procedure has
6750 * neither arguments nor reply, so the
6751 * payload for that protocol is empty.
6752 *
6753 * We also allow the others to be zero-length -
6754 * because that's the way the code has been for a
6755 * long, long time.
6756 *
6757 * However, we want to ensure that the start
6758 * offset is not *past* the byte past the end
6759 * of the tvbuff: we throw an exception in that
6760 * case.
6761 */
6762 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6763 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6763, "*length >= 0"
))))
;
6764 break;
6765
6766 case FT_STRINGZ:
6767 /*
6768 * Leave the length as -1, so our caller knows
6769 * it was -1.
6770 */
6771 break;
6772
6773 default:
6774 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6775 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6775))
;
6776 }
6777 *item_length = *length;
6778 } else {
6779 *item_length = *length;
6780 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6781 /*
6782 * These types are for interior nodes of the
6783 * tree, and don't have data associated with
6784 * them; if the length is negative (XXX - see
6785 * above) or goes past the end of the tvbuff,
6786 * cut it short at the end of the tvbuff.
6787 * That way, if this field is selected in
6788 * Wireshark, we don't highlight stuff past
6789 * the end of the data.
6790 */
6791 /* XXX - what to do, if we don't have a tvb? */
6792 /* XXX - Should *length be shortened to the remaining
6793 * length too, as in the -1 case? */
6794 if (tvb) {
6795 length_remaining = tvb_captured_length_remaining(tvb, start);
6796 if (*item_length < 0 ||
6797 (*item_length > 0 &&
6798 (length_remaining < *item_length)))
6799 *item_length = length_remaining;
6800 }
6801 }
6802 if (*item_length < 0) {
6803 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6804 }
6805 }
6806}
6807
6808static void
6809get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6810 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6811{
6812 unsigned length_remaining;
6813
6814 /*
6815 * We only allow a null tvbuff if the item has a zero length,
6816 * i.e. if there's no data backing it.
6817 */
6818 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", 6818, "tvb != ((void*)0) || *length == 0"
))))
;
6819
6820
6821 *item_length = *length;
6822 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6823 /*
6824 * These types are for interior nodes of the
6825 * tree, and don't have data associated with
6826 * them; if the length is negative (XXX - see
6827 * above) or goes past the end of the tvbuff,
6828 * cut it short at the end of the tvbuff.
6829 * That way, if this field is selected in
6830 * Wireshark, we don't highlight stuff past
6831 * the end of the data.
6832 */
6833 /* XXX - what to do, if we don't have a tvb? */
6834 if (tvb) {
6835 length_remaining = tvb_captured_length_remaining(tvb, start);
6836 if (*item_length > 0 && (length_remaining < *item_length)) {
6837 *item_length = length_remaining;
6838 }
6839 }
6840 }
6841}
6842
6843static int
6844get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6845 int length, unsigned item_length, const int encoding)
6846{
6847 uint32_t n;
6848
6849 /*
6850 * We need to get the correct item length here.
6851 * That's normally done by proto_tree_new_item(),
6852 * but we won't be calling it.
6853 */
6854 switch (hfinfo->type) {
6855
6856 case FT_NONE:
6857 case FT_PROTOCOL:
6858 case FT_BYTES:
6859 /*
6860 * The length is the specified length.
6861 */
6862 break;
6863
6864 case FT_UINT_BYTES:
6865 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6866 item_length += n;
6867 if ((int)item_length < length) {
6868 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6869 }
6870 break;
6871
6872 /* XXX - make these just FT_UINT? */
6873 case FT_UINT8:
6874 case FT_UINT16:
6875 case FT_UINT24:
6876 case FT_UINT32:
6877 case FT_UINT40:
6878 case FT_UINT48:
6879 case FT_UINT56:
6880 case FT_UINT64:
6881 /* XXX - make these just FT_INT? */
6882 case FT_INT8:
6883 case FT_INT16:
6884 case FT_INT24:
6885 case FT_INT32:
6886 case FT_INT40:
6887 case FT_INT48:
6888 case FT_INT56:
6889 case FT_INT64:
6890 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6891 if (length < -1) {
6892 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6893 }
6894 if (length == -1) {
6895 uint64_t dummy;
6896 /* This can throw an exception */
6897 /* XXX - do this without fetching the varint? */
6898 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6899 if (length == 0) {
6900 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6901 }
6902 }
6903 item_length = length;
6904 break;
6905 }
6906
6907 /*
6908 * The length is the specified length.
6909 */
6910 break;
6911
6912 case FT_BOOLEAN:
6913 case FT_CHAR:
6914 case FT_IPv4:
6915 case FT_IPXNET:
6916 case FT_IPv6:
6917 case FT_FCWWN:
6918 case FT_AX25:
6919 case FT_VINES:
6920 case FT_ETHER:
6921 case FT_EUI64:
6922 case FT_GUID:
6923 case FT_OID:
6924 case FT_REL_OID:
6925 case FT_SYSTEM_ID:
6926 case FT_FLOAT:
6927 case FT_DOUBLE:
6928 case FT_STRING:
6929 /*
6930 * The length is the specified length.
6931 */
6932 break;
6933
6934 case FT_STRINGZ:
6935 if (length < -1) {
6936 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6937 }
6938 if (length == -1) {
6939 /* This can throw an exception */
6940 item_length = tvb_strsize_enc(tvb, start, encoding);
6941 }
6942 break;
6943
6944 case FT_UINT_STRING:
6945 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6946 item_length += n;
6947 if ((int)item_length < length) {
6948 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6949 }
6950 break;
6951
6952 case FT_STRINGZPAD:
6953 case FT_STRINGZTRUNC:
6954 case FT_ABSOLUTE_TIME:
6955 case FT_RELATIVE_TIME:
6956 case FT_IEEE_11073_SFLOAT:
6957 case FT_IEEE_11073_FLOAT:
6958 /*
6959 * The length is the specified length.
6960 */
6961 break;
6962
6963 default:
6964 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
))
6965 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
))
6966 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
))
6967 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
))
;
6968 break;
6969 }
6970 return item_length;
6971}
6972
6973// This was arbitrarily chosen, but if you're adding 50K items to the tree
6974// without advancing the offset you should probably take a long, hard look
6975// at what you're doing.
6976// We *could* make this a configurable option, but I (Gerald) would like to
6977// avoid adding yet another nerd knob.
6978# define PROTO_TREE_MAX_IDLE50000 50000
6979static field_info *
6980new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6981 const int start, const int item_length)
6982{
6983 field_info *fi;
6984
6985 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6986
6987 fi->hfinfo = hfinfo;
6988 fi->start = start;
6989 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6990 /* add the data source tvbuff */
6991 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6992
6993 // If our start offset hasn't advanced after adding many items it probably
6994 // means we're in a large or infinite loop.
6995 if (fi->start > 0) {
6996 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6997 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6998 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
6999 if (wireshark_abort_on_too_many_items) {
7000 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", 7001
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7001 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7001
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7002 }
7003 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7004 * but if not, we should hit the max item error earlier,
7005 * so we shouldn't need to reset the tree count to
7006 * ensure that the exception handler can add the item. */
7007 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)))
7008 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)))
7009 "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)))
7010 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)))
;
7011 }
7012 } else {
7013 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7014 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7015 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7016 }
7017 }
7018 fi->length = item_length;
7019 fi->tree_type = -1;
7020 fi->flags = 0;
7021 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7022 /* If the tree is not visible, set the item hidden, unless we
7023 * need the representation or length and can't fake them.
7024 */
7025 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7026 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7027 }
7028 }
7029 fi->value = fvalue_new(fi->hfinfo->type);
7030 fi->rep = NULL((void*)0);
7031
7032 fi->appendix_start = 0;
7033 fi->appendix_length = 0;
7034
7035 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7036 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7037
7038 return fi;
7039}
7040
7041static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7042{
7043 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7044 return 0;
7045 }
7046
7047 /* Search for field name */
7048 char *ptr = strstr(representation, hfinfo->name);
7049 if (!ptr) {
7050 return 0;
7051 }
7052
7053 /* Check if field name ends with the ": " delimiter */
7054 ptr += strlen(hfinfo->name);
7055 if (strncmp(ptr, ": ", 2) == 0) {
7056 ptr += 2;
7057 }
7058
7059 /* Return offset to after field name */
7060 return ptr - representation;
7061}
7062
7063static size_t label_find_name_pos(const item_label_t *rep)
7064{
7065 size_t name_pos = 0;
7066
7067 /* If the value_pos is too small or too large, we can't find the expected format */
7068 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7069 return 0;
7070 }
7071
7072 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7073 if (rep->representation[rep->value_pos-2] == ':') {
7074 name_pos = rep->value_pos - 2;
7075 }
7076
7077 return name_pos;
7078}
7079
7080/* If the protocol tree is to be visible, set the representation of a
7081 proto_tree entry with the name of the field for the item and with
7082 the value formatted with the supplied printf-style format and
7083 argument list. */
7084static void
7085proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7086{
7087 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7087, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7088
7089 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7090 * items string representation */
7091 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7092 size_t name_pos, ret = 0;
7093 char *str;
7094 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7095 const header_field_info *hf;
7096
7097 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7097, "fi"))))
;
7098
7099 hf = fi->hfinfo;
7100
7101 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;
;
7102 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))
)) {
7103 uint64_t val;
7104 char *p;
7105
7106 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)
)
7107 val = fvalue_get_uinteger(fi->value);
7108 else
7109 val = fvalue_get_uinteger64(fi->value);
7110
7111 val <<= hfinfo_bitshift(hf);
7112
7113 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7114 ret = (p - fi->rep->representation);
7115 }
7116
7117 /* put in the hf name */
7118 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)
;
7119
7120 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7121 /* If possible, Put in the value of the string */
7122 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7123 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"
, 7123, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7124 fi->rep->value_pos = ret;
7125 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7126 if (ret >= ITEM_LABEL_LENGTH240) {
7127 /* Uh oh, we don't have enough room. Tell the user
7128 * that the field is truncated.
7129 */
7130 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7131 }
7132 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7133 }
7134}
7135
7136/* If the protocol tree is to be visible, set the representation of a
7137 proto_tree entry with the representation formatted with the supplied
7138 printf-style format and argument list. */
7139static void
7140proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7141{
7142 size_t ret; /*tmp return value */
7143 char *str;
7144 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7145
7146 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7146, "fi"))))
;
7147
7148 if (!proto_item_is_hidden(pi)) {
7149 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;
;
7150
7151 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7152 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"
, 7152, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7153 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7154 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7155 if (ret >= ITEM_LABEL_LENGTH240) {
7156 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7157 size_t name_pos = label_find_name_pos(fi->rep);
7158 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7159 }
7160 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7161 }
7162}
7163
7164static int
7165proto_strlcpy(char *dest, const char *src, size_t dest_size)
7166{
7167 if (dest_size == 0) return 0;
7168
7169 size_t res = g_strlcpy(dest, src, dest_size);
7170
7171 /* At most dest_size - 1 characters will be copied
7172 * (unless dest_size is 0). */
7173 if (res >= dest_size)
7174 res = dest_size - 1;
7175 return (int) res;
7176}
7177
7178static header_field_info *
7179hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7180{
7181 header_field_info *dup_hfinfo;
7182
7183 if (hfinfo->same_name_prev_id == -1)
7184 return NULL((void*)0);
7185 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", 7185
, __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", 7185, "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", 7185,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7186 return dup_hfinfo;
7187}
7188
7189static void
7190hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7191{
7192 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)
;
7193 last_field_name = NULL((void*)0);
7194
7195 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7196 /* No hfinfo with the same name */
7197 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7198 return;
7199 }
7200
7201 if (hfinfo->same_name_next) {
7202 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7203 }
7204
7205 if (hfinfo->same_name_prev_id != -1) {
7206 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7207 same_name_prev->same_name_next = hfinfo->same_name_next;
7208 if (!hfinfo->same_name_next) {
7209 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7210 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7211 }
7212 }
7213}
7214
7215int
7216proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7217{
7218 const header_field_info *hfinfo = finfo->hfinfo;
7219 int label_len = 0;
7220 char *tmp_str;
7221 const char *str;
7222 const uint8_t *bytes;
7223 uint32_t number;
7224 uint64_t number64;
7225 const char *hf_str_val;
7226 char number_buf[NUMBER_LABEL_LENGTH80];
7227 const char *number_out;
7228 address addr;
7229 const ipv4_addr_and_mask *ipv4;
7230 const ipv6_addr_and_prefix *ipv6;
7231
7232 switch (hfinfo->type) {
7233
7234 case FT_NONE:
7235 case FT_PROTOCOL:
7236 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7237
7238 case FT_UINT_BYTES:
7239 case FT_BYTES:
7240 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7241 hfinfo,
7242 fvalue_get_bytes_data(finfo->value),
7243 (unsigned)fvalue_length2(finfo->value),
7244 label_str_size);
7245 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7246 wmem_free(NULL((void*)0), tmp_str);
7247 break;
7248
7249 case FT_ABSOLUTE_TIME:
7250 {
7251 const nstime_t *value = fvalue_get_time(finfo->value);
7252 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7253 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7254 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7255 }
7256 if (hfinfo->strings) {
7257 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7258 if (time_string != NULL((void*)0)) {
7259 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7260 break;
7261 }
7262 }
7263 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7264 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7265 wmem_free(NULL((void*)0), tmp_str);
7266 break;
7267 }
7268
7269 case FT_RELATIVE_TIME:
7270 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7271 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7272 wmem_free(NULL((void*)0), tmp_str);
7273 break;
7274
7275 case FT_BOOLEAN:
7276 number64 = fvalue_get_uinteger64(finfo->value);
7277 label_len = proto_strlcpy(display_label_str,
7278 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7279 break;
7280
7281 case FT_CHAR:
7282 number = fvalue_get_uinteger(finfo->value);
7283
7284 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7285 char tmp[ITEM_LABEL_LENGTH240];
7286 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7287
7288 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7288, "fmtfunc"))))
;
7289 fmtfunc(tmp, number);
7290
7291 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7292
7293 } else if (hfinfo->strings) {
7294 number_out = hf_try_val_to_str(number, hfinfo);
7295
7296 if (!number_out) {
7297 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7298 }
7299
7300 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7301
7302 } else {
7303 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7304
7305 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7306 }
7307
7308 break;
7309
7310 /* XXX - make these just FT_NUMBER? */
7311 case FT_INT8:
7312 case FT_INT16:
7313 case FT_INT24:
7314 case FT_INT32:
7315 case FT_UINT8:
7316 case FT_UINT16:
7317 case FT_UINT24:
7318 case FT_UINT32:
7319 case FT_FRAMENUM:
7320 hf_str_val = NULL((void*)0);
7321 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
))
?
7322 (uint32_t) fvalue_get_sinteger(finfo->value) :
7323 fvalue_get_uinteger(finfo->value);
7324
7325 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7326 char tmp[ITEM_LABEL_LENGTH240];
7327 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7328
7329 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7329, "fmtfunc"))))
;
7330 fmtfunc(tmp, number);
7331
7332 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7333
7334 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7335 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7336 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7337 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7338 hf_str_val = hf_try_val_to_str(number, hfinfo);
7339 if (hf_str_val)
7340 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7341 } else {
7342 number_out = hf_try_val_to_str(number, hfinfo);
7343
7344 if (!number_out) {
7345 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7346 }
7347
7348 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7349 }
7350 } else {
7351 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7352
7353 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7354 }
7355
7356 break;
7357
7358 case FT_INT40:
7359 case FT_INT48:
7360 case FT_INT56:
7361 case FT_INT64:
7362 case FT_UINT40:
7363 case FT_UINT48:
7364 case FT_UINT56:
7365 case FT_UINT64:
7366 hf_str_val = NULL((void*)0);
7367 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
))
?
7368 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7369 fvalue_get_uinteger64(finfo->value);
7370
7371 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7372 char tmp[ITEM_LABEL_LENGTH240];
7373 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7374
7375 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7375, "fmtfunc64"
))))
;
7376 fmtfunc64(tmp, number64);
7377
7378 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7379 } else if (hfinfo->strings) {
7380 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7381 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7382 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7383 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7384 if (hf_str_val)
7385 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7386 } else {
7387 number_out = hf_try_val64_to_str(number64, hfinfo);
7388
7389 if (!number_out)
7390 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7391
7392 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7393 }
7394 } else {
7395 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7396
7397 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7398 }
7399
7400 break;
7401
7402 case FT_EUI64:
7403 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7404 tmp_str = address_to_display(NULL((void*)0), &addr);
7405 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7406 wmem_free(NULL((void*)0), tmp_str);
7407 break;
7408
7409 case FT_IPv4:
7410 ipv4 = fvalue_get_ipv4(finfo->value);
7411 //XXX: Should we ignore the mask?
7412 set_address_ipv4(&addr, ipv4);
7413 tmp_str = address_to_display(NULL((void*)0), &addr);
7414 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7415 wmem_free(NULL((void*)0), tmp_str);
7416 free_address(&addr);
7417 break;
7418
7419 case FT_IPv6:
7420 ipv6 = fvalue_get_ipv6(finfo->value);
7421 set_address_ipv6(&addr, ipv6);
7422 tmp_str = address_to_display(NULL((void*)0), &addr);
7423 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7424 wmem_free(NULL((void*)0), tmp_str);
7425 free_address(&addr);
7426 break;
7427
7428 case FT_FCWWN:
7429 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7430 tmp_str = address_to_display(NULL((void*)0), &addr);
7431 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7432 wmem_free(NULL((void*)0), tmp_str);
7433 break;
7434
7435 case FT_ETHER:
7436 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7437 tmp_str = address_to_display(NULL((void*)0), &addr);
7438 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7439 wmem_free(NULL((void*)0), tmp_str);
7440 break;
7441
7442 case FT_GUID:
7443 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7444 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7445 wmem_free(NULL((void*)0), tmp_str);
7446 break;
7447
7448 case FT_REL_OID:
7449 bytes = fvalue_get_bytes_data(finfo->value);
7450 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7451 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7452 wmem_free(NULL((void*)0), tmp_str);
7453 break;
7454
7455 case FT_OID:
7456 bytes = fvalue_get_bytes_data(finfo->value);
7457 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7458 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7459 wmem_free(NULL((void*)0), tmp_str);
7460 break;
7461
7462 case FT_SYSTEM_ID:
7463 bytes = fvalue_get_bytes_data(finfo->value);
7464 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7465 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7466 wmem_free(NULL((void*)0), tmp_str);
7467 break;
7468
7469 case FT_FLOAT:
7470 case FT_DOUBLE:
7471 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7472 break;
7473
7474 case FT_IEEE_11073_SFLOAT:
7475 case FT_IEEE_11073_FLOAT:
7476 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7477 break;
7478
7479 case FT_STRING:
7480 case FT_STRINGZ:
7481 case FT_UINT_STRING:
7482 case FT_STRINGZPAD:
7483 case FT_STRINGZTRUNC:
7484 str = fvalue_get_string(finfo->value);
7485 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7486 if (label_len >= label_str_size) {
7487 /* Truncation occurred. Get the real length
7488 * copied (not including '\0') */
7489 label_len = label_str_size ? label_str_size - 1 : 0;
7490 }
7491 break;
7492
7493 default:
7494 /* First try ftype string representation */
7495 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7496 if (!tmp_str) {
7497 /* Default to show as bytes */
7498 bytes = fvalue_get_bytes_data(finfo->value);
7499 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7500 }
7501 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7502 wmem_free(NULL((void*)0), tmp_str);
7503 break;
7504 }
7505 return label_len;
7506}
7507
7508const char *
7509proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7510 char *result, char *expr, const int size)
7511{
7512 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7513 GPtrArray *finfos;
7514 field_info *finfo = NULL((void*)0);
7515 header_field_info* hfinfo;
7516 const char *abbrev = NULL((void*)0);
7517
7518 char *str;
7519 col_custom_t *field_idx;
7520 int field_id;
7521 int ii = 0;
7522
7523 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7523, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7524 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7525 field_id = field_idx->field_id;
7526 if (field_id == 0) {
7527 GPtrArray *fvals = NULL((void*)0);
7528 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7529 if (fvals != NULL((void*)0)) {
7530
7531 // XXX - Handling occurrences is unusual when more
7532 // than one field is involved, e.g. there's four
7533 // results for tcp.port + tcp.port. We may really
7534 // want to apply it to the operands, not the output.
7535 // Note that occurrences are not quite the same as
7536 // the layer operator (should the grammar support
7537 // both?)
7538 /* Calculate single index or set outer boundaries */
7539 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7540 if (occurrence < 0) {
7541 i = occurrence + len;
7542 last = i;
7543 } else if (occurrence > 0) {
7544 i = occurrence - 1;
7545 last = i;
7546 } else {
7547 i = 0;
7548 last = len - 1;
7549 }
7550 if (i < 0 || i >= len) {
7551 g_ptr_array_unref(fvals);
7552 continue;
7553 }
7554 for (; i <= last; i++) {
7555 /* XXX - We could have a "resolved" result
7556 * for types where the value depends only
7557 * on the type, e.g. FT_IPv4, and not on
7558 * hfinfo->strings. Supporting the latter
7559 * requires knowing which hfinfo matched
7560 * if there are multiple with the same
7561 * abbreviation. In any case, we need to
7562 * know the expected return type of the
7563 * field expression.
7564 */
7565 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7566 if (offset_r && (offset_r < (size - 1)))
7567 result[offset_r++] = ',';
7568 if (offset_e && (offset_e < (size - 1)))
7569 expr[offset_e++] = ',';
7570 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7571 // col_{add,append,set}_* calls ws_label_strcpy
7572 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7573
7574 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7575 }
7576 g_ptr_array_unref(fvals);
7577 } else if (passed) {
7578 // XXX - Occurrence doesn't make sense for a test
7579 // output, it should be applied to the operands.
7580 if (offset_r && (offset_r < (size - 1)))
7581 result[offset_r++] = ',';
7582 if (offset_e && (offset_e < (size - 1)))
7583 expr[offset_e++] = ',';
7584 /* Prevent multiple check marks */
7585 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7586 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7587 } else {
7588 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7589 }
7590 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7591 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7592 } else {
7593 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7594 }
7595 }
7596 continue;
7597 }
7598 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", 7598
, __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", 7598,
"(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", 7598,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7599
7600 /* do we need to rewind ? */
7601 if (!hfinfo)
7602 return "";
7603
7604 if (occurrence < 0) {
7605 /* Search other direction */
7606 while (hfinfo->same_name_prev_id != -1) {
7607 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", 7607
, __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", 7607, "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", 7607,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7608 }
7609 }
7610
7611 prev_len = 0; /* Reset handled occurrences */
7612
7613 while (hfinfo) {
7614 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7615
7616 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7617 if (occurrence < 0) {
7618 hfinfo = hfinfo->same_name_next;
7619 } else {
7620 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7621 }
7622 continue;
7623 }
7624
7625 /* Are there enough occurrences of the field? */
7626 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7627 if (occurrence < 0) {
7628 hfinfo = hfinfo->same_name_next;
7629 } else {
7630 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7631 }
7632 prev_len += len;
7633 continue;
7634 }
7635
7636 /* Calculate single index or set outer boundaries */
7637 if (occurrence < 0) {
7638 i = occurrence + len + prev_len;
7639 last = i;
7640 } else if (occurrence > 0) {
7641 i = occurrence - 1 - prev_len;
7642 last = i;
7643 } else {
7644 i = 0;
7645 last = len - 1;
7646 }
7647
7648 prev_len += len; /* Count handled occurrences */
7649
7650 while (i <= last) {
7651 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7652
7653 if (offset_r && (offset_r < (size - 1)))
7654 result[offset_r++] = ',';
7655
7656 if (display_details) {
7657 char representation[ITEM_LABEL_LENGTH240];
7658 size_t offset = 0;
7659
7660 if (finfo->rep && finfo->rep->value_len) {
7661 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7662 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7663 } else {
7664 proto_item_fill_label(finfo, representation, &offset);
7665 }
7666 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7667 } else {
7668 switch (hfinfo->type) {
7669
7670 case FT_NONE:
7671 case FT_PROTOCOL:
7672 /* Prevent multiple check marks */
7673 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7674 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7675 } else {
7676 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7677 }
7678 break;
7679
7680 default:
7681 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7682 break;
7683 }
7684 }
7685
7686 if (offset_e && (offset_e < (size - 1)))
7687 expr[offset_e++] = ',';
7688
7689 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
))
)) {
7690 const char *hf_str_val;
7691 /* Integer types with BASE_NONE never get the numeric value. */
7692 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7693 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7694 } 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
)
) {
7695 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7696 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7697 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7698 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7699 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7700 }
7701 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7702 offset_e = (int)strlen(expr);
7703 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7704 /* Prevent multiple check marks */
7705 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7706 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7707 } else {
7708 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7709 }
7710 } else {
7711 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7712 // col_{add,append,set}_* calls ws_label_strcpy
7713 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7714 wmem_free(NULL((void*)0), str);
7715 }
7716 i++;
7717 }
7718
7719 /* XXX: Why is only the first abbreviation returned for a multifield
7720 * custom column? */
7721 if (!abbrev) {
7722 /* Store abbrev for return value */
7723 abbrev = hfinfo->abbrev;
7724 }
7725
7726 if (occurrence == 0) {
7727 /* Fetch next hfinfo with same name (abbrev) */
7728 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7729 } else {
7730 hfinfo = NULL((void*)0);
7731 }
7732 }
7733 }
7734
7735 if (offset_r >= (size - 1)) {
7736 mark_truncated(result, 0, size, NULL((void*)0));
7737 }
7738 if (offset_e >= (size - 1)) {
7739 mark_truncated(expr, 0, size, NULL((void*)0));
7740 }
7741 return abbrev ? abbrev : "";
7742}
7743
7744char *
7745proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7746{
7747 int len, prev_len, last, i;
7748 GPtrArray *finfos;
7749 field_info *finfo = NULL((void*)0);
7750 header_field_info* hfinfo;
7751
7752 char *filter = NULL((void*)0);
7753 GPtrArray *filter_array;
7754
7755 col_custom_t *col_custom;
7756 int field_id;
7757
7758 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7758, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7759 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7760 for (GSList *iter = field_ids; iter; iter = iter->next) {
7761 col_custom = (col_custom_t*)iter->data;
7762 field_id = col_custom->field_id;
7763 if (field_id == 0) {
7764 GPtrArray *fvals = NULL((void*)0);
7765 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7766 if (fvals != NULL((void*)0)) {
7767 // XXX - Handling occurrences is unusual when more
7768 // than one field is involved, e.g. there's four
7769 // results for tcp.port + tcp.port. We really
7770 // want to apply it to the operands, not the output.
7771 /* Calculate single index or set outer boundaries */
7772 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7773 if (occurrence < 0) {
7774 i = occurrence + len;
7775 last = i;
7776 } else if (occurrence > 0) {
7777 i = occurrence - 1;
7778 last = i;
7779 } else {
7780 i = 0;
7781 last = len - 1;
7782 }
7783 if (i < 0 || i >= len) {
7784 g_ptr_array_unref(fvals);
7785 continue;
7786 }
7787 for (; i <= last; i++) {
7788 /* XXX - Should multiple values for one
7789 * field use set membership to reduce
7790 * verbosity, here and below? */
7791 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7792 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7793 wmem_free(NULL((void*)0), str);
7794 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7795 g_ptr_array_add(filter_array, filter);
7796 }
7797 }
7798 g_ptr_array_unref(fvals);
7799 } else if (passed) {
7800 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7801 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7802 g_ptr_array_add(filter_array, filter);
7803 }
7804 } else {
7805 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7806 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7807 g_ptr_array_add(filter_array, filter);
7808 }
7809 }
7810 continue;
7811 }
7812
7813 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", 7813
, __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", 7813,
"(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", 7813,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7814
7815 /* do we need to rewind ? */
7816 if (!hfinfo)
7817 return NULL((void*)0);
7818
7819 if (occurrence < 0) {
7820 /* Search other direction */
7821 while (hfinfo->same_name_prev_id != -1) {
7822 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", 7822
, __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", 7822, "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", 7822,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7823 }
7824 }
7825
7826 prev_len = 0; /* Reset handled occurrences */
7827
7828 while (hfinfo) {
7829 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7830
7831 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7832 if (occurrence < 0) {
7833 hfinfo = hfinfo->same_name_next;
7834 } else {
7835 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7836 }
7837 continue;
7838 }
7839
7840 /* Are there enough occurrences of the field? */
7841 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7842 if (occurrence < 0) {
7843 hfinfo = hfinfo->same_name_next;
7844 } else {
7845 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7846 }
7847 prev_len += len;
7848 continue;
7849 }
7850
7851 /* Calculate single index or set outer boundaries */
7852 if (occurrence < 0) {
7853 i = occurrence + len + prev_len;
7854 last = i;
7855 } else if (occurrence > 0) {
7856 i = occurrence - 1 - prev_len;
7857 last = i;
7858 } else {
7859 i = 0;
7860 last = len - 1;
7861 }
7862
7863 prev_len += len; /* Count handled occurrences */
7864
7865 while (i <= last) {
7866 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7867
7868 filter = proto_construct_match_selected_string(finfo, edt);
7869 if (filter) {
7870 /* Only add the same expression once (especially for FT_PROTOCOL).
7871 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7872 */
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 i++;
7878 }
7879
7880 if (occurrence == 0) {
7881 /* Fetch next hfinfo with same name (abbrev) */
7882 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7883 } else {
7884 hfinfo = NULL((void*)0);
7885 }
7886 }
7887 }
7888
7889 g_ptr_array_add(filter_array, NULL((void*)0));
7890
7891 /* XXX: Should this be || or && ? */
7892 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7893
7894 g_ptr_array_free(filter_array, true1);
7895
7896 return output;
7897}
7898
7899/* Set text of proto_item after having already been created. */
7900void
7901proto_item_set_text(proto_item *pi, const char *format, ...)
7902{
7903 field_info *fi = NULL((void*)0);
7904 va_list ap;
7905
7906 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7907
7908 fi = PITEM_FINFO(pi)((pi)->finfo);
7909 if (fi == NULL((void*)0))
7910 return;
7911
7912 if (fi->rep) {
7913 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7914 fi->rep = NULL((void*)0);
7915 }
7916
7917 va_start(ap, format)__builtin_va_start(ap, format);
7918 proto_tree_set_representation(pi, format, ap);
7919 va_end(ap)__builtin_va_end(ap);
7920}
7921
7922/* Append to text of proto_item after having already been created. */
7923void
7924proto_item_append_text(proto_item *pi, const char *format, ...)
7925{
7926 field_info *fi = NULL((void*)0);
7927 size_t curlen;
7928 char *str;
7929 va_list ap;
7930
7931 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7932
7933 fi = PITEM_FINFO(pi)((pi)->finfo);
7934 if (fi == NULL((void*)0)) {
7935 return;
7936 }
7937
7938 if (!proto_item_is_hidden(pi)) {
7939 /*
7940 * If we don't already have a representation,
7941 * generate the default representation.
7942 */
7943 if (fi->rep == NULL((void*)0)) {
7944 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;
;
7945 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7946 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7947 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7948 (strncmp(format, ": ", 2) == 0)) {
7949 fi->rep->value_pos += 2;
7950 }
7951 }
7952 if (fi->rep) {
7953 curlen = strlen(fi->rep->representation);
7954 /* curlen doesn't include the \0 byte.
7955 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7956 * the representation has already been truncated (of an up
7957 * to 4 byte UTF-8 character) or is just at the maximum length
7958 * unless we search for " [truncated]" (which may not be
7959 * at the start.)
7960 * It's safer to do nothing.
7961 */
7962 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7963 va_start(ap, format)__builtin_va_start(ap, format);
7964 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7965 va_end(ap)__builtin_va_end(ap);
7966 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"
, 7966, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7967 /* Keep fi->rep->value_pos */
7968 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7969 if (curlen >= ITEM_LABEL_LENGTH240) {
7970 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7971 size_t name_pos = label_find_name_pos(fi->rep);
7972 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7973 }
7974 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7975 }
7976 }
7977 }
7978}
7979
7980/* Prepend to text of proto_item after having already been created. */
7981void
7982proto_item_prepend_text(proto_item *pi, const char *format, ...)
7983{
7984 field_info *fi = NULL((void*)0);
7985 size_t pos;
7986 char representation[ITEM_LABEL_LENGTH240];
7987 char *str;
7988 va_list ap;
7989
7990 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7991
7992 fi = PITEM_FINFO(pi)((pi)->finfo);
7993 if (fi == NULL((void*)0)) {
7994 return;
7995 }
7996
7997 if (!proto_item_is_hidden(pi)) {
7998 /*
7999 * If we don't already have a representation,
8000 * generate the default representation.
8001 */
8002 if (fi->rep == NULL((void*)0)) {
8003 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;
;
8004 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8005 } else
8006 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8007
8008 va_start(ap, format)__builtin_va_start(ap, format);
8009 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8010 va_end(ap)__builtin_va_end(ap);
8011 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"
, 8011, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8012 fi->rep->value_pos += strlen(str);
8013 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8014 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8015 /* XXX: As above, if the old representation is close to the label
8016 * length, it might already be marked as truncated. */
8017 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8018 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8019 size_t name_pos = label_find_name_pos(fi->rep);
8020 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8021 }
8022 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8023 }
8024}
8025
8026static void
8027finfo_set_len(field_info *fi, const unsigned length)
8028{
8029 unsigned length_remaining;
8030
8031 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8032 if (length > length_remaining)
8033 fi->length = length_remaining;
8034 else
8035 fi->length = length;
8036
8037 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8038 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8039 fvalue_set_protocol_length(fi->value, fi->length);
8040 }
8041
8042 /*
8043 * You cannot just make the "len" field of a GByteArray
8044 * larger, if there's no data to back that length;
8045 * you can only make it smaller.
8046 */
8047 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8048 GBytes *bytes = fvalue_get_bytes(fi->value);
8049 size_t size;
8050 const void *data = g_bytes_get_data(bytes, &size);
8051 if ((size_t)fi->length <= size) {
8052 fvalue_set_bytes_data(fi->value, data, fi->length);
8053 }
8054 g_bytes_unref(bytes);
8055 }
8056}
8057
8058void
8059proto_item_set_len(proto_item *pi, const unsigned length)
8060{
8061 field_info *fi;
8062
8063 if (pi == NULL((void*)0))
8064 return;
8065
8066 fi = PITEM_FINFO(pi)((pi)->finfo);
8067 if (fi == NULL((void*)0))
8068 return;
8069
8070 finfo_set_len(fi, length);
8071}
8072
8073/*
8074 * Sets the length of the item based on its start and on the specified
8075 * offset, which is the offset past the end of the item; as the start
8076 * in the item is relative to the beginning of the data source tvbuff,
8077 * we need to pass in a tvbuff - the end offset is relative to the beginning
8078 * of that tvbuff.
8079 */
8080void
8081proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8082{
8083 field_info *fi;
8084 unsigned length;
8085
8086 if (pi == NULL((void*)0))
8087 return;
8088
8089 fi = PITEM_FINFO(pi)((pi)->finfo);
8090 if (fi == NULL((void*)0))
8091 return;
8092
8093 if (G_LIKELY(tvb)(tvb)) {
8094 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"
, 8094, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8095 end += tvb_raw_offset(tvb);
8096 } else {
8097 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", 8097, "((void*)0) == fi->ds_tvb"
))))
;
8098 }
8099 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8099, "end >= fi->start"
))))
;
8100 length = end - fi->start;
8101
8102 finfo_set_len(fi, length);
8103}
8104
8105unsigned
8106proto_item_get_len(const proto_item *pi)
8107{
8108 /* XXX - The only use case where this is really guaranteed to work is
8109 * increasing the length of an item (which has no effect if the item
8110 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8111 *
8112 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8113 *
8114 * Should there be a macro or function to do that, and possibly this
8115 * be deprecated? As a bonus, we could handle overflow.
8116 */
8117 field_info *fi;
8118
8119 if (!pi)
8120 return 0;
8121 fi = PITEM_FINFO(pi)((pi)->finfo);
8122 if (fi) {
8123 return fi->length;
8124 }
8125 return 0;
8126}
8127
8128void
8129proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8130 if (!ti) {
8131 return;
8132 }
8133 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)
;
8134 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)
;
8135}
8136
8137char *
8138proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8139{
8140 field_info *fi;
8141
8142 if (!pi)
8143 return wmem_strdup(scope, "");
8144 fi = PITEM_FINFO(pi)((pi)->finfo);
8145 if (!fi)
8146 return wmem_strdup(scope, "");
8147 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8147, "fi->hfinfo != ((void*)0)"
))))
;
8148 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8149}
8150
8151proto_tree *
8152proto_tree_create_root(packet_info *pinfo)
8153{
8154 proto_node *pnode;
8155
8156 /* Initialize the proto_node */
8157 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8158 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8159 pnode->parent = NULL((void*)0);
8160 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8161 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)))
;
8162
8163 /* Make sure we can access pinfo everywhere */
8164 pnode->tree_data->pinfo = pinfo;
8165
8166 /* Don't initialize the tree_data_t. Wait until we know we need it */
8167 pnode->tree_data->interesting_hfids = NULL((void*)0);
8168
8169 /* Set the default to false so it's easier to
8170 * find errors; if we expect to see the protocol tree
8171 * but for some reason the default 'visible' is not
8172 * changed, then we'll find out very quickly. */
8173 pnode->tree_data->visible = false0;
8174
8175 /* Make sure that we fake protocols (if possible) */
8176 pnode->tree_data->fake_protocols = true1;
8177
8178 /* Keep track of the number of children */
8179 pnode->tree_data->count = 0;
8180
8181 /* Initialize our loop checks */
8182 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8183 pnode->tree_data->max_start = 0;
8184 pnode->tree_data->start_idle_count = 0;
8185
8186 return (proto_tree *)pnode;
8187}
8188
8189
8190/* "prime" a proto_tree with a single hfid that a dfilter
8191 * is interested in. */
8192void
8193proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8194{
8195 header_field_info *hfinfo;
8196
8197 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", 8197, __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", 8197, "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", 8197, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8198 /* this field is referenced by a filter so increase the refcount.
8199 also increase the refcount for the parent, i.e the protocol.
8200 Don't increase the refcount if we're already printing the
8201 type, as that is a superset of direct reference.
8202 */
8203 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8204 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8205 }
8206 /* only increase the refcount if there is a parent.
8207 if this is a protocol and not a field then parent will be -1
8208 and there is no parent to add any refcounting for.
8209 */
8210 if (hfinfo->parent != -1) {
8211 header_field_info *parent_hfinfo;
8212 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", 8212
, __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", 8212,
"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", 8212,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8213
8214 /* Mark parent as indirectly referenced unless it is already directly
8215 * referenced, i.e. the user has specified the parent in a filter.
8216 */
8217 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8218 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8219 }
8220}
8221
8222/* "prime" a proto_tree with a single hfid that a dfilter
8223 * is interested in. */
8224void
8225proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8226{
8227 header_field_info *hfinfo;
8228
8229 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", 8229, __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", 8229, "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", 8229, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8230 /* this field is referenced by an (output) filter so increase the refcount.
8231 also increase the refcount for the parent, i.e the protocol.
8232 */
8233 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8234 /* only increase the refcount if there is a parent.
8235 if this is a protocol and not a field then parent will be -1
8236 and there is no parent to add any refcounting for.
8237 */
8238 if (hfinfo->parent != -1) {
8239 header_field_info *parent_hfinfo;
8240 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", 8240
, __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", 8240,
"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", 8240,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8241
8242 /* Mark parent as indirectly referenced unless it is already directly
8243 * referenced, i.e. the user has specified the parent in a filter.
8244 */
8245 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8246 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8247 }
8248}
8249
8250proto_tree *
8251proto_item_add_subtree(proto_item *pi, const int idx) {
8252 field_info *fi;
8253
8254 if (!pi)
8255 return NULL((void*)0);
8256
8257 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", 8257, "idx >= 0 && idx < num_tree_types"
))))
;
8258
8259 fi = PITEM_FINFO(pi)((pi)->finfo);
8260 if (!fi)
8261 return (proto_tree *)pi;
8262
8263 fi->tree_type = idx;
8264
8265 return (proto_tree *)pi;
8266}
8267
8268proto_tree *
8269proto_item_get_subtree(proto_item *pi) {
8270 field_info *fi;
8271
8272 if (!pi)
8273 return NULL((void*)0);
8274 fi = PITEM_FINFO(pi)((pi)->finfo);
8275 if ( (fi) && (fi->tree_type == -1) )
8276 return NULL((void*)0);
8277 return (proto_tree *)pi;
8278}
8279
8280proto_item *
8281proto_item_get_parent(const proto_item *ti) {
8282 if (!ti)
8283 return NULL((void*)0);
8284 return ti->parent;
8285}
8286
8287proto_item *
8288proto_item_get_parent_nth(proto_item *ti, int gen) {
8289 if (!ti)
8290 return NULL((void*)0);
8291 while (gen--) {
8292 ti = ti->parent;
8293 if (!ti)
8294 return NULL((void*)0);
8295 }
8296 return ti;
8297}
8298
8299
8300proto_item *
8301proto_tree_get_parent(proto_tree *tree) {
8302 if (!tree)
8303 return NULL((void*)0);
8304 return (proto_item *)tree;
8305}
8306
8307proto_tree *
8308proto_tree_get_parent_tree(proto_tree *tree) {
8309 if (!tree)
8310 return NULL((void*)0);
8311
8312 /* we're the root tree, there's no parent
8313 return ourselves so the caller has at least a tree to attach to */
8314 if (!tree->parent)
8315 return tree;
8316
8317 return (proto_tree *)tree->parent;
8318}
8319
8320proto_tree *
8321proto_tree_get_root(proto_tree *tree) {
8322 if (!tree)
8323 return NULL((void*)0);
8324 while (tree->parent) {
8325 tree = tree->parent;
8326 }
8327 return tree;
8328}
8329
8330void
8331proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8332 proto_item *item_to_move)
8333{
8334 /* This function doesn't generate any values. It only reorganizes the protocol tree
8335 * so we can bail out immediately if it isn't visible. */
8336 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8337 return;
8338
8339 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", 8339, "item_to_move->parent == tree"
))))
;
8340 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", 8340, "fixed_item->parent == tree"
))))
;
8341
8342 /*** cut item_to_move out ***/
8343
8344 /* is item_to_move the first? */
8345 if (tree->first_child == item_to_move) {
8346 /* simply change first child to next */
8347 tree->first_child = item_to_move->next;
8348
8349 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", 8349, "tree->last_child != item_to_move"
))))
;
8350 } else {
8351 proto_item *curr_item;
8352 /* find previous and change it's next */
8353 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8354 if (curr_item->next == item_to_move) {
8355 break;
8356 }
8357 }
8358
8359 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8359, "curr_item"
))))
;
8360
8361 curr_item->next = item_to_move->next;
8362
8363 /* fix last_child if required */
8364 if (tree->last_child == item_to_move) {
8365 tree->last_child = curr_item;
8366 }
8367 }
8368
8369 /*** insert to_move after fixed ***/
8370 item_to_move->next = fixed_item->next;
8371 fixed_item->next = item_to_move;
8372 if (tree->last_child == fixed_item) {
8373 tree->last_child = item_to_move;
8374 }
8375}
8376
8377void
8378proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8379 const int length)
8380{
8381 field_info *fi;
8382
8383 if (tree == NULL((void*)0))
8384 return;
8385
8386 fi = PTREE_FINFO(tree)((tree)->finfo);
8387 if (fi == NULL((void*)0))
8388 return;
8389
8390 /* We don't store a separate data source tvb for the appendix, so
8391 * it must be from the same data source. (XXX - Are there any
8392 * situations where it makes sense to have an appendix from a
8393 * different data source?) */
8394 if (G_LIKELY(tvb)(tvb)) {
8395 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"
, 8395, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8396 start += tvb_raw_offset(tvb);
8397 } else {
8398 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", 8398, "((void*)0) == fi->ds_tvb"
))))
;
8399 }
8400 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8400, "start >= 0"
))))
;
8401 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8401, "length >= 0"
))))
;
8402
8403 fi->appendix_start = start;
8404 fi->appendix_length = length;
8405}
8406
8407static void
8408check_protocol_filter_name_or_fail(const char *filter_name)
8409{
8410 /* Require at least two characters. */
8411 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8412 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)
;
8413 }
8414
8415 if (proto_check_field_name(filter_name) != '\0') {
8416 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)
8417 " 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)
8418 " 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)
;
8419 }
8420
8421 /* Check that it doesn't match some very common numeric forms. */
8422 if (filter_name[0] == '0' &&
8423 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8424 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8425 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])
8426 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])
;
8427 }
8428
8429 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8430
8431 /* Check that it contains at least one letter. */
8432 bool_Bool have_letter = false0;
8433 for (const char *s = filter_name; *s != '\0'; s++) {
8434 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8435 have_letter = true1;
8436 break;
8437 }
8438 }
8439 if (!have_letter) {
8440 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)
8441 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8442 }
8443
8444 /* Check for reserved keywords. */
8445 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8446 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)
8447 " 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)
;
8448 }
8449}
8450
8451int
8452proto_register_protocol(const char *name, const char *short_name,
8453 const char *filter_name)
8454{
8455 protocol_t *protocol;
8456 header_field_info *hfinfo;
8457
8458 check_protocol_filter_name_or_fail(filter_name);
8459
8460 /*
8461 * Add this protocol to the list of known protocols;
8462 * the list is sorted by protocol short name.
8463 */
8464 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8465 protocol->name = name;
8466 protocol->short_name = short_name;
8467 protocol->filter_name = filter_name;
8468 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8469 protocol->is_enabled = true1; /* protocol is enabled by default */
8470 protocol->enabled_by_default = true1; /* see previous comment */
8471 protocol->can_toggle = true1;
8472 protocol->parent_proto_id = -1;
8473 protocol->heur_list = NULL((void*)0);
8474
8475 /* List will be sorted later by name, when all protocols completed registering */
8476 protocols = g_list_prepend(protocols, protocol);
8477 /*
8478 * Make sure there's not already a protocol with any of those
8479 * names. Crash if there is, as that's an error in the code
8480 * or an inappropriate plugin.
8481 * This situation has to be fixed to not register more than one
8482 * protocol with the same name.
8483 */
8484 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8485 /* ws_error will terminate the program */
8486 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)
8487 " 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)
;
8488 }
8489 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8490 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)
8491 " 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)
;
8492 }
8493 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8494 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)
8495 " 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)
;
8496 }
8497
8498 /* Here we allocate a new header_field_info struct */
8499 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8500 hfinfo->name = name;
8501 hfinfo->abbrev = filter_name;
8502 hfinfo->type = FT_PROTOCOL;
8503 hfinfo->display = BASE_NONE;
8504 hfinfo->strings = protocol;
8505 hfinfo->bitmask = 0;
8506 hfinfo->ref_type = HF_REF_TYPE_NONE;
8507 hfinfo->blurb = NULL((void*)0);
8508 hfinfo->parent = -1; /* This field differentiates protos and fields */
8509
8510 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8511 return protocol->proto_id;
8512}
8513
8514int
8515proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8516{
8517 protocol_t *protocol;
8518 header_field_info *hfinfo;
8519
8520 /*
8521 * Helper protocols don't need the strict rules as a "regular" protocol
8522 * Just register it in a list and make a hf_ field from it
8523 */
8524 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8525 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)
;
8526 }
8527
8528 if (parent_proto <= 0) {
8529 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)
8530 " 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)
;
8531 }
8532
8533 check_protocol_filter_name_or_fail(filter_name);
8534
8535 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8536 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8537 protocol->name = name;
8538 protocol->short_name = short_name;
8539 protocol->filter_name = filter_name;
8540 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8541
8542 /* Enabling and toggling is really determined by parent protocol,
8543 but provide default values here */
8544 protocol->is_enabled = true1;
8545 protocol->enabled_by_default = true1;
8546 protocol->can_toggle = true1;
8547
8548 protocol->parent_proto_id = parent_proto;
8549 protocol->heur_list = NULL((void*)0);
8550
8551 /* List will be sorted later by name, when all protocols completed registering */
8552 protocols = g_list_prepend(protocols, protocol);
8553
8554 /* Here we allocate a new header_field_info struct */
8555 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8556 hfinfo->name = name;
8557 hfinfo->abbrev = filter_name;
8558 hfinfo->type = field_type;
8559 hfinfo->display = BASE_NONE;
8560 if (field_type == FT_BYTES) {
8561 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8562 }
8563 hfinfo->strings = protocol;
8564 hfinfo->bitmask = 0;
8565 hfinfo->ref_type = HF_REF_TYPE_NONE;
8566 hfinfo->blurb = NULL((void*)0);
8567 hfinfo->parent = -1; /* This field differentiates protos and fields */
8568
8569 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8570 return protocol->proto_id;
8571}
8572
8573bool_Bool
8574proto_deregister_protocol(const char *short_name)
8575{
8576 protocol_t *protocol;
8577 header_field_info *hfinfo;
8578 int proto_id;
8579 unsigned i;
8580
8581 proto_id = proto_get_id_by_short_name(short_name);
8582 protocol = find_protocol_by_id(proto_id);
8583 if (protocol == NULL((void*)0))
8584 return false0;
8585
8586 g_hash_table_remove(proto_names, protocol->name);
8587 g_hash_table_remove(proto_short_names, (void *)short_name);
8588 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8589
8590 if (protocol->fields) {
8591 for (i = 0; i < protocol->fields->len; i++) {
8592 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8593 hfinfo_remove_from_gpa_name_map(hfinfo);
8594 expert_deregister_expertinfo(hfinfo->abbrev);
8595 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8596 }
8597 g_ptr_array_free(protocol->fields, true1);
8598 protocol->fields = NULL((void*)0);
8599 }
8600
8601 g_list_free(protocol->heur_list);
8602
8603 /* Remove this protocol from the list of known protocols */
8604 protocols = g_list_remove(protocols, protocol);
8605
8606 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8607 wmem_map_remove(gpa_name_map, protocol->filter_name);
8608
8609 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)
;
8610 last_field_name = NULL((void*)0);
8611
8612 return true1;
8613}
8614
8615void
8616proto_register_alias(const int proto_id, const char *alias_name)
8617{
8618 protocol_t *protocol;
8619
8620 protocol = find_protocol_by_id(proto_id);
8621 if (alias_name && protocol) {
8622 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8623 }
8624}
8625
8626/*
8627 * Routines to use to iterate over the protocols.
8628 * The argument passed to the iterator routines is an opaque cookie to
8629 * their callers; it's the GList pointer for the current element in
8630 * the list.
8631 * The ID of the protocol is returned, or -1 if there is no protocol.
8632 */
8633int
8634proto_get_first_protocol(void **cookie)
8635{
8636 protocol_t *protocol;
8637
8638 if (protocols == NULL((void*)0))
8639 return -1;
8640 *cookie = protocols;
8641 protocol = (protocol_t *)protocols->data;
8642 return protocol->proto_id;
8643}
8644
8645int
8646proto_get_data_protocol(void *cookie)
8647{
8648 GList *list_item = (GList *)cookie;
8649
8650 protocol_t *protocol = (protocol_t *)list_item->data;
8651 return protocol->proto_id;
8652}
8653
8654int
8655proto_get_next_protocol(void **cookie)
8656{
8657 GList *list_item = (GList *)*cookie;
8658 protocol_t *protocol;
8659
8660 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8661 if (list_item == NULL((void*)0))
8662 return -1;
8663 *cookie = list_item;
8664 protocol = (protocol_t *)list_item->data;
8665 return protocol->proto_id;
8666}
8667
8668header_field_info *
8669proto_get_first_protocol_field(const int proto_id, void **cookie)
8670{
8671 protocol_t *protocol = find_protocol_by_id(proto_id);
8672
8673 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8674 return NULL((void*)0);
8675
8676 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8677 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8678}
8679
8680header_field_info *
8681proto_get_next_protocol_field(const int proto_id, void **cookie)
8682{
8683 protocol_t *protocol = find_protocol_by_id(proto_id);
8684 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8685
8686 i++;
8687
8688 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8689 return NULL((void*)0);
8690
8691 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8692 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8693}
8694
8695protocol_t *
8696find_protocol_by_id(const int proto_id)
8697{
8698 header_field_info *hfinfo;
8699
8700 if (proto_id <= 0)
8701 return NULL((void*)0);
8702
8703 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", 8703, __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", 8703,
"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", 8703, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8704 if (hfinfo->type != FT_PROTOCOL) {
8705 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", 8705, "hfinfo->display & 0x00004000"
))))
;
8706 }
8707 return (protocol_t *)hfinfo->strings;
8708}
8709
8710int
8711proto_get_id(const protocol_t *protocol)
8712{
8713 return protocol->proto_id;
8714}
8715
8716bool_Bool
8717proto_name_already_registered(const char *name)
8718{
8719 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8719, "name", "No name present"))))
;
8720
8721 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8722 return true1;
8723 return false0;
8724}
8725
8726int
8727proto_get_id_by_filter_name(const char *filter_name)
8728{
8729 const protocol_t *protocol = NULL((void*)0);
8730
8731 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", 8731,
"filter_name", "No filter name present"))))
;
8732
8733 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8734
8735 if (protocol == NULL((void*)0))
8736 return -1;
8737 return protocol->proto_id;
8738}
8739
8740int
8741proto_get_id_by_short_name(const char *short_name)
8742{
8743 const protocol_t *protocol = NULL((void*)0);
8744
8745 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", 8745,
"short_name", "No short name present"))))
;
8746
8747 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8748
8749 if (protocol == NULL((void*)0))
8750 return -1;
8751 return protocol->proto_id;
8752}
8753
8754const char *
8755proto_get_protocol_name(const int proto_id)
8756{
8757 protocol_t *protocol;
8758
8759 protocol = find_protocol_by_id(proto_id);
8760
8761 if (protocol == NULL((void*)0))
8762 return NULL((void*)0);
8763 return protocol->name;
8764}
8765
8766const char *
8767proto_get_protocol_short_name(const protocol_t *protocol)
8768{
8769 if (protocol == NULL((void*)0))
8770 return "(none)";
8771 return protocol->short_name;
8772}
8773
8774const char *
8775proto_get_protocol_long_name(const protocol_t *protocol)
8776{
8777 if (protocol == NULL((void*)0))
8778 return "(none)";
8779 return protocol->name;
8780}
8781
8782const char *
8783proto_get_protocol_filter_name(const int proto_id)
8784{
8785 protocol_t *protocol;
8786
8787 protocol = find_protocol_by_id(proto_id);
8788 if (protocol == NULL((void*)0))
8789 return "(none)";
8790 return protocol->filter_name;
8791}
8792
8793void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8794{
8795 heur_dtbl_entry_t* heuristic_dissector;
8796
8797 if (protocol == NULL((void*)0))
8798 return;
8799
8800 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8801 if (heuristic_dissector != NULL((void*)0))
8802 {
8803 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8804 }
8805}
8806
8807void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8808{
8809 if (protocol == NULL((void*)0))
8810 return;
8811
8812 g_list_foreach(protocol->heur_list, func, user_data);
8813}
8814
8815void
8816proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8817 bool_Bool *is_tcp, bool_Bool *is_udp,
8818 bool_Bool *is_sctp, bool_Bool *is_tls,
8819 bool_Bool *is_rtp,
8820 bool_Bool *is_lte_rlc)
8821{
8822 wmem_list_frame_t *protos = wmem_list_head(layers);
8823 int proto_id;
8824 const char *proto_name;
8825
8826 /* Walk the list of a available protocols in the packet and
8827 attempt to find "major" ones. */
8828 /* It might make more sense to assemble and return a bitfield. */
8829 while (protos != NULL((void*)0))
8830 {
8831 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8832 proto_name = proto_get_protocol_filter_name(proto_id);
8833
8834 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8835 (!strcmp(proto_name, "ipv6")))) {
8836 *is_ip = true1;
8837 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8838 *is_tcp = true1;
8839 } else if (is_udp && !strcmp(proto_name, "udp")) {
8840 *is_udp = true1;
8841 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8842 *is_sctp = true1;
8843 } else if (is_tls && !strcmp(proto_name, "tls")) {
8844 *is_tls = true1;
8845 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8846 *is_rtp = true1;
8847 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8848 *is_lte_rlc = true1;
8849 }
8850
8851 protos = wmem_list_frame_next(protos);
8852 }
8853}
8854
8855bool_Bool
8856proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8857{
8858 wmem_list_frame_t *protos = wmem_list_head(layers);
8859 int proto_id;
8860 const char *name;
8861
8862 /* Walk the list of a available protocols in the packet and
8863 attempt to find the specified protocol. */
8864 while (protos != NULL((void*)0))
8865 {
8866 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8867 name = proto_get_protocol_filter_name(proto_id);
8868
8869 if (!strcmp(name, proto_name))
8870 {
8871 return true1;
8872 }
8873
8874 protos = wmem_list_frame_next(protos);
8875 }
8876
8877 return false0;
8878}
8879
8880char *
8881proto_list_layers(const packet_info *pinfo)
8882{
8883 wmem_strbuf_t *buf;
8884 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8885
8886 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8887
8888 /* Walk the list of layers in the packet and
8889 return a string of all entries. */
8890 while (layers != NULL((void*)0))
8891 {
8892 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8893
8894 layers = wmem_list_frame_next(layers);
8895 if (layers != NULL((void*)0)) {
8896 wmem_strbuf_append_c(buf, ':');
8897 }
8898 }
8899
8900 return wmem_strbuf_finalize(buf);
8901}
8902
8903uint8_t
8904proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8905{
8906 int *proto_layer_num_ptr;
8907
8908 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8909 if (proto_layer_num_ptr == NULL((void*)0)) {
8910 return 0;
8911 }
8912
8913 return (uint8_t)*proto_layer_num_ptr;
8914}
8915
8916bool_Bool
8917proto_is_pino(const protocol_t *protocol)
8918{
8919 return (protocol->parent_proto_id != -1);
8920}
8921
8922bool_Bool
8923// NOLINTNEXTLINE(misc-no-recursion)
8924proto_is_protocol_enabled(const protocol_t *protocol)
8925{
8926 if (protocol == NULL((void*)0))
8927 return false0;
8928
8929 //parent protocol determines enable/disable for helper dissectors
8930 if (proto_is_pino(protocol))
8931 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8932
8933 return protocol->is_enabled;
8934}
8935
8936bool_Bool
8937// NOLINTNEXTLINE(misc-no-recursion)
8938proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8939{
8940 //parent protocol determines enable/disable for helper dissectors
8941 if (proto_is_pino(protocol))
8942 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8943
8944 return protocol->enabled_by_default;
8945}
8946
8947bool_Bool
8948// NOLINTNEXTLINE(misc-no-recursion)
8949proto_can_toggle_protocol(const int proto_id)
8950{
8951 protocol_t *protocol;
8952
8953 protocol = find_protocol_by_id(proto_id);
8954 //parent protocol determines toggling for helper dissectors
8955 if (proto_is_pino(protocol))
8956 return proto_can_toggle_protocol(protocol->parent_proto_id);
8957
8958 return protocol->can_toggle;
8959}
8960
8961void
8962proto_disable_by_default(const int proto_id)
8963{
8964 protocol_t *protocol;
8965
8966 protocol = find_protocol_by_id(proto_id);
8967 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8967, "protocol->can_toggle"
))))
;
8968 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", 8968, "proto_is_pino(protocol) == 0"
))))
;
8969 protocol->is_enabled = false0;
8970 protocol->enabled_by_default = false0;
8971}
8972
8973void
8974proto_set_decoding(const int proto_id, const bool_Bool enabled)
8975{
8976 protocol_t *protocol;
8977
8978 protocol = find_protocol_by_id(proto_id);
8979 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8979, "protocol->can_toggle"
))))
;
8980 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", 8980, "proto_is_pino(protocol) == 0"
))))
;
8981 protocol->is_enabled = enabled;
8982}
8983
8984void
8985proto_disable_all(void)
8986{
8987 /* This doesn't explicitly disable heuristic protocols,
8988 * but the heuristic doesn't get called if the parent
8989 * protocol isn't enabled.
8990 */
8991 protocol_t *protocol;
8992 GList *list_item = protocols;
8993
8994 if (protocols == NULL((void*)0))
8995 return;
8996
8997 while (list_item) {
8998 protocol = (protocol_t *)list_item->data;
8999 if (protocol->can_toggle) {
9000 protocol->is_enabled = false0;
9001 }
9002 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9003 }
9004}
9005
9006static void
9007heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9008{
9009 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9010
9011 heur->enabled = heur->enabled_by_default;
9012}
9013
9014void
9015proto_reenable_all(void)
9016{
9017 protocol_t *protocol;
9018 GList *list_item = protocols;
9019
9020 if (protocols == NULL((void*)0))
9021 return;
9022
9023 while (list_item) {
9024 protocol = (protocol_t *)list_item->data;
9025 if (protocol->can_toggle)
9026 protocol->is_enabled = protocol->enabled_by_default;
9027 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9028 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9029 }
9030}
9031
9032void
9033proto_set_cant_toggle(const int proto_id)
9034{
9035 protocol_t *protocol;
9036
9037 protocol = find_protocol_by_id(proto_id);
9038 protocol->can_toggle = false0;
9039}
9040
9041static int
9042proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9043{
9044 g_ptr_array_add(proto->fields, hfi);
9045
9046 return proto_register_field_init(hfi, parent);
9047}
9048
9049/* for use with static arrays only, since we don't allocate our own copies
9050of the header_field_info struct contained within the hf_register_info struct */
9051void
9052proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9053{
9054 hf_register_info *ptr = hf;
9055 protocol_t *proto;
9056 int i;
9057
9058 proto = find_protocol_by_id(parent);
9059
9060 /* if (proto == NULL) - error or return? */
9061
9062 if (proto->fields == NULL((void*)0)) {
9063 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9064 * GLib introduced g_ptr_array_new_from_array, which might have
9065 * given a reason to actually use it. (#17774)
9066 */
9067 proto->fields = g_ptr_array_sized_new(num_records);
9068 }
9069
9070 for (i = 0; i < num_records; i++, ptr++) {
9071 /*
9072 * Make sure we haven't registered this yet.
9073 * Most fields have variables associated with them that
9074 * are initialized to 0; some are initialized to -1 (which
9075 * was the standard before 4.4).
9076 *
9077 * XXX - Since this is called almost 300000 times at startup,
9078 * it might be nice to compare to only 0 and require
9079 * dissectors to pass in zero for unregistered fields.
9080 */
9081 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9082 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9083 "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)
9084 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9085 return;
9086 }
9087
9088 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9089 }
9090}
9091
9092/* deregister already registered fields */
9093void
9094proto_deregister_field (const int parent, int hf_id)
9095{
9096 header_field_info *hfi;
9097 protocol_t *proto;
9098 unsigned i;
9099
9100 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)
;
9101 last_field_name = NULL((void*)0);
9102
9103 if (hf_id == -1 || hf_id == 0)
9104 return;
9105
9106 proto = find_protocol_by_id (parent);
9107 if (!proto || proto->fields == NULL((void*)0)) {
9108 return;
9109 }
9110
9111 for (i = 0; i < proto->fields->len; i++) {
9112 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9113 if (hfi->id == hf_id) {
9114 /* Found the hf_id in this protocol */
9115 wmem_map_remove(gpa_name_map, hfi->abbrev);
9116 g_ptr_array_remove_index_fast(proto->fields, i);
9117 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9118 return;
9119 }
9120 }
9121}
9122
9123/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9124void
9125proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9126{
9127 header_field_info *hfinfo;
9128 protocol_t *proto;
9129
9130 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)
;
9131 last_field_name = NULL((void*)0);
9132
9133 proto = find_protocol_by_id(parent);
9134 if (proto && proto->fields && proto->fields->len > 0) {
9135 unsigned i = proto->fields->len;
9136 do {
9137 i--;
9138
9139 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9140 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) )
) {
9141 hfinfo_remove_from_gpa_name_map(hfinfo);
9142 expert_deregister_expertinfo(hfinfo->abbrev);
9143 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9144 g_ptr_array_remove_index_fast(proto->fields, i);
9145 }
9146 } while (i > 0);
9147 }
9148}
9149
9150void
9151proto_add_deregistered_data (void *data)
9152{
9153 g_ptr_array_add(deregistered_data, data);
9154}
9155
9156void
9157proto_add_deregistered_slice (size_t block_size, void *mem_block)
9158{
9159 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)))
;
9160
9161 slice_data->block_size = block_size;
9162 slice_data->mem_block = mem_block;
9163
9164 g_ptr_array_add(deregistered_slice, slice_data);
9165}
9166
9167void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9168{
9169 if (field_strings == NULL((void*)0)) {
9170 return;
9171 }
9172
9173 switch (field_type) {
9174 case FT_FRAMENUM:
9175 /* This is just an integer represented as a pointer */
9176 break;
9177 case FT_PROTOCOL: {
9178 protocol_t *protocol = (protocol_t *)field_strings;
9179 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)
;
9180 break;
9181 }
9182 case FT_BOOLEAN: {
9183 true_false_string *tf = (true_false_string *)field_strings;
9184 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)
;
9185 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)
;
9186 break;
9187 }
9188 case FT_UINT40:
9189 case FT_INT40:
9190 case FT_UINT48:
9191 case FT_INT48:
9192 case FT_UINT56:
9193 case FT_INT56:
9194 case FT_UINT64:
9195 case FT_INT64: {
9196 if (field_display & BASE_UNIT_STRING0x00001000) {
9197 unit_name_string *unit = (unit_name_string *)field_strings;
9198 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)
;
9199 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)
;
9200 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9201 range_string *rs = (range_string *)field_strings;
9202 while (rs->strptr) {
9203 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
)
;
9204 rs++;
9205 }
9206 } else if (field_display & BASE_EXT_STRING0x00000200) {
9207 val64_string_ext *vse = (val64_string_ext *)field_strings;
9208 val64_string *vs = (val64_string *)vse->_vs_p;
9209 while (vs->strptr) {
9210 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
)
;
9211 vs++;
9212 }
9213 val64_string_ext_free(vse);
9214 field_strings = NULL((void*)0);
9215 } else if (field_display == BASE_CUSTOM) {
9216 /* this will be a pointer to a function, don't free that */
9217 field_strings = NULL((void*)0);
9218 } else {
9219 val64_string *vs64 = (val64_string *)field_strings;
9220 while (vs64->strptr) {
9221 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)
;
9222 vs64++;
9223 }
9224 }
9225 break;
9226 }
9227 case FT_CHAR:
9228 case FT_UINT8:
9229 case FT_INT8:
9230 case FT_UINT16:
9231 case FT_INT16:
9232 case FT_UINT24:
9233 case FT_INT24:
9234 case FT_UINT32:
9235 case FT_INT32:
9236 case FT_FLOAT:
9237 case FT_DOUBLE: {
9238 if (field_display & BASE_UNIT_STRING0x00001000) {
9239 unit_name_string *unit = (unit_name_string *)field_strings;
9240 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)
;
9241 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)
;
9242 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9243 range_string *rs = (range_string *)field_strings;
9244 while (rs->strptr) {
9245 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
)
;
9246 rs++;
9247 }
9248 } else if (field_display & BASE_EXT_STRING0x00000200) {
9249 value_string_ext *vse = (value_string_ext *)field_strings;
9250 value_string *vs = (value_string *)vse->_vs_p;
9251 while (vs->strptr) {
9252 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
)
;
9253 vs++;
9254 }
9255 value_string_ext_free(vse);
9256 field_strings = NULL((void*)0);
9257 } else if (field_display == BASE_CUSTOM) {
9258 /* this will be a pointer to a function, don't free that */
9259 field_strings = NULL((void*)0);
9260 } else {
9261 value_string *vs = (value_string *)field_strings;
9262 while (vs->strptr) {
9263 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
)
;
9264 vs++;
9265 }
9266 }
9267 break;
9268 default:
9269 break;
9270 }
9271 }
9272
9273 if (field_type != FT_FRAMENUM) {
9274 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
)
;
9275 }
9276}
9277
9278static void
9279free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9280{
9281 header_field_info *hfi = (header_field_info *) data;
9282 int hf_id = hfi->id;
9283
9284 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
)
;
9285 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
)
;
9286 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
)
;
9287
9288 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9289
9290 if (hfi->parent == -1)
9291 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)
;
9292
9293 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9294}
9295
9296static void
9297free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9298{
9299 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9300}
9301
9302static void
9303free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9304{
9305 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9306
9307 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9308 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)
;
9309}
9310
9311/* free deregistered fields and data */
9312void
9313proto_free_deregistered_fields (void)
9314{
9315 expert_free_deregistered_expertinfos();
9316
9317 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9318 g_ptr_array_free(deregistered_fields, true1);
9319 deregistered_fields = g_ptr_array_new();
9320
9321 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9322 g_ptr_array_free(deregistered_data, true1);
9323 deregistered_data = g_ptr_array_new();
9324
9325 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9326 g_ptr_array_free(deregistered_slice, true1);
9327 deregistered_slice = g_ptr_array_new();
9328}
9329
9330static const value_string hf_display[] = {
9331 { BASE_NONE, "BASE_NONE" },
9332 { BASE_DEC, "BASE_DEC" },
9333 { BASE_HEX, "BASE_HEX" },
9334 { BASE_OCT, "BASE_OCT" },
9335 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9336 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9337 { BASE_CUSTOM, "BASE_CUSTOM" },
9338 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9339 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9340 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9341 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9342 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9343 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9344 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9345 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9346 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9347 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9348 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9349 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9350 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9351 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9352 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9353 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9354 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9355 { BASE_PT_UDP, "BASE_PT_UDP" },
9356 { BASE_PT_TCP, "BASE_PT_TCP" },
9357 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9358 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9359 { BASE_OUI, "BASE_OUI" },
9360 { 0, NULL((void*)0) } };
9361
9362const char* proto_field_display_to_string(int field_display)
9363{
9364 return val_to_str_const(field_display, hf_display, "Unknown");
9365}
9366
9367static inline port_type
9368display_to_port_type(field_display_e e)
9369{
9370 switch (e) {
9371 case BASE_PT_UDP:
9372 return PT_UDP;
9373 case BASE_PT_TCP:
9374 return PT_TCP;
9375 case BASE_PT_DCCP:
9376 return PT_DCCP;
9377 case BASE_PT_SCTP:
9378 return PT_SCTP;
9379 default:
9380 break;
9381 }
9382 return PT_NONE;
9383}
9384
9385/* temporary function containing assert part for easier profiling */
9386static void
9387tmp_fld_check_assert(header_field_info *hfinfo)
9388{
9389 char* tmp_str;
9390
9391 /* The field must have a name (with length > 0) */
9392 if (!hfinfo->name || !hfinfo->name[0]) {
9393 if (hfinfo->abbrev)
9394 /* Try to identify the field */
9395 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)
9396 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9397 else
9398 /* Hum, no luck */
9399 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)"
)
;
9400 }
9401
9402 /* fields with an empty string for an abbreviation aren't filterable */
9403 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9404 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)
;
9405
9406 /* TODO: This check is a significant percentage of startup time (~10%),
9407 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9408 It might be nice to have a way to disable this check when, e.g.,
9409 running TShark many times with the same configuration. */
9410 /* Check that the filter name (abbreviation) is legal;
9411 * it must contain only alphanumerics, '-', "_", and ".". */
9412 unsigned char c;
9413 c = module_check_valid_name(hfinfo->abbrev, false0);
9414 if (c) {
9415 if (c == '.') {
9416 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)
;
9417 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9418 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)
;
9419 } else {
9420 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)
;
9421 }
9422 }
9423
9424 /* These types of fields are allowed to have value_strings,
9425 * true_false_strings or a protocol_t struct
9426 */
9427 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9428 switch (hfinfo->type) {
9429
9430 /*
9431 * These types are allowed to support display value_strings,
9432 * value64_strings, the extended versions of the previous
9433 * two, range strings, or unit strings.
9434 */
9435 case FT_CHAR:
9436 case FT_UINT8:
9437 case FT_UINT16:
9438 case FT_UINT24:
9439 case FT_UINT32:
9440 case FT_UINT40:
9441 case FT_UINT48:
9442 case FT_UINT56:
9443 case FT_UINT64:
9444 case FT_INT8:
9445 case FT_INT16:
9446 case FT_INT24:
9447 case FT_INT32:
9448 case FT_INT40:
9449 case FT_INT48:
9450 case FT_INT56:
9451 case FT_INT64:
9452 case FT_BOOLEAN:
9453 case FT_PROTOCOL:
9454 break;
9455
9456 /*
9457 * This is allowed to have a value of type
9458 * enum ft_framenum_type to indicate what relationship
9459 * the frame in question has to the frame in which
9460 * the field is put.
9461 */
9462 case FT_FRAMENUM:
9463 break;
9464
9465 /*
9466 * These types are allowed to support only unit strings.
9467 */
9468 case FT_FLOAT:
9469 case FT_DOUBLE:
9470 case FT_IEEE_11073_SFLOAT:
9471 case FT_IEEE_11073_FLOAT:
9472 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9473 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))
9474 " (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))
9475 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))
;
9476 }
9477 break;
9478
9479 /*
9480 * These types are allowed to support display
9481 * time_value_strings.
9482 */
9483 case FT_ABSOLUTE_TIME:
9484 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9485 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9486 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9487 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9488 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))
9489 " (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))
9490 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))
;
9491 }
9492 break;
9493
9494 /*
9495 * This type is only allowed to support a string if it's
9496 * a protocol (for pinos).
9497 */
9498 case FT_BYTES:
9499 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9500 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))
9501 " (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))
9502 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))
;
9503 }
9504 break;
9505
9506 default:
9507 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))
9508 " (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))
9509 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))
;
9510 }
9511 }
9512
9513 /* TODO: This check may slow down startup, and output quite a few warnings.
9514 It would be good to be able to enable this (and possibly other checks?)
9515 in non-release builds. */
9516#ifdef ENABLE_CHECK_FILTER
9517 /* Check for duplicate value_string values.
9518 There are lots that have the same value *and* string, so for now only
9519 report those that have same value but different string. */
9520 if ((hfinfo->strings != NULL((void*)0)) &&
9521 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9522 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9523 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9524 (
9525 (hfinfo->type == FT_CHAR) ||
9526 (hfinfo->type == FT_UINT8) ||
9527 (hfinfo->type == FT_UINT16) ||
9528 (hfinfo->type == FT_UINT24) ||
9529 (hfinfo->type == FT_UINT32) ||
9530 (hfinfo->type == FT_INT8) ||
9531 (hfinfo->type == FT_INT16) ||
9532 (hfinfo->type == FT_INT24) ||
9533 (hfinfo->type == FT_INT32) )) {
9534
9535 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9536 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9537 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9538 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9539 } else {
9540 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9541 CHECK_HF_VALUE(value_string, "u", start_values);
9542 }
9543 } else {
9544 const value_string *start_values = (const value_string*)hfinfo->strings;
9545 CHECK_HF_VALUE(value_string, "u", start_values);
9546 }
9547 }
9548
9549 if (hfinfo->type == FT_BOOLEAN) {
9550 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9551 if (tfs) {
9552 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9553 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9555
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9554 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9555
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9555 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9555
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9556 }
9557 }
9558 }
9559
9560 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9561 const range_string *rs = (const range_string*)(hfinfo->strings);
9562 if (rs) {
9563 const range_string *this_it = rs;
9564
9565 do {
9566 if (this_it->value_max < this_it->value_min) {
9567 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"
, 9571, __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)
9568 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9571, __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)
9569 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9571, __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)
9570 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9571, __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)
9571 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9571, __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)
;
9572 ++this_it;
9573 continue;
9574 }
9575
9576 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9577 /* Not OK if this one is completely hidden by an earlier one! */
9578 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9579 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"
, 9585, __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)
9580 "(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"
, 9585, __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)
9581 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9585, __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)
9582 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9585, __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)
9583 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9585, __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)
9584 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9585, __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)
9585 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9585, __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)
;
9586 }
9587 }
9588 ++this_it;
9589 } while (this_it->strptr);
9590 }
9591 }
9592#endif
9593
9594 switch (hfinfo->type) {
9595
9596 case FT_CHAR:
9597 /* Require the char type to have BASE_HEX, BASE_OCT,
9598 * BASE_CUSTOM, or BASE_NONE as its base.
9599 *
9600 * If the display value is BASE_NONE and there is a
9601 * strings conversion then the dissector writer is
9602 * telling us that the field's numerical value is
9603 * meaningless; we'll avoid showing the value to the
9604 * user.
9605 */
9606 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9607 case BASE_HEX:
9608 case BASE_OCT:
9609 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9610 break;
9611 case BASE_NONE:
9612 if (hfinfo->strings == NULL((void*)0))
9613 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
))
9614 " 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
))
9615 " 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
))
9616 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
))
9617 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
))
;
9618 break;
9619 default:
9620 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9621 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)
9622 " 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)
9623 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)
9624 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)
;
9625 //wmem_free(NULL, tmp_str);
9626 }
9627 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9628 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
))
9629 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
))
9630 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
))
;
9631 }
9632 break;
9633 case FT_INT8:
9634 case FT_INT16:
9635 case FT_INT24:
9636 case FT_INT32:
9637 case FT_INT40:
9638 case FT_INT48:
9639 case FT_INT56:
9640 case FT_INT64:
9641 /* Hexadecimal and octal are, in printf() and everywhere
9642 * else, unsigned so don't allow dissectors to register a
9643 * signed field to be displayed unsigned. (Else how would
9644 * we display negative values?)
9645 */
9646 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9647 case BASE_HEX:
9648 case BASE_OCT:
9649 case BASE_DEC_HEX:
9650 case BASE_HEX_DEC:
9651 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9652 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)
9653 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)
9654 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)
;
9655 //wmem_free(NULL, tmp_str);
9656 }
9657 /* FALL THROUGH */
9658 case FT_UINT8:
9659 case FT_UINT16:
9660 case FT_UINT24:
9661 case FT_UINT32:
9662 case FT_UINT40:
9663 case FT_UINT48:
9664 case FT_UINT56:
9665 case FT_UINT64:
9666 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
))
) {
9667 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9668 if (hfinfo->type != FT_UINT16) {
9669 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))
9670 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))
9671 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))
;
9672 }
9673 if (hfinfo->strings != NULL((void*)0)) {
9674 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)
9675 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)
9676 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)
;
9677 }
9678 if (hfinfo->bitmask != 0) {
9679 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)
9680 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)
9681 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)
;
9682 }
9683 wmem_free(NULL((void*)0), tmp_str);
9684 break;
9685 }
9686
9687 if (hfinfo->display == BASE_OUI) {
9688 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9689 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) {
9690 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))
9691 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))
9692 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))
;
9693 }
9694 if (hfinfo->strings != NULL((void*)0)) {
9695 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)
9696 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)
9697 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)
;
9698 }
9699 /* It can be a FT_UINT24 with a 0 bitmask, or
9700 * larger with a bitmask with 24 bits set. */
9701 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9702 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)
9703 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)
9704 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)
;
9705 }
9706 wmem_free(NULL((void*)0), tmp_str);
9707 break;
9708 }
9709
9710 /* Require integral types (other than frame number,
9711 * which is always displayed in decimal) to have a
9712 * number base.
9713 *
9714 * If the display value is BASE_NONE and there is a
9715 * strings conversion then the dissector writer is
9716 * telling us that the field's numerical value is
9717 * meaningless; we'll avoid showing the value to the
9718 * user.
9719 */
9720 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9721 case BASE_DEC:
9722 case BASE_HEX:
9723 case BASE_OCT:
9724 case BASE_DEC_HEX:
9725 case BASE_HEX_DEC:
9726 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9727 break;
9728 case BASE_NONE:
9729 if (hfinfo->strings == NULL((void*)0)) {
9730 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
))
9731 " 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
))
9732 " 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
))
9733 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
))
9734 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
))
;
9735 }
9736 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9737 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
))
9738 " 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
))
9739 " 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
))
9740 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
))
9741 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
))
;
9742 }
9743 break;
9744
9745 default:
9746 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9747 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)
9748 " 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)
9749 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)
9750 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)
;
9751 //wmem_free(NULL, tmp_str);
9752 }
9753 break;
9754 case FT_BYTES:
9755 case FT_UINT_BYTES:
9756 /* Require bytes to have a "display type" that could
9757 * add a character between displayed bytes.
9758 */
9759 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9760 case BASE_NONE:
9761 case SEP_DOT:
9762 case SEP_DASH:
9763 case SEP_COLON:
9764 case SEP_SPACE:
9765 break;
9766 default:
9767 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9768 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)
9769 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)
;
9770 //wmem_free(NULL, tmp_str);
9771 }
9772 if (hfinfo->bitmask != 0)
9773 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
))
9774 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
))
9775 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
))
;
9776 //allowed to support string if its a protocol (for pinos)
9777 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9778 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
))
9779 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
))
9780 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
))
;
9781 break;
9782
9783 case FT_PROTOCOL:
9784 case FT_FRAMENUM:
9785 if (hfinfo->display != BASE_NONE) {
9786 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9787 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)
9788 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)
9789 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)
;
9790 //wmem_free(NULL, tmp_str);
9791 }
9792 if (hfinfo->bitmask != 0)
9793 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
))
9794 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
))
9795 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
))
;
9796 break;
9797
9798 case FT_BOOLEAN:
9799 break;
9800
9801 case FT_ABSOLUTE_TIME:
9802 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9803 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9804 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)
9805 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)
;
9806 //wmem_free(NULL, tmp_str);
9807 }
9808 if (hfinfo->bitmask != 0)
9809 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
))
9810 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
))
9811 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
))
;
9812 break;
9813
9814 case FT_STRING:
9815 case FT_STRINGZ:
9816 case FT_UINT_STRING:
9817 case FT_STRINGZPAD:
9818 case FT_STRINGZTRUNC:
9819 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9820 case BASE_NONE:
9821 case BASE_STR_WSP:
9822 break;
9823
9824 default:
9825 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9826 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)
9827 " 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)
9828 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)
9829 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)
;
9830 //wmem_free(NULL, tmp_str);
9831 }
9832
9833 if (hfinfo->bitmask != 0)
9834 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
))
9835 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
))
9836 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
))
;
9837 if (hfinfo->strings != NULL((void*)0))
9838 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
))
9839 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
))
9840 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
))
;
9841 break;
9842
9843 case FT_IPv4:
9844 switch (hfinfo->display) {
9845 case BASE_NONE:
9846 case BASE_NETMASK:
9847 break;
9848
9849 default:
9850 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9851 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)
9852 " 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)
9853 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)
9854 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)
;
9855 //wmem_free(NULL, tmp_str);
9856 break;
9857 }
9858 break;
9859 case FT_FLOAT:
9860 case FT_DOUBLE:
9861 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9862 case BASE_NONE:
9863 case BASE_DEC:
9864 case BASE_HEX:
9865 case BASE_EXP:
9866 case BASE_CUSTOM:
9867 break;
9868 default:
9869 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9870 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)
9871 " 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)
9872 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)
9873 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)
;
9874 //wmem_free(NULL, tmp_str);
9875 }
9876 if (hfinfo->bitmask != 0)
9877 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
))
9878 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
))
9879 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
))
;
9880 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9881 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
))
9882 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
))
9883 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
))
;
9884 break;
9885 case FT_IEEE_11073_SFLOAT:
9886 case FT_IEEE_11073_FLOAT:
9887 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9888 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9889 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)
9890 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)
9891 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)
9892 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)
;
9893 //wmem_free(NULL, tmp_str);
9894 }
9895 if (hfinfo->bitmask != 0)
9896 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
))
9897 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
))
9898 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
))
;
9899 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9900 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
))
9901 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
))
9902 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
))
;
9903 break;
9904 default:
9905 if (hfinfo->display != BASE_NONE) {
9906 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9907 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)
9908 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)
9909 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)
9910 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)
;
9911 //wmem_free(NULL, tmp_str);
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}
9924
9925static void
9926register_type_length_mismatch(void)
9927{
9928 static ei_register_info ei[] = {
9929 { &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)}}
}},
9930 { &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)}}
}},
9931 };
9932
9933 expert_module_t* expert_type_length_mismatch;
9934
9935 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9936
9937 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9938 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9939
9940 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9941 disabling them makes no sense. */
9942 proto_set_cant_toggle(proto_type_length_mismatch);
9943}
9944
9945static void
9946register_byte_array_string_decodinws_error(void)
9947{
9948 static ei_register_info ei[] = {
9949 { &ei_byte_array_string_decoding_failed_error,
9950 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9951 "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)}}
9952 }
9953 },
9954 };
9955
9956 expert_module_t* expert_byte_array_string_decoding_error;
9957
9958 proto_byte_array_string_decoding_error =
9959 proto_register_protocol("Byte Array-String Decoding Error",
9960 "Byte Array-string decoding error",
9961 "_ws.byte_array_string.decoding_error");
9962
9963 expert_byte_array_string_decoding_error =
9964 expert_register_protocol(proto_byte_array_string_decoding_error);
9965 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9966
9967 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9968 disabling them makes no sense. */
9969 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9970}
9971
9972static void
9973register_date_time_string_decodinws_error(void)
9974{
9975 static ei_register_info ei[] = {
9976 { &ei_date_time_string_decoding_failed_error,
9977 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9978 "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)}}
9979 }
9980 },
9981 };
9982
9983 expert_module_t* expert_date_time_string_decoding_error;
9984
9985 proto_date_time_string_decoding_error =
9986 proto_register_protocol("Date and Time-String Decoding Error",
9987 "Date and Time-string decoding error",
9988 "_ws.date_time_string.decoding_error");
9989
9990 expert_date_time_string_decoding_error =
9991 expert_register_protocol(proto_date_time_string_decoding_error);
9992 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9993
9994 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9995 disabling them makes no sense. */
9996 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9997}
9998
9999static void
10000register_string_errors(void)
10001{
10002 static ei_register_info ei[] = {
10003 { &ei_string_trailing_characters,
10004 { "_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)}}
}
10005 },
10006 };
10007
10008 expert_module_t* expert_string_errors;
10009
10010 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10011
10012 expert_string_errors = expert_register_protocol(proto_string_errors);
10013 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10014
10015 /* "String Errors" isn't really a protocol, it's an error indication;
10016 disabling them makes no sense. */
10017 proto_set_cant_toggle(proto_string_errors);
10018}
10019
10020static int
10021proto_register_field_init(header_field_info *hfinfo, const int parent)
10022{
10023
10024 tmp_fld_check_assert(hfinfo);
10025
10026 hfinfo->parent = parent;
10027 hfinfo->same_name_next = NULL((void*)0);
10028 hfinfo->same_name_prev_id = -1;
10029
10030 /* if we always add and never delete, then id == len - 1 is correct */
10031 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10032 if (!gpa_hfinfo.hfi) {
10033 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10034 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10035 /* The entry with index 0 is not used. */
10036 gpa_hfinfo.hfi[0] = NULL((void*)0);
10037 gpa_hfinfo.len = 1;
10038 } else {
10039 gpa_hfinfo.allocated_len += 1000;
10040 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10041 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10042 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10043 }
10044 }
10045 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10046 gpa_hfinfo.len++;
10047 hfinfo->id = gpa_hfinfo.len - 1;
10048
10049 /* if we have real names, enter this field in the name tree */
10050 /* Already checked in tmp_fld_check_assert */
10051 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10052 {
10053
10054 header_field_info *same_name_next_hfinfo;
10055
10056 /* We allow multiple hfinfo's to be registered under the same
10057 * abbreviation. This was done for X.25, as, depending
10058 * on whether it's modulo-8 or modulo-128 operation,
10059 * some bitfield fields may be in different bits of
10060 * a byte, and we want to be able to refer to that field
10061 * with one name regardless of whether the packets
10062 * are modulo-8 or modulo-128 packets. */
10063
10064 /* wmem_map_insert - if key is already present the previous
10065 * hfinfo with the same key/name is returned, otherwise NULL */
10066 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10067 if (same_name_hfinfo) {
10068 /* There's already a field with this name.
10069 * Put the current field *before* that field
10070 * in the list of fields with this name, Thus,
10071 * we end up with an effectively
10072 * doubly-linked-list of same-named hfinfo's,
10073 * with the head of the list (stored in the
10074 * hash) being the last seen hfinfo.
10075 */
10076 same_name_next_hfinfo =
10077 same_name_hfinfo->same_name_next;
10078
10079 hfinfo->same_name_next = same_name_next_hfinfo;
10080 if (same_name_next_hfinfo)
10081 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10082
10083 same_name_hfinfo->same_name_next = hfinfo;
10084 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10085#ifdef ENABLE_CHECK_FILTER
10086 while (same_name_hfinfo) {
10087 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10088 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", 10088
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10089 same_name_hfinfo = same_name_hfinfo->same_name_next;
10090 }
10091#endif
10092 }
10093 }
10094
10095 return hfinfo->id;
10096}
10097
10098void
10099proto_register_subtree_array(int * const *indices, const int num_indices)
10100{
10101 int i;
10102 int *const *ptr = indices;
10103
10104 /*
10105 * If we've already allocated the array of tree types, expand
10106 * it; this lets plugins such as mate add tree types after
10107 * the initial startup. (If we haven't already allocated it,
10108 * we don't allocate it; on the first pass, we just assign
10109 * ett values and keep track of how many we've assigned, and
10110 * when we're finished registering all dissectors we allocate
10111 * the array, so that we do only one allocation rather than
10112 * wasting CPU time and memory by growing the array for each
10113 * dissector that registers ett values.)
10114 */
10115 if (tree_is_expanded != NULL((void*)0)) {
10116 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10117
10118 /* set new items to 0 */
10119 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10120 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10121 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10122 }
10123
10124 /*
10125 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10126 * returning the indices through the pointers in the array whose
10127 * first element is pointed to by "indices", and update
10128 * "num_tree_types" appropriately.
10129 */
10130 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10131 if (**ptr != -1 && **ptr != 0) {
10132 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.")
10133 " 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.")
10134 " 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.")
10135 " 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.")
;
10136 }
10137 **ptr = num_tree_types;
10138 }
10139}
10140
10141static void
10142mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10143{
10144 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10145 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10146 char *last_char;
10147
10148 /* ..... field_name: dataaaaaaaaaaaaa
10149 * |
10150 * ^^^^^ name_pos
10151 *
10152 * ..... field_name […]: dataaaaaaaaaaaaa
10153 *
10154 * name_pos==0 means that we have only data or only a field_name
10155 */
10156
10157 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10157, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10158
10159 if (name_pos >= size - trunc_len) {
10160 /* No room for trunc_str after the field_name, put it first. */
10161 name_pos = 0;
10162 }
10163
10164 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10165 if (name_pos == 0) {
10166 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10167 memcpy(label_str, trunc_str + 1, trunc_len);
10168 } else {
10169 memcpy(label_str + name_pos, trunc_str, trunc_len);
10170 }
10171 /* in general, label_str is UTF-8
10172 we can truncate it only at the beginning of a new character
10173 we go backwards from the byte right after our buffer and
10174 find the next starting byte of a UTF-8 character, this is
10175 where we cut
10176 there's no need to use g_utf8_find_prev_char(), the search
10177 will always succeed since we copied trunc_str into the
10178 buffer */
10179 /* g_utf8_prev_char does not deference the memory address
10180 * passed in (until after decrementing it, so it is perfectly
10181 * legal to pass in a pointer one past the last element.
10182 */
10183 last_char = g_utf8_prev_char(label_str + size);
10184 *last_char = '\0';
10185 /* This is unnecessary (above always terminates), but try to
10186 * convince Coverity to avoid dozens of false positives. */
10187 label_str[size - 1] = '\0';
10188
10189 if (value_pos && *value_pos > 0) {
10190 if (name_pos == 0) {
10191 *value_pos += trunc_len;
10192 } else {
10193 /* Move one back to include trunc_str in the value. */
10194 *value_pos -= 1;
10195 }
10196 }
10197
10198 /* Check if value_pos is past label_str. */
10199 if (value_pos && *value_pos >= size) {
10200 *value_pos = size - 1;
10201 }
10202}
10203
10204static void
10205label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10206{
10207 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10208}
10209
10210static size_t
10211label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10212{
10213 size_t name_pos;
10214
10215 /* "%s: %s", hfinfo->name, text */
10216 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)
;
10217 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10218 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10219 if (value_pos) {
10220 *value_pos = pos;
10221 }
10222 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10223 }
10224
10225 if (pos >= ITEM_LABEL_LENGTH240) {
10226 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10227 label_mark_truncated(label_str, name_pos, value_pos);
10228 }
10229
10230 return pos;
10231}
10232
10233static size_t
10234label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10235{
10236 size_t name_pos;
10237
10238 /* "%s: %s (%s)", hfinfo->name, text, descr */
10239 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)
;
10240 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10241 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10242 if (value_pos) {
10243 *value_pos = pos;
10244 }
10245 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10246 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)
;
10247 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)
;
10248 } else {
10249 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)
;
10250 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10251 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)
;
10252 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10253 }
10254 }
10255
10256 if (pos >= ITEM_LABEL_LENGTH240) {
10257 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10258 label_mark_truncated(label_str, name_pos, value_pos);
10259 }
10260
10261 return pos;
10262}
10263
10264void
10265proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10266{
10267 const header_field_info *hfinfo;
10268 const char *str;
10269 const uint8_t *bytes;
10270 uint32_t integer;
10271 const ipv4_addr_and_mask *ipv4;
10272 const ipv6_addr_and_prefix *ipv6;
10273 const e_guid_t *guid;
10274 char *name;
10275 address addr;
10276 char *addr_str;
10277 char *tmp;
10278
10279 if (!label_str) {
10280 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10280, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10281 return;
10282 }
10283
10284 label_str[0]= '\0';
10285
10286 if (!fi) {
10287 return;
10288 }
10289
10290 hfinfo = fi->hfinfo;
10291
10292 switch (hfinfo->type) {
10293 case FT_NONE:
10294 case FT_PROTOCOL:
10295 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10296 if (value_pos) {
10297 *value_pos = strlen(hfinfo->name);
10298 }
10299 break;
10300
10301 case FT_BOOLEAN:
10302 fill_label_boolean(fi, label_str, value_pos);
10303 break;
10304
10305 case FT_BYTES:
10306 case FT_UINT_BYTES:
10307 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10308 fvalue_get_bytes_data(fi->value),
10309 (unsigned)fvalue_length2(fi->value));
10310 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10311 wmem_free(NULL((void*)0), tmp);
10312 break;
10313
10314 case FT_CHAR:
10315 if (hfinfo->bitmask) {
10316 fill_label_bitfield_char(fi, label_str, value_pos);
10317 } else {
10318 fill_label_char(fi, label_str, value_pos);
10319 }
10320 break;
10321
10322 /* Four types of integers to take care of:
10323 * Bitfield, with val_string
10324 * Bitfield, w/o val_string
10325 * Non-bitfield, with val_string
10326 * Non-bitfield, w/o val_string
10327 */
10328 case FT_UINT8:
10329 case FT_UINT16:
10330 case FT_UINT24:
10331 case FT_UINT32:
10332 if (hfinfo->bitmask) {
10333 fill_label_bitfield(fi, label_str, value_pos, false0);
10334 } else {
10335 fill_label_number(fi, label_str, value_pos, false0);
10336 }
10337 break;
10338
10339 case FT_FRAMENUM:
10340 fill_label_number(fi, label_str, value_pos, false0);
10341 break;
10342
10343 case FT_UINT40:
10344 case FT_UINT48:
10345 case FT_UINT56:
10346 case FT_UINT64:
10347 if (hfinfo->bitmask) {
10348 fill_label_bitfield64(fi, label_str, value_pos, false0);
10349 } else {
10350 fill_label_number64(fi, label_str, value_pos, false0);
10351 }
10352 break;
10353
10354 case FT_INT8:
10355 case FT_INT16:
10356 case FT_INT24:
10357 case FT_INT32:
10358 if (hfinfo->bitmask) {
10359 fill_label_bitfield(fi, label_str, value_pos, true1);
10360 } else {
10361 fill_label_number(fi, label_str, value_pos, true1);
10362 }
10363 break;
10364
10365 case FT_INT40:
10366 case FT_INT48:
10367 case FT_INT56:
10368 case FT_INT64:
10369 if (hfinfo->bitmask) {
10370 fill_label_bitfield64(fi, label_str, value_pos, true1);
10371 } else {
10372 fill_label_number64(fi, label_str, value_pos, true1);
10373 }
10374 break;
10375
10376 case FT_FLOAT:
10377 case FT_DOUBLE:
10378 fill_label_float(fi, label_str, value_pos);
10379 break;
10380
10381 case FT_ABSOLUTE_TIME:
10382 {
10383 const nstime_t *value = fvalue_get_time(fi->value);
10384 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10385 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10386 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10387 }
10388 if (hfinfo->strings) {
10389 /*
10390 * Table of time valus to be displayed
10391 * specially.
10392 */
10393 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10394 if (time_string != NULL((void*)0)) {
10395 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10396 break;
10397 }
10398 }
10399 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10400 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10401 wmem_free(NULL((void*)0), tmp);
10402 break;
10403 }
10404 case FT_RELATIVE_TIME:
10405 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10406 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10407 wmem_free(NULL((void*)0), tmp);
10408 break;
10409
10410 case FT_IPXNET:
10411 integer = fvalue_get_uinteger(fi->value);
10412 tmp = get_ipxnet_name(NULL((void*)0), integer);
10413 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10414 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10415 wmem_free(NULL((void*)0), tmp);
10416 wmem_free(NULL((void*)0), addr_str);
10417 break;
10418
10419 case FT_VINES:
10420 addr.type = AT_VINES;
10421 addr.len = VINES_ADDR_LEN6;
10422 addr.data = fvalue_get_bytes_data(fi->value);
10423
10424 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10425 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10426 wmem_free(NULL((void*)0), addr_str);
10427 break;
10428
10429 case FT_ETHER:
10430 bytes = fvalue_get_bytes_data(fi->value);
10431
10432 addr.type = AT_ETHER;
10433 addr.len = 6;
10434 addr.data = bytes;
10435
10436 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10437 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10438 wmem_free(NULL((void*)0), addr_str);
10439 break;
10440
10441 case FT_IPv4:
10442 ipv4 = fvalue_get_ipv4(fi->value);
10443 set_address_ipv4(&addr, ipv4);
10444
10445 if (hfinfo->display == BASE_NETMASK) {
10446 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10447 } else {
10448 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10449 }
10450 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10451 wmem_free(NULL((void*)0), addr_str);
10452 free_address(&addr);
10453 break;
10454
10455 case FT_IPv6:
10456 ipv6 = fvalue_get_ipv6(fi->value);
10457 set_address_ipv6(&addr, ipv6);
10458
10459 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10460 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10461 wmem_free(NULL((void*)0), addr_str);
10462 free_address(&addr);
10463 break;
10464
10465 case FT_FCWWN:
10466 bytes = fvalue_get_bytes_data(fi->value);
10467 addr.type = AT_FCWWN;
10468 addr.len = FCWWN_ADDR_LEN8;
10469 addr.data = bytes;
10470
10471 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10472 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10473 wmem_free(NULL((void*)0), addr_str);
10474 break;
10475
10476 case FT_GUID:
10477 guid = fvalue_get_guid(fi->value);
10478 tmp = guid_to_str(NULL((void*)0), guid);
10479 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10480 wmem_free(NULL((void*)0), tmp);
10481 break;
10482
10483 case FT_OID:
10484 bytes = fvalue_get_bytes_data(fi->value);
10485 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10486 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10487 if (name) {
10488 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10489 wmem_free(NULL((void*)0), name);
10490 } else {
10491 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10492 }
10493 wmem_free(NULL((void*)0), tmp);
10494 break;
10495
10496 case FT_REL_OID:
10497 bytes = fvalue_get_bytes_data(fi->value);
10498 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10499 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10500 if (name) {
10501 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10502 wmem_free(NULL((void*)0), name);
10503 } else {
10504 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10505 }
10506 wmem_free(NULL((void*)0), tmp);
10507 break;
10508
10509 case FT_SYSTEM_ID:
10510 bytes = fvalue_get_bytes_data(fi->value);
10511 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10512 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10513 wmem_free(NULL((void*)0), tmp);
10514 break;
10515
10516 case FT_EUI64:
10517 bytes = fvalue_get_bytes_data(fi->value);
10518 addr.type = AT_EUI64;
10519 addr.len = EUI64_ADDR_LEN8;
10520 addr.data = bytes;
10521
10522 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10523 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10524 wmem_free(NULL((void*)0), addr_str);
10525 break;
10526 case FT_STRING:
10527 case FT_STRINGZ:
10528 case FT_UINT_STRING:
10529 case FT_STRINGZPAD:
10530 case FT_STRINGZTRUNC:
10531 case FT_AX25:
10532 str = fvalue_get_string(fi->value);
10533 label_fill(label_str, 0, hfinfo, str, value_pos);
10534 break;
10535
10536 case FT_IEEE_11073_SFLOAT:
10537 case FT_IEEE_11073_FLOAT:
10538 fill_label_ieee_11073_float(fi, label_str, value_pos);
10539 break;
10540
10541 default:
10542 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
))
10543 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
))
10544 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
))
10545 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
))
;
10546 break;
10547 }
10548}
10549
10550static void
10551fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10552{
10553 char *p;
10554 int bitfield_byte_length = 0, bitwidth;
10555 uint64_t unshifted_value;
10556 uint64_t value;
10557
10558 const header_field_info *hfinfo = fi->hfinfo;
10559
10560 value = fvalue_get_uinteger64(fi->value);
10561 if (hfinfo->bitmask) {
10562 /* Figure out the bit width */
10563 bitwidth = hfinfo_container_bitwidth(hfinfo);
10564
10565 /* Un-shift bits */
10566 unshifted_value = value;
10567 unshifted_value <<= hfinfo_bitshift(hfinfo);
10568
10569 /* Create the bitfield first */
10570 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10571 bitfield_byte_length = (int) (p - label_str);
10572 }
10573
10574 /* Fill in the textual info */
10575 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10576}
10577
10578static const char *
10579hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10580{
10581 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10582 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10583
10584 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10585 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10586 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10587 else
10588 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10589 }
10590
10591 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10592 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10593
10594 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10595 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10596
10597 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10598}
10599
10600static const char *
10601hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10602{
10603 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10604 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10605 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10606 else
10607 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10608 }
10609
10610 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10611 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10612
10613 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10614 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10615
10616 /* If this is reached somebody registered a 64-bit field with a 32-bit
10617 * value-string, which isn't right. */
10618 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)
10619 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10620
10621 /* This is necessary to squelch MSVC errors; is there
10622 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10623 never returns? */
10624 return NULL((void*)0);
10625}
10626
10627static const char *
10628hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10629{
10630 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10631 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10632
10633 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)
;
10634
10635 /* This is necessary to squelch MSVC errors; is there
10636 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10637 never returns? */
10638 return NULL((void*)0);
10639}
10640
10641static const char *
10642hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10643{
10644 const char *str = hf_try_val_to_str(value, hfinfo);
10645
10646 return (str) ? str : unknown_str;
10647}
10648
10649static const char *
10650hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10651{
10652 const char *str = hf_try_val64_to_str(value, hfinfo);
10653
10654 return (str) ? str : unknown_str;
10655}
10656
10657/* Fills data for bitfield chars with val_strings */
10658static void
10659fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10660{
10661 char *p;
10662 int bitfield_byte_length, bitwidth;
10663 uint32_t unshifted_value;
10664 uint32_t value;
10665
10666 char buf[32];
10667 const char *out;
10668
10669 const header_field_info *hfinfo = fi->hfinfo;
10670
10671 /* Figure out the bit width */
10672 bitwidth = hfinfo_container_bitwidth(hfinfo);
10673
10674 /* Un-shift bits */
10675 value = fvalue_get_uinteger(fi->value);
10676
10677 unshifted_value = value;
10678 if (hfinfo->bitmask) {
10679 unshifted_value <<= hfinfo_bitshift(hfinfo);
10680 }
10681
10682 /* Create the bitfield first */
10683 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10684 bitfield_byte_length = (int) (p - label_str);
10685
10686 /* Fill in the textual info using stored (shifted) value */
10687 if (hfinfo->display == BASE_CUSTOM) {
10688 char tmp[ITEM_LABEL_LENGTH240];
10689 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10690
10691 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10691, "fmtfunc"))))
;
10692 fmtfunc(tmp, value);
10693 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10694 }
10695 else if (hfinfo->strings) {
10696 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10697
10698 out = hfinfo_char_vals_format(hfinfo, buf, value);
10699 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10700 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10701 else
10702 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10703 }
10704 else {
10705 out = hfinfo_char_value_format(hfinfo, buf, value);
10706
10707 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10708 }
10709}
10710
10711/* Fills data for bitfield ints with val_strings */
10712static void
10713fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10714{
10715 char *p;
10716 int bitfield_byte_length, bitwidth;
10717 uint32_t value, unshifted_value;
10718 char buf[NUMBER_LABEL_LENGTH80];
10719 const char *out;
10720
10721 const header_field_info *hfinfo = fi->hfinfo;
10722
10723 /* Figure out the bit width */
10724 if (fi->flags & FI_VARINT0x00040000)
10725 bitwidth = fi->length*8;
10726 else
10727 bitwidth = hfinfo_container_bitwidth(hfinfo);
10728
10729 /* Un-shift bits */
10730 if (is_signed)
10731 value = fvalue_get_sinteger(fi->value);
10732 else
10733 value = fvalue_get_uinteger(fi->value);
10734
10735 unshifted_value = value;
10736 if (hfinfo->bitmask) {
10737 unshifted_value <<= hfinfo_bitshift(hfinfo);
10738 }
10739
10740 /* Create the bitfield first */
10741 if (fi->flags & FI_VARINT0x00040000)
10742 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10743 else
10744 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10745 bitfield_byte_length = (int) (p - label_str);
10746
10747 /* Fill in the textual info using stored (shifted) value */
10748 if (hfinfo->display == BASE_CUSTOM) {
10749 char tmp[ITEM_LABEL_LENGTH240];
10750 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10751
10752 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10752, "fmtfunc"))))
;
10753 fmtfunc(tmp, value);
10754 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10755 }
10756 else if (hfinfo->strings) {
10757 const char *val_str = hf_try_val_to_str(value, hfinfo);
10758
10759 out = hfinfo_number_vals_format(hfinfo, buf, value);
10760 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10761 /*
10762 * Unique values only display value_string string
10763 * if there is a match. Otherwise it's just a number
10764 */
10765 if (val_str) {
10766 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10767 } else {
10768 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10769 }
10770 } else {
10771 if (val_str == NULL((void*)0))
10772 val_str = "Unknown";
10773
10774 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10775 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10776 else
10777 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10778 }
10779 }
10780 else {
10781 out = hfinfo_number_value_format(hfinfo, buf, value);
10782
10783 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10784 }
10785}
10786
10787static void
10788fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10789{
10790 char *p;
10791 int bitfield_byte_length, bitwidth;
10792 uint64_t value, unshifted_value;
10793 char buf[NUMBER_LABEL_LENGTH80];
10794 const char *out;
10795
10796 const header_field_info *hfinfo = fi->hfinfo;
10797
10798 /* Figure out the bit width */
10799 if (fi->flags & FI_VARINT0x00040000)
10800 bitwidth = fi->length*8;
10801 else
10802 bitwidth = hfinfo_container_bitwidth(hfinfo);
10803
10804 /* Un-shift bits */
10805 if (is_signed)
10806 value = fvalue_get_sinteger64(fi->value);
10807 else
10808 value = fvalue_get_uinteger64(fi->value);
10809
10810 unshifted_value = value;
10811 if (hfinfo->bitmask) {
10812 unshifted_value <<= hfinfo_bitshift(hfinfo);
10813 }
10814
10815 /* Create the bitfield first */
10816 if (fi->flags & FI_VARINT0x00040000)
10817 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10818 else
10819 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10820 bitfield_byte_length = (int) (p - label_str);
10821
10822 /* Fill in the textual info using stored (shifted) value */
10823 if (hfinfo->display == BASE_CUSTOM) {
10824 char tmp[ITEM_LABEL_LENGTH240];
10825 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10826
10827 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10827, "fmtfunc64"
))))
;
10828 fmtfunc64(tmp, value);
10829 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10830 }
10831 else if (hfinfo->strings) {
10832 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10833
10834 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10835 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10836 /*
10837 * Unique values only display value_string string
10838 * if there is a match. Otherwise it's just a number
10839 */
10840 if (val_str) {
10841 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10842 } else {
10843 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10844 }
10845 } else {
10846 if (val_str == NULL((void*)0))
10847 val_str = "Unknown";
10848
10849 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10850 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10851 else
10852 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10853 }
10854 }
10855 else {
10856 out = hfinfo_number_value_format64(hfinfo, buf, value);
10857
10858 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10859 }
10860}
10861
10862static void
10863fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10864{
10865 const header_field_info *hfinfo = fi->hfinfo;
10866 uint32_t value;
10867
10868 char buf[32];
10869 const char *out;
10870
10871 value = fvalue_get_uinteger(fi->value);
10872
10873 /* Fill in the textual info */
10874 if (hfinfo->display == BASE_CUSTOM) {
10875 char tmp[ITEM_LABEL_LENGTH240];
10876 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10877
10878 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10878, "fmtfunc"))))
;
10879 fmtfunc(tmp, value);
10880 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10881 }
10882 else if (hfinfo->strings) {
10883 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10884
10885 out = hfinfo_char_vals_format(hfinfo, buf, value);
10886 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10887 }
10888 else {
10889 out = hfinfo_char_value_format(hfinfo, buf, value);
10890
10891 label_fill(label_str, 0, hfinfo, out, value_pos);
10892 }
10893}
10894
10895static void
10896fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10897{
10898 const header_field_info *hfinfo = fi->hfinfo;
10899 uint32_t value;
10900
10901 char buf[NUMBER_LABEL_LENGTH80];
10902 const char *out;
10903
10904 if (is_signed)
10905 value = fvalue_get_sinteger(fi->value);
10906 else
10907 value = fvalue_get_uinteger(fi->value);
10908
10909 /* Fill in the textual info */
10910 if (hfinfo->display == BASE_CUSTOM) {
10911 char tmp[ITEM_LABEL_LENGTH240];
10912 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10913
10914 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10914, "fmtfunc"))))
;
10915 fmtfunc(tmp, value);
10916 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10917 }
10918 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10919 /*
10920 * It makes no sense to have a value-string table for a
10921 * frame-number field - they're just integers giving
10922 * the ordinal frame number.
10923 */
10924 const char *val_str = hf_try_val_to_str(value, hfinfo);
10925
10926 out = hfinfo_number_vals_format(hfinfo, buf, value);
10927 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10928 /*
10929 * Unique values only display value_string string
10930 * if there is a match. Otherwise it's just a number
10931 */
10932 if (val_str) {
10933 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10934 } else {
10935 label_fill(label_str, 0, hfinfo, out, value_pos);
10936 }
10937 } else {
10938 if (val_str == NULL((void*)0))
10939 val_str = "Unknown";
10940
10941 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10942 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10943 else
10944 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10945 }
10946 }
10947 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
))
) {
10948 char tmp[ITEM_LABEL_LENGTH240];
10949
10950 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10951 display_to_port_type((field_display_e)hfinfo->display), value);
10952 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10953 }
10954 else {
10955 out = hfinfo_number_value_format(hfinfo, buf, value);
10956
10957 label_fill(label_str, 0, hfinfo, out, value_pos);
10958 }
10959}
10960
10961static void
10962fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10963{
10964 const header_field_info *hfinfo = fi->hfinfo;
10965 uint64_t value;
10966
10967 char buf[NUMBER_LABEL_LENGTH80];
10968 const char *out;
10969
10970 if (is_signed)
10971 value = fvalue_get_sinteger64(fi->value);
10972 else
10973 value = fvalue_get_uinteger64(fi->value);
10974
10975 /* Fill in the textual info */
10976 if (hfinfo->display == BASE_CUSTOM) {
10977 char tmp[ITEM_LABEL_LENGTH240];
10978 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10979
10980 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10980, "fmtfunc64"
))))
;
10981 fmtfunc64(tmp, value);
10982 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10983 }
10984 else if (hfinfo->strings) {
10985 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10986
10987 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10988 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10989 /*
10990 * Unique values only display value_string string
10991 * if there is a match. Otherwise it's just a number
10992 */
10993 if (val_str) {
10994 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10995 } else {
10996 label_fill(label_str, 0, hfinfo, out, value_pos);
10997 }
10998 } else {
10999 if (val_str == NULL((void*)0))
11000 val_str = "Unknown";
11001
11002 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11003 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11004 else
11005 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11006 }
11007 }
11008 else {
11009 out = hfinfo_number_value_format64(hfinfo, buf, value);
11010
11011 label_fill(label_str, 0, hfinfo, out, value_pos);
11012 }
11013}
11014
11015static size_t
11016fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11017{
11018 int display;
11019 int n;
11020 double value;
11021
11022 if (label_str_size < 12) {
11023 /* Not enough room to write an entire floating point value. */
11024 return 0;
11025 }
11026
11027 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11028 value = fvalue_get_floating(fi->value);
11029
11030 if (display == BASE_CUSTOM) {
11031 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11032 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11032, "fmtfunc"))))
;
11033 fmtfunc(label_str, value);
11034 return strlen(label_str);
11035 }
11036
11037 switch (display) {
11038 case BASE_NONE:
11039 if (fi->hfinfo->type == FT_FLOAT) {
11040 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11041 } else {
11042 n = (int)strlen(dtoa_g_fmt(label_str, value));
11043 }
11044 break;
11045 case BASE_DEC:
11046 n = snprintf(label_str, label_str_size, "%f", value);
11047 break;
11048 case BASE_HEX:
11049 n = snprintf(label_str, label_str_size, "%a", value);
11050 break;
11051 case BASE_EXP:
11052 n = snprintf(label_str, label_str_size, "%e", value);
11053 break;
11054 default:
11055 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11055
, __func__, "assertion \"not reached\" failed")
;
11056 }
11057 if (n < 0) {
11058 return 0; /* error */
11059 }
11060 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11061 const char *hf_str_val;
11062 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11063 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11064 }
11065 if (n > label_str_size) {
11066 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11066, __func__, "label length too small"); } } while (0)
;
11067 return strlen(label_str);
11068 }
11069
11070 return n;
11071}
11072
11073void
11074fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11075{
11076 char tmp[ITEM_LABEL_LENGTH240];
11077
11078 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11079 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11080}
11081
11082static size_t
11083fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11084{
11085 int display;
11086 size_t pos = 0;
11087 double value;
11088 char* tmp_str;
11089
11090 if (label_str_size < 12) {
11091 /* Not enough room to write an entire floating point value. */
11092 return 0;
11093 }
11094
11095 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11096 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11097 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11098 wmem_free(NULL((void*)0), tmp_str);
11099
11100 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11101 const char *hf_str_val;
11102 fvalue_to_double(fi->value, &value);
11103 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11104 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)
;
11105 }
11106 if ((int)pos > label_str_size) {
11107 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11107, __func__, "label length too small"); } } while (0)
;
11108 return strlen(label_str);
11109 }
11110
11111 return pos;
11112}
11113
11114void
11115fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11116{
11117 char tmp[ITEM_LABEL_LENGTH240];
11118
11119 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11120 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11121}
11122
11123int
11124hfinfo_bitshift(const header_field_info *hfinfo)
11125{
11126 return ws_ctz(hfinfo->bitmask);
11127}
11128
11129
11130static int
11131hfinfo_bitoffset(const header_field_info *hfinfo)
11132{
11133 if (!hfinfo->bitmask) {
11134 return 0;
11135 }
11136
11137 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11138 * as the first bit */
11139 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11140}
11141
11142static int
11143hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11144{
11145 if (!hfinfo->bitmask) {
11146 return 0;
11147 }
11148
11149 /* ilog2 = first set bit, ctz = last set bit */
11150 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11151}
11152
11153static int
11154hfinfo_type_bitwidth(enum ftenum type)
11155{
11156 int bitwidth = 0;
11157
11158 switch (type) {
11159 case FT_CHAR:
11160 case FT_UINT8:
11161 case FT_INT8:
11162 bitwidth = 8;
11163 break;
11164 case FT_UINT16:
11165 case FT_INT16:
11166 bitwidth = 16;
11167 break;
11168 case FT_UINT24:
11169 case FT_INT24:
11170 bitwidth = 24;
11171 break;
11172 case FT_UINT32:
11173 case FT_INT32:
11174 bitwidth = 32;
11175 break;
11176 case FT_UINT40:
11177 case FT_INT40:
11178 bitwidth = 40;
11179 break;
11180 case FT_UINT48:
11181 case FT_INT48:
11182 bitwidth = 48;
11183 break;
11184 case FT_UINT56:
11185 case FT_INT56:
11186 bitwidth = 56;
11187 break;
11188 case FT_UINT64:
11189 case FT_INT64:
11190 bitwidth = 64;
11191 break;
11192 default:
11193 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11193))
;
11194 ;
11195 }
11196 return bitwidth;
11197}
11198
11199
11200static int
11201hfinfo_container_bitwidth(const header_field_info *hfinfo)
11202{
11203 if (!hfinfo->bitmask) {
11204 return 0;
11205 }
11206
11207 if (hfinfo->type == FT_BOOLEAN) {
11208 return hfinfo->display; /* hacky? :) */
11209 }
11210
11211 return hfinfo_type_bitwidth(hfinfo->type);
11212}
11213
11214static int
11215hfinfo_hex_digits(const header_field_info *hfinfo)
11216{
11217 int bitwidth;
11218
11219 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11220 * appropriate to determine the number of hex digits for the field.
11221 * So instead, we compute it from the bitmask.
11222 */
11223 if (hfinfo->bitmask != 0) {
11224 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11225 } else {
11226 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11227 }
11228
11229 /* Divide by 4, rounding up, to get number of hex digits. */
11230 return (bitwidth + 3) / 4;
11231}
11232
11233const char *
11234hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11235{
11236 char *ptr = &buf[6];
11237 static const char hex_digits[16] =
11238 { '0', '1', '2', '3', '4', '5', '6', '7',
11239 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11240
11241 *ptr = '\0';
11242 *(--ptr) = '\'';
11243 /* Properly format value */
11244 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11245 /*
11246 * Printable, so just show the character, and, if it needs
11247 * to be escaped, escape it.
11248 */
11249 *(--ptr) = value;
11250 if (value == '\\' || value == '\'')
11251 *(--ptr) = '\\';
11252 } else {
11253 /*
11254 * Non-printable; show it as an escape sequence.
11255 */
11256 switch (value) {
11257
11258 case '\0':
11259 /*
11260 * Show a NUL with only one digit.
11261 */
11262 *(--ptr) = '0';
11263 break;
11264
11265 case '\a':
11266 case '\b':
11267 case '\f':
11268 case '\n':
11269 case '\r':
11270 case '\t':
11271 case '\v':
11272 *(--ptr) = value - '\a' + 'a';
11273 break;
11274
11275 default:
11276 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11277
11278 case BASE_OCT:
11279 *(--ptr) = (value & 0x7) + '0';
11280 value >>= 3;
11281 *(--ptr) = (value & 0x7) + '0';
11282 value >>= 3;
11283 *(--ptr) = (value & 0x7) + '0';
11284 break;
11285
11286 case BASE_HEX:
11287 *(--ptr) = hex_digits[value & 0x0F];
11288 value >>= 4;
11289 *(--ptr) = hex_digits[value & 0x0F];
11290 *(--ptr) = 'x';
11291 break;
11292
11293 default:
11294 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11295 }
11296 }
11297 *(--ptr) = '\\';
11298 }
11299 *(--ptr) = '\'';
11300 return ptr;
11301}
11302
11303static const char *
11304hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11305{
11306 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11307 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
))
;
11308
11309 *ptr = '\0';
11310 /* Properly format value */
11311 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11312 case BASE_DEC:
11313 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11314
11315 case BASE_DEC_HEX:
11316 *(--ptr) = ')';
11317 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11318 *(--ptr) = '(';
11319 *(--ptr) = ' ';
11320 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11321 return ptr;
11322
11323 case BASE_OCT:
11324 return oct_to_str_back(ptr, value);
11325
11326 case BASE_HEX:
11327 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11328
11329 case BASE_HEX_DEC:
11330 *(--ptr) = ')';
11331 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11332 *(--ptr) = '(';
11333 *(--ptr) = ' ';
11334 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11335 return ptr;
11336
11337 case BASE_PT_UDP:
11338 case BASE_PT_TCP:
11339 case BASE_PT_DCCP:
11340 case BASE_PT_SCTP:
11341 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11342 display_to_port_type((field_display_e)display), value);
11343 return buf;
11344 case BASE_OUI:
11345 {
11346 uint8_t p_oui[3];
11347 const char *manuf_name;
11348
11349 p_oui[0] = value >> 16 & 0xFF;
11350 p_oui[1] = value >> 8 & 0xFF;
11351 p_oui[2] = value & 0xFF;
11352
11353 /* Attempt an OUI lookup. */
11354 manuf_name = uint_get_manuf_name_if_known(value);
11355 if (manuf_name == NULL((void*)0)) {
11356 /* Could not find an OUI. */
11357 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11358 }
11359 else {
11360 /* Found an address string. */
11361 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11362 }
11363 return buf;
11364 }
11365
11366 default:
11367 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11368 }
11369 return ptr;
11370}
11371
11372static const char *
11373hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11374{
11375 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11376 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
))
;
11377
11378 *ptr = '\0';
11379 /* Properly format value */
11380 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11381 case BASE_DEC:
11382 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11383
11384 case BASE_DEC_HEX:
11385 *(--ptr) = ')';
11386 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11387 *(--ptr) = '(';
11388 *(--ptr) = ' ';
11389 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11390 return ptr;
11391
11392 case BASE_OCT:
11393 return oct64_to_str_back(ptr, value);
11394
11395 case BASE_HEX:
11396 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11397
11398 case BASE_HEX_DEC:
11399 *(--ptr) = ')';
11400 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11401 *(--ptr) = '(';
11402 *(--ptr) = ' ';
11403 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11404 return ptr;
11405
11406 default:
11407 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11408 }
11409
11410 return ptr;
11411}
11412
11413static const char *
11414hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11415{
11416 int display = hfinfo->display;
11417
11418 if (hfinfo->type == FT_FRAMENUM) {
11419 /*
11420 * Frame numbers are always displayed in decimal.
11421 */
11422 display = BASE_DEC;
11423 }
11424
11425 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11426}
11427
11428static const char *
11429hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11430{
11431 int display = hfinfo->display;
11432
11433 if (hfinfo->type == FT_FRAMENUM) {
11434 /*
11435 * Frame numbers are always displayed in decimal.
11436 */
11437 display = BASE_DEC;
11438 }
11439
11440 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11441}
11442
11443static const char *
11444hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11445{
11446 /* Get the underlying BASE_ value */
11447 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11448
11449 return hfinfo_char_value_format_display(display, buf, value);
11450}
11451
11452static const char *
11453hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11454{
11455 /* Get the underlying BASE_ value */
11456 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11457
11458 if (hfinfo->type == FT_FRAMENUM) {
11459 /*
11460 * Frame numbers are always displayed in decimal.
11461 */
11462 display = BASE_DEC;
11463 }
11464
11465 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11466 display = BASE_DEC;
11467 } else if (display == BASE_OUI) {
11468 display = BASE_HEX;
11469 }
11470
11471 switch (display) {
11472 case BASE_NONE:
11473 /* case BASE_DEC: */
11474 case BASE_DEC_HEX:
11475 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11476 case BASE_CUSTOM:
11477 display = BASE_DEC;
11478 break;
11479
11480 /* case BASE_HEX: */
11481 case BASE_HEX_DEC:
11482 display = BASE_HEX;
11483 break;
11484 }
11485
11486 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11487}
11488
11489static const char *
11490hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11491{
11492 /* Get the underlying BASE_ value */
11493 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11494
11495 if (hfinfo->type == FT_FRAMENUM) {
11496 /*
11497 * Frame numbers are always displayed in decimal.
11498 */
11499 display = BASE_DEC;
11500 }
11501
11502 switch (display) {
11503 case BASE_NONE:
11504 /* case BASE_DEC: */
11505 case BASE_DEC_HEX:
11506 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11507 case BASE_CUSTOM:
11508 display = BASE_DEC;
11509 break;
11510
11511 /* case BASE_HEX: */
11512 case BASE_HEX_DEC:
11513 display = BASE_HEX;
11514 break;
11515 }
11516
11517 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11518}
11519
11520static const char *
11521hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11522{
11523 /* Get the underlying BASE_ value */
11524 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11525
11526 return hfinfo_char_value_format_display(display, buf, value);
11527}
11528
11529static const char *
11530hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11531{
11532 /* Get the underlying BASE_ value */
11533 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11534
11535 if (display == BASE_NONE)
11536 return NULL((void*)0);
11537
11538 if (display == BASE_DEC_HEX)
11539 display = BASE_DEC;
11540 if (display == BASE_HEX_DEC)
11541 display = BASE_HEX;
11542
11543 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11544}
11545
11546static const char *
11547hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11548{
11549 /* Get the underlying BASE_ value */
11550 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11551
11552 if (display == BASE_NONE)
11553 return NULL((void*)0);
11554
11555 if (display == BASE_DEC_HEX)
11556 display = BASE_DEC;
11557 if (display == BASE_HEX_DEC)
11558 display = BASE_HEX;
11559
11560 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11561}
11562
11563const char *
11564proto_registrar_get_name(const int n)
11565{
11566 header_field_info *hfinfo;
11567
11568 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", 11568
, __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", 11568
, "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", 11568, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11569 return hfinfo->name;
11570}
11571
11572const char *
11573proto_registrar_get_abbrev(const int n)
11574{
11575 header_field_info *hfinfo;
11576
11577 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", 11577
, __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", 11577
, "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", 11577, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11578 return hfinfo->abbrev;
11579}
11580
11581enum ftenum
11582proto_registrar_get_ftype(const int n)
11583{
11584 header_field_info *hfinfo;
11585
11586 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", 11586
, __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", 11586
, "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", 11586, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11587 return hfinfo->type;
11588}
11589
11590int
11591proto_registrar_get_parent(const int n)
11592{
11593 header_field_info *hfinfo;
11594
11595 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", 11595
, __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", 11595
, "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", 11595, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11596 return hfinfo->parent;
11597}
11598
11599bool_Bool
11600proto_registrar_is_protocol(const int n)
11601{
11602 header_field_info *hfinfo;
11603
11604 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", 11604
, __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", 11604
, "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", 11604, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11605 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11606}
11607
11608/* Returns length of field in packet (not necessarily the length
11609 * in our internal representation, as in the case of IPv4).
11610 * 0 means undeterminable at time of registration
11611 * -1 means the field is not registered. */
11612int
11613proto_registrar_get_length(const int n)
11614{
11615 header_field_info *hfinfo;
11616
11617 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", 11617
, __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", 11617
, "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", 11617, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11618 return ftype_wire_size(hfinfo->type);
11619}
11620
11621size_t
11622proto_registrar_get_count(struct proto_registrar_stats *stats)
11623{
11624 header_field_info *hfinfo;
11625
11626 // Index zero is not used. We have to skip it.
11627 size_t total_count = gpa_hfinfo.len - 1;
11628 if (stats == NULL((void*)0)) {
11629 return total_count;
11630 }
11631 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11632 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11633 stats->deregistered_count++;
11634 continue; /* This is a deregistered protocol or header field */
11635 }
11636
11637 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", 11637
, __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", 11637, "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", 11637, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11638
11639 if (proto_registrar_is_protocol(id))
11640 stats->protocol_count++;
11641
11642 if (hfinfo->same_name_prev_id != -1)
11643 stats->same_name_count++;
11644 }
11645
11646 return total_count;
11647}
11648
11649/* Looks for a protocol or a field in a proto_tree. Returns true if
11650 * it exists anywhere, or false if it exists nowhere. */
11651bool_Bool
11652proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11653{
11654 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11655
11656 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11657 return true1;
11658 }
11659 else {
11660 return false0;
11661 }
11662}
11663
11664/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11665 * This only works if the hfindex was "primed" before the dissection
11666 * took place, as we just pass back the already-created GPtrArray*.
11667 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11668 * handles that. */
11669GPtrArray *
11670proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11671{
11672 if (!tree)
11673 return NULL((void*)0);
11674
11675 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11676 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11677 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11678 else
11679 return NULL((void*)0);
11680}
11681
11682bool_Bool
11683proto_tracking_interesting_fields(const proto_tree *tree)
11684{
11685 GHashTable *interesting_hfids;
11686
11687 if (!tree)
11688 return false0;
11689
11690 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11691
11692 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11693}
11694
11695/* Helper struct for proto_find_info() and proto_all_finfos() */
11696typedef struct {
11697 GPtrArray *array;
11698 int id;
11699} ffdata_t;
11700
11701/* Helper function for proto_find_info() */
11702static bool_Bool
11703find_finfo(proto_node *node, void * data)
11704{
11705 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11706 if (fi && fi->hfinfo) {
11707 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11708 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11709 }
11710 }
11711
11712 /* Don't stop traversing. */
11713 return false0;
11714}
11715
11716/* Helper function for proto_find_first_info() */
11717static bool_Bool
11718find_first_finfo(proto_node *node, void *data)
11719{
11720 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11721 if (fi && fi->hfinfo) {
11722 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11723 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11724
11725 /* Stop traversing. */
11726 return true1;
11727 }
11728 }
11729
11730 /* Continue traversing. */
11731 return false0;
11732}
11733
11734/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11735* This works on any proto_tree, primed or unprimed, but actually searches
11736* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11737* The caller does need to free the returned GPtrArray with
11738* g_ptr_array_free(<array>, true).
11739*/
11740GPtrArray *
11741proto_find_finfo(proto_tree *tree, const int id)
11742{
11743 ffdata_t ffdata;
11744
11745 ffdata.array = g_ptr_array_new();
11746 ffdata.id = id;
11747
11748 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11749
11750 return ffdata.array;
11751}
11752
11753/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11754* This works on any proto_tree, primed or unprimed, but actually searches
11755* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11756* The caller does need to free the returned GPtrArray with
11757* g_ptr_array_free(<array>, true).
11758*/
11759GPtrArray *
11760proto_find_first_finfo(proto_tree *tree, const int id)
11761{
11762 ffdata_t ffdata;
11763
11764 ffdata.array = g_ptr_array_new();
11765 ffdata.id = id;
11766
11767 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11768
11769 return ffdata.array;
11770}
11771
11772/* Helper function for proto_all_finfos() */
11773static bool_Bool
11774every_finfo(proto_node *node, void * data)
11775{
11776 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11777 if (fi && fi->hfinfo) {
11778 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11779 }
11780
11781 /* Don't stop traversing. */
11782 return false0;
11783}
11784
11785/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11786 * The caller does need to free the returned GPtrArray with
11787 * g_ptr_array_free(<array>, true).
11788 */
11789GPtrArray *
11790proto_all_finfos(proto_tree *tree)
11791{
11792 ffdata_t ffdata;
11793
11794 /* Pre allocate enough space to hold all fields in most cases */
11795 ffdata.array = g_ptr_array_sized_new(512);
11796 ffdata.id = 0;
11797
11798 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11799
11800 return ffdata.array;
11801}
11802
11803
11804typedef struct {
11805 unsigned offset;
11806 field_info *finfo;
11807 tvbuff_t *tvb;
11808} offset_search_t;
11809
11810static bool_Bool
11811check_for_offset(proto_node *node, void * data)
11812{
11813 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11814 offset_search_t *offsearch = (offset_search_t *)data;
11815
11816 /* !fi == the top most container node which holds nothing */
11817 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11818 if (offsearch->offset >= (unsigned) fi->start &&
11819 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11820
11821 offsearch->finfo = fi;
11822 return false0; /* keep traversing */
11823 }
11824 }
11825 return false0; /* keep traversing */
11826}
11827
11828/* Search a proto_tree backwards (from leaves to root) looking for the field
11829 * whose start/length occupies 'offset' */
11830/* XXX - I couldn't find an easy way to search backwards, so I search
11831 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11832 * the one I want to return to the user. This algorithm is inefficient
11833 * and could be re-done, but I'd have to handle all the children and
11834 * siblings of each node myself. When I have more time I'll do that.
11835 * (yeah right) */
11836field_info *
11837proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11838{
11839 offset_search_t offsearch;
11840
11841 offsearch.offset = offset;
11842 offsearch.finfo = NULL((void*)0);
11843 offsearch.tvb = tvb;
11844
11845 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11846
11847 return offsearch.finfo;
11848}
11849
11850typedef struct {
11851 unsigned length;
11852 char *buf;
11853} decoded_data_t;
11854
11855static bool_Bool
11856check_for_undecoded(proto_node *node, void * data)
11857{
11858 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11859 decoded_data_t* decoded = (decoded_data_t*)data;
11860 unsigned i;
11861 unsigned byte;
11862 unsigned bit;
11863
11864 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11865 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11866 byte = i / 8;
11867 bit = i % 8;
11868 decoded->buf[byte] |= (1 << bit);
11869 }
11870 }
11871
11872 return false0;
11873}
11874
11875char*
11876proto_find_undecoded_data(proto_tree *tree, unsigned length)
11877{
11878 decoded_data_t decoded;
11879 decoded.length = length;
11880 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11881
11882 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11883 return decoded.buf;
11884}
11885
11886/* Dumps the protocols in the registration database to stdout. An independent
11887 * program can take this output and format it into nice tables or HTML or
11888 * whatever.
11889 *
11890 * There is one record per line. The fields are tab-delimited.
11891 *
11892 * Field 1 = protocol name
11893 * Field 2 = protocol short name
11894 * Field 3 = protocol filter name
11895 * Field 4 = protocol enabled
11896 * Field 5 = protocol enabled by default
11897 * Field 6 = protocol can toggle
11898 */
11899void
11900proto_registrar_dump_protocols(void)
11901{
11902 protocol_t *protocol;
11903 int i;
11904 void *cookie = NULL((void*)0);
11905
11906
11907 i = proto_get_first_protocol(&cookie);
11908 while (i != -1) {
11909 protocol = find_protocol_by_id(i);
11910 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11911 protocol->name,
11912 protocol->short_name,
11913 protocol->filter_name,
11914 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11915 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11916 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11917 i = proto_get_next_protocol(&cookie);
11918 }
11919}
11920
11921/* Dumps the value_strings, extended value string headers, range_strings
11922 * or true/false strings for fields that have them.
11923 * There is one record per line. Fields are tab-delimited.
11924 * There are four types of records: Value String, Extended Value String Header,
11925 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11926 * the type of record.
11927 *
11928 * Note that a record will be generated only if the value_string,... is referenced
11929 * in a registered hfinfo entry.
11930 *
11931 *
11932 * Value Strings
11933 * -------------
11934 * Field 1 = 'V'
11935 * Field 2 = Field abbreviation to which this value string corresponds
11936 * Field 3 = Integer value
11937 * Field 4 = String
11938 *
11939 * Extended Value String Headers
11940 * -----------------------------
11941 * Field 1 = 'E'
11942 * Field 2 = Field abbreviation to which this extended value string header corresponds
11943 * Field 3 = Extended Value String "Name"
11944 * Field 4 = Number of entries in the associated value_string array
11945 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11946 *
11947 * Range Strings
11948 * -------------
11949 * Field 1 = 'R'
11950 * Field 2 = Field abbreviation to which this range string corresponds
11951 * Field 3 = Integer value: lower bound
11952 * Field 4 = Integer value: upper bound
11953 * Field 5 = String
11954 *
11955 * True/False Strings
11956 * ------------------
11957 * Field 1 = 'T'
11958 * Field 2 = Field abbreviation to which this true/false string corresponds
11959 * Field 3 = True String
11960 * Field 4 = False String
11961 */
11962void
11963proto_registrar_dump_values(void)
11964{
11965 header_field_info *hfinfo;
11966 int i, len, vi;
11967 const value_string *vals;
11968 const val64_string *vals64;
11969 const range_string *range;
11970 const true_false_string *tfs;
11971 const unit_name_string *units;
11972
11973 len = gpa_hfinfo.len;
11974 for (i = 1; i < len ; i++) {
11975 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11976 continue; /* This is a deregistered protocol or field */
11977
11978 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", 11978
, __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", 11978
, "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", 11978, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11979
11980 if (hfinfo->id == hf_text_only) {
11981 continue;
11982 }
11983
11984 /* ignore protocols */
11985 if (proto_registrar_is_protocol(i)) {
11986 continue;
11987 }
11988 /* process header fields */
11989#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11990 /*
11991 * If this field isn't at the head of the list of
11992 * fields with this name, skip this field - all
11993 * fields with the same name are really just versions
11994 * of the same field stored in different bits, and
11995 * should have the same type/radix/value list, and
11996 * just differ in their bit masks. (If a field isn't
11997 * a bitfield, but can be, say, 1 or 2 bytes long,
11998 * it can just be made FT_UINT16, meaning the
11999 * *maximum* length is 2 bytes, and be used
12000 * for all lengths.)
12001 */
12002 if (hfinfo->same_name_prev_id != -1)
12003 continue;
12004#endif
12005 vals = NULL((void*)0);
12006 vals64 = NULL((void*)0);
12007 range = NULL((void*)0);
12008 tfs = NULL((void*)0);
12009 units = NULL((void*)0);
12010
12011 if (hfinfo->strings != NULL((void*)0)) {
12012 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12013 (hfinfo->type == FT_CHAR ||
12014 hfinfo->type == FT_UINT8 ||
12015 hfinfo->type == FT_UINT16 ||
12016 hfinfo->type == FT_UINT24 ||
12017 hfinfo->type == FT_UINT32 ||
12018 hfinfo->type == FT_UINT40 ||
12019 hfinfo->type == FT_UINT48 ||
12020 hfinfo->type == FT_UINT56 ||
12021 hfinfo->type == FT_UINT64 ||
12022 hfinfo->type == FT_INT8 ||
12023 hfinfo->type == FT_INT16 ||
12024 hfinfo->type == FT_INT24 ||
12025 hfinfo->type == FT_INT32 ||
12026 hfinfo->type == FT_INT40 ||
12027 hfinfo->type == FT_INT48 ||
12028 hfinfo->type == FT_INT56 ||
12029 hfinfo->type == FT_INT64 ||
12030 hfinfo->type == FT_FLOAT ||
12031 hfinfo->type == FT_DOUBLE)) {
12032
12033 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12034 range = (const range_string *)hfinfo->strings;
12035 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12036 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12037 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12038 } else {
12039 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12040 }
12041 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12042 vals64 = (const val64_string *)hfinfo->strings;
12043 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12044 units = (const unit_name_string *)hfinfo->strings;
12045 } else {
12046 vals = (const value_string *)hfinfo->strings;
12047 }
12048 }
12049 else if (hfinfo->type == FT_BOOLEAN) {
12050 tfs = (const struct true_false_string *)hfinfo->strings;
12051 }
12052 }
12053
12054 /* Print value strings? */
12055 if (vals) {
12056 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12057 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12058 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12059 if (!val64_string_ext_validate(vse_p)) {
12060 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12060, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12061 continue;
12062 }
12063 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12064 printf("E\t%s\t%u\t%s\t%s\n",
12065 hfinfo->abbrev,
12066 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12067 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12068 val64_string_ext_match_type_str(vse_p));
12069 } else {
12070 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12071 if (!value_string_ext_validate(vse_p)) {
12072 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12072, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12073 continue;
12074 }
12075 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12076 printf("E\t%s\t%u\t%s\t%s\n",
12077 hfinfo->abbrev,
12078 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12079 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12080 value_string_ext_match_type_str(vse_p));
12081 }
12082 }
12083 vi = 0;
12084 while (vals[vi].strptr) {
12085 /* Print in the proper base */
12086 if (hfinfo->type == FT_CHAR) {
12087 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12088 printf("V\t%s\t'%c'\t%s\n",
12089 hfinfo->abbrev,
12090 vals[vi].value,
12091 vals[vi].strptr);
12092 } else {
12093 if (hfinfo->display == BASE_HEX) {
12094 printf("V\t%s\t'\\x%02x'\t%s\n",
12095 hfinfo->abbrev,
12096 vals[vi].value,
12097 vals[vi].strptr);
12098 }
12099 else {
12100 printf("V\t%s\t'\\%03o'\t%s\n",
12101 hfinfo->abbrev,
12102 vals[vi].value,
12103 vals[vi].strptr);
12104 }
12105 }
12106 } else {
12107 if (hfinfo->display == BASE_HEX) {
12108 printf("V\t%s\t0x%x\t%s\n",
12109 hfinfo->abbrev,
12110 vals[vi].value,
12111 vals[vi].strptr);
12112 }
12113 else {
12114 printf("V\t%s\t%u\t%s\n",
12115 hfinfo->abbrev,
12116 vals[vi].value,
12117 vals[vi].strptr);
12118 }
12119 }
12120 vi++;
12121 }
12122 }
12123 else if (vals64) {
12124 vi = 0;
12125 while (vals64[vi].strptr) {
12126 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12127 hfinfo->abbrev,
12128 vals64[vi].value,
12129 vals64[vi].strptr);
12130 vi++;
12131 }
12132 }
12133
12134 /* print range strings? */
12135 else if (range) {
12136 vi = 0;
12137 while (range[vi].strptr) {
12138 /* Print in the proper base */
12139 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12140 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12141 hfinfo->abbrev,
12142 range[vi].value_min,
12143 range[vi].value_max,
12144 range[vi].strptr);
12145 }
12146 else {
12147 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12148 hfinfo->abbrev,
12149 range[vi].value_min,
12150 range[vi].value_max,
12151 range[vi].strptr);
12152 }
12153 vi++;
12154 }
12155 }
12156
12157 /* Print true/false strings? */
12158 else if (tfs) {
12159 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12160 tfs->true_string, tfs->false_string);
12161 }
12162 /* Print unit strings? */
12163 else if (units) {
12164 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12165 units->singular, units->plural ? units->plural : "(no plural)");
12166 }
12167 }
12168}
12169
12170/* Prints the number of registered fields.
12171 * Useful for determining an appropriate value for
12172 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12173 *
12174 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12175 * the number of fields, true otherwise.
12176 */
12177bool_Bool
12178proto_registrar_dump_fieldcount(void)
12179{
12180 struct proto_registrar_stats stats = {0, 0, 0};
12181 size_t total_count = proto_registrar_get_count(&stats);
12182
12183 printf("There are %zu header fields registered, of which:\n"
12184 "\t%zu are deregistered\n"
12185 "\t%zu are protocols\n"
12186 "\t%zu have the same name as another field\n\n",
12187 total_count, stats.deregistered_count, stats.protocol_count,
12188 stats.same_name_count);
12189
12190 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12191 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12192 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12193 "\n");
12194
12195 printf("The header field table consumes %u KiB of memory.\n",
12196 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12197 printf("The fields themselves consume %u KiB of memory.\n",
12198 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12199
12200 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12201}
12202
12203static void
12204elastic_add_base_mapping(json_dumper *dumper)
12205{
12206 json_dumper_set_member_name(dumper, "index_patterns");
12207 json_dumper_begin_array(dumper);
12208 // The index names from write_json_index() in print.c
12209 json_dumper_value_string(dumper, "packets-*");
12210 json_dumper_end_array(dumper);
12211
12212 json_dumper_set_member_name(dumper, "settings");
12213 json_dumper_begin_object(dumper);
12214 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12215 json_dumper_value_anyf(dumper, "%d", 1000000);
12216 json_dumper_end_object(dumper);
12217}
12218
12219static char*
12220ws_type_to_elastic(unsigned type)
12221{
12222 switch(type) {
12223 case FT_INT8:
12224 return "byte";
12225 case FT_UINT8:
12226 case FT_INT16:
12227 return "short";
12228 case FT_UINT16:
12229 case FT_INT32:
12230 case FT_UINT24:
12231 case FT_INT24:
12232 return "integer";
12233 case FT_FRAMENUM:
12234 case FT_UINT32:
12235 case FT_UINT40:
12236 case FT_UINT48:
12237 case FT_UINT56:
12238 case FT_INT40:
12239 case FT_INT48:
12240 case FT_INT56:
12241 case FT_INT64:
12242 return "long";
12243 case FT_UINT64:
12244 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12245 case FT_FLOAT:
12246 return "float";
12247 case FT_DOUBLE:
12248 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12249 return "double";
12250 case FT_IPv6:
12251 case FT_IPv4:
12252 return "ip";
12253 case FT_ABSOLUTE_TIME:
12254 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12255 case FT_BOOLEAN:
12256 return "boolean";
12257 default:
12258 return NULL((void*)0);
12259 }
12260}
12261
12262static char*
12263dot_to_underscore(char* str)
12264{
12265 unsigned i;
12266 for (i = 0; i < strlen(str); i++) {
12267 if (str[i] == '.')
12268 str[i] = '_';
12269 }
12270 return str;
12271}
12272
12273/* Dumps a mapping file for ElasticSearch
12274 * This is the v1 (legacy) _template API.
12275 * At some point it may need to be updated with the composable templates
12276 * introduced in Elasticsearch 7.8 (_index_template)
12277 */
12278void
12279proto_registrar_dump_elastic(const char* filter)
12280{
12281 header_field_info *hfinfo;
12282 header_field_info *parent_hfinfo;
12283 unsigned i;
12284 bool_Bool open_object = true1;
12285 const char* prev_proto = NULL((void*)0);
12286 char* str;
12287 char** protos = NULL((void*)0);
12288 char* proto;
12289 bool_Bool found;
12290 unsigned j;
12291 char* type;
12292 char* prev_item = NULL((void*)0);
12293
12294 /* We have filtering protocols. Extract them. */
12295 if (filter) {
12296 protos = g_strsplit(filter, ",", -1);
12297 }
12298
12299 /*
12300 * To help tracking down the json tree, objects have been appended with a comment:
12301 * n.label -> where n is the indentation level and label the name of the object
12302 */
12303
12304 json_dumper dumper = {
12305 .output_file = stdoutstdout,
12306 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12307 };
12308 json_dumper_begin_object(&dumper); // 1.root
12309 elastic_add_base_mapping(&dumper);
12310
12311 json_dumper_set_member_name(&dumper, "mappings");
12312 json_dumper_begin_object(&dumper); // 2.mappings
12313
12314 json_dumper_set_member_name(&dumper, "properties");
12315 json_dumper_begin_object(&dumper); // 3.properties
12316 json_dumper_set_member_name(&dumper, "timestamp");
12317 json_dumper_begin_object(&dumper); // 4.timestamp
12318 json_dumper_set_member_name(&dumper, "type");
12319 json_dumper_value_string(&dumper, "date");
12320 json_dumper_end_object(&dumper); // 4.timestamp
12321
12322 json_dumper_set_member_name(&dumper, "layers");
12323 json_dumper_begin_object(&dumper); // 4.layers
12324 json_dumper_set_member_name(&dumper, "properties");
12325 json_dumper_begin_object(&dumper); // 5.properties
12326
12327 for (i = 1; i < gpa_hfinfo.len; i++) {
12328 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12329 continue; /* This is a deregistered protocol or header field */
12330
12331 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", 12331
, __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", 12331
, "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", 12331, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12332
12333 /*
12334 * Skip the pseudo-field for "proto_tree_add_text()" since
12335 * we don't want it in the list of filterable protocols.
12336 */
12337 if (hfinfo->id == hf_text_only)
12338 continue;
12339
12340 if (!proto_registrar_is_protocol(i)) {
12341 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", 12341
, __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", 12341
, "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", 12341
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12342
12343 /*
12344 * Skip the field if filter protocols have been set and this one's
12345 * parent is not listed.
12346 */
12347 if (protos) {
12348 found = false0;
12349 j = 0;
12350 proto = protos[0];
12351 while(proto) {
12352 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12353 found = true1;
12354 break;
12355 }
12356 j++;
12357 proto = protos[j];
12358 }
12359 if (!found)
12360 continue;
12361 }
12362
12363 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12364 json_dumper_end_object(&dumper); // 7.properties
12365 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12366 open_object = true1;
12367 }
12368
12369 prev_proto = parent_hfinfo->abbrev;
12370
12371 if (open_object) {
12372 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12373 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12374 json_dumper_set_member_name(&dumper, "properties");
12375 json_dumper_begin_object(&dumper); // 7.properties
12376 open_object = false0;
12377 }
12378 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12379 type = ws_type_to_elastic(hfinfo->type);
12380 /* when type is NULL, we have the default mapping: string */
12381 if (type) {
12382 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12383 dot_to_underscore(str);
12384 if (g_strcmp0(prev_item, str)) {
12385 json_dumper_set_member_name(&dumper, str);
12386 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12387 json_dumper_set_member_name(&dumper, "type");
12388 json_dumper_value_string(&dumper, type);
12389 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12390 }
12391 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)
;
12392 prev_item = str;
12393 }
12394 }
12395 }
12396 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)
;
12397
12398 if (prev_proto) {
12399 json_dumper_end_object(&dumper); // 7.properties
12400 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12401 }
12402
12403 json_dumper_end_object(&dumper); // 5.properties
12404 json_dumper_end_object(&dumper); // 4.layers
12405 json_dumper_end_object(&dumper); // 3.properties
12406 json_dumper_end_object(&dumper); // 2.mappings
12407 json_dumper_end_object(&dumper); // 1.root
12408 bool_Bool ret = json_dumper_finish(&dumper);
12409 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12409, "ret"))))
;
12410
12411 g_strfreev(protos);
12412}
12413
12414/* Dumps the contents of the registration database to stdout. An independent
12415 * program can take this output and format it into nice tables or HTML or
12416 * whatever.
12417 *
12418 * There is one record per line. Each record is either a protocol or a header
12419 * field, differentiated by the first field. The fields are tab-delimited.
12420 *
12421 * Protocols
12422 * ---------
12423 * Field 1 = 'P'
12424 * Field 2 = descriptive protocol name
12425 * Field 3 = protocol abbreviation
12426 *
12427 * Header Fields
12428 * -------------
12429 * Field 1 = 'F'
12430 * Field 2 = descriptive field name
12431 * Field 3 = field abbreviation
12432 * Field 4 = type ( textual representation of the ftenum type )
12433 * Field 5 = parent protocol abbreviation
12434 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12435 * Field 7 = bitmask: format: hex: 0x....
12436 * Field 8 = blurb describing field
12437 */
12438void
12439proto_registrar_dump_fields(void)
12440{
12441 header_field_info *hfinfo, *parent_hfinfo;
12442 int i, len;
12443 const char *enum_name;
12444 const char *base_name;
12445 const char *blurb;
12446 char width[5];
12447
12448 len = gpa_hfinfo.len;
12449 for (i = 1; i < len ; i++) {
12450 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12451 continue; /* This is a deregistered protocol or header field */
12452
12453 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", 12453
, __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", 12453
, "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", 12453, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12454
12455 /*
12456 * Skip the pseudo-field for "proto_tree_add_text()" since
12457 * we don't want it in the list of filterable fields.
12458 */
12459 if (hfinfo->id == hf_text_only)
12460 continue;
12461
12462 /* format for protocols */
12463 if (proto_registrar_is_protocol(i)) {
12464 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12465 }
12466 /* format for header fields */
12467 else {
12468 /*
12469 * If this field isn't at the head of the list of
12470 * fields with this name, skip this field - all
12471 * fields with the same name are really just versions
12472 * of the same field stored in different bits, and
12473 * should have the same type/radix/value list, and
12474 * just differ in their bit masks. (If a field isn't
12475 * a bitfield, but can be, say, 1 or 2 bytes long,
12476 * it can just be made FT_UINT16, meaning the
12477 * *maximum* length is 2 bytes, and be used
12478 * for all lengths.)
12479 */
12480 if (hfinfo->same_name_prev_id != -1)
12481 continue;
12482
12483 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", 12483
, __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", 12483
, "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", 12483
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12484
12485 enum_name = ftype_name(hfinfo->type);
12486 base_name = "";
12487
12488 if (hfinfo->type == FT_CHAR ||
12489 hfinfo->type == FT_UINT8 ||
12490 hfinfo->type == FT_UINT16 ||
12491 hfinfo->type == FT_UINT24 ||
12492 hfinfo->type == FT_UINT32 ||
12493 hfinfo->type == FT_UINT40 ||
12494 hfinfo->type == FT_UINT48 ||
12495 hfinfo->type == FT_UINT56 ||
12496 hfinfo->type == FT_UINT64 ||
12497 hfinfo->type == FT_INT8 ||
12498 hfinfo->type == FT_INT16 ||
12499 hfinfo->type == FT_INT24 ||
12500 hfinfo->type == FT_INT32 ||
12501 hfinfo->type == FT_INT40 ||
12502 hfinfo->type == FT_INT48 ||
12503 hfinfo->type == FT_INT56 ||
12504 hfinfo->type == FT_INT64) {
12505
12506 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12507 case BASE_NONE:
12508 case BASE_DEC:
12509 case BASE_HEX:
12510 case BASE_OCT:
12511 case BASE_DEC_HEX:
12512 case BASE_HEX_DEC:
12513 case BASE_CUSTOM:
12514 case BASE_PT_UDP:
12515 case BASE_PT_TCP:
12516 case BASE_PT_DCCP:
12517 case BASE_PT_SCTP:
12518 case BASE_OUI:
12519 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12520 break;
12521 default:
12522 base_name = "????";
12523 break;
12524 }
12525 } else if (hfinfo->type == FT_BOOLEAN) {
12526 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12527 snprintf(width, sizeof(width), "%d", hfinfo->display);
12528 base_name = width;
12529 }
12530
12531 blurb = hfinfo->blurb;
12532 if (blurb == NULL((void*)0))
12533 blurb = "";
12534 else if (strlen(blurb) == 0)
12535 blurb = "\"\"";
12536
12537 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12538 hfinfo->name, hfinfo->abbrev, enum_name,
12539 parent_hfinfo->abbrev, base_name,
12540 hfinfo->bitmask, blurb);
12541 }
12542 }
12543}
12544
12545/* Dumps all abbreviated field and protocol completions of the given string to
12546 * stdout. An independent program may use this for command-line tab completion
12547 * of fields.
12548 */
12549bool_Bool
12550proto_registrar_dump_field_completions(const char *prefix)
12551{
12552 header_field_info *hfinfo;
12553 int i, len;
12554 size_t prefix_len;
12555 bool_Bool matched = false0;
12556
12557 prefix_len = strlen(prefix);
12558 len = gpa_hfinfo.len;
12559 for (i = 1; i < len ; i++) {
12560 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12561 continue; /* This is a deregistered protocol or header field */
12562
12563 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", 12563
, __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", 12563
, "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", 12563, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12564
12565 /*
12566 * Skip the pseudo-field for "proto_tree_add_text()" since
12567 * we don't want it in the list of filterable fields.
12568 */
12569 if (hfinfo->id == hf_text_only)
12570 continue;
12571
12572 /* format for protocols */
12573 if (proto_registrar_is_protocol(i)) {
12574 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12575 matched = true1;
12576 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12577 }
12578 }
12579 /* format for header fields */
12580 else {
12581 /*
12582 * If this field isn't at the head of the list of
12583 * fields with this name, skip this field - all
12584 * fields with the same name are really just versions
12585 * of the same field stored in different bits, and
12586 * should have the same type/radix/value list, and
12587 * just differ in their bit masks. (If a field isn't
12588 * a bitfield, but can be, say, 1 or 2 bytes long,
12589 * it can just be made FT_UINT16, meaning the
12590 * *maximum* length is 2 bytes, and be used
12591 * for all lengths.)
12592 */
12593 if (hfinfo->same_name_prev_id != -1)
12594 continue;
12595
12596 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12597 matched = true1;
12598 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12599 }
12600 }
12601 }
12602 return matched;
12603}
12604
12605/* Dumps field types and descriptive names to stdout. An independent
12606 * program can take this output and format it into nice tables or HTML or
12607 * whatever.
12608 *
12609 * There is one record per line. The fields are tab-delimited.
12610 *
12611 * Field 1 = field type name, e.g. FT_UINT8
12612 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12613 */
12614void
12615proto_registrar_dump_ftypes(void)
12616{
12617 int fte;
12618
12619 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12620 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12621 }
12622}
12623
12624/* This function indicates whether it's possible to construct a
12625 * "match selected" display filter string for the specified field,
12626 * returns an indication of whether it's possible, and, if it's
12627 * possible and "filter" is non-null, constructs the filter and
12628 * sets "*filter" to point to it.
12629 * You do not need to [g_]free() this string since it will be automatically
12630 * freed once the next packet is dissected.
12631 */
12632static bool_Bool
12633construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12634 char **filter)
12635{
12636 const header_field_info *hfinfo;
12637 int start, length, length_remaining;
12638
12639 if (!finfo)
12640 return false0;
12641
12642 hfinfo = finfo->hfinfo;
12643 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12643, "hfinfo"))))
;
12644
12645 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12646 * then "the numeric value ... is not used when preparing
12647 * filters for the field in question." If it's any other
12648 * base, we'll generate the filter normally (which will
12649 * be numeric, even though the human-readable string does
12650 * work for filtering.)
12651 *
12652 * XXX - It might be nice to use fvalue_to_string_repr() in
12653 * "proto_item_fill_label()" as well, although, there, you'd
12654 * have to deal with the base *and* with resolved values for
12655 * addresses.
12656 *
12657 * Perhaps in addition to taking the repr type (DISPLAY
12658 * or DFILTER) and the display (base), fvalue_to_string_repr()
12659 * should have the the "strings" values in the header_field_info
12660 * structure for the field as a parameter, so it can have
12661 * if the field is Boolean or an enumerated integer type,
12662 * the tables used to generate human-readable values.
12663 */
12664 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12665 const char *str = NULL((void*)0);
12666
12667 switch (hfinfo->type) {
12668
12669 case FT_INT8:
12670 case FT_INT16:
12671 case FT_INT24:
12672 case FT_INT32:
12673 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12674 break;
12675
12676 case FT_CHAR:
12677 case FT_UINT8:
12678 case FT_UINT16:
12679 case FT_UINT24:
12680 case FT_UINT32:
12681 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12682 break;
12683
12684 default:
12685 break;
12686 }
12687
12688 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12689 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12690 return true1;
12691 }
12692 }
12693
12694 switch (hfinfo->type) {
12695
12696 case FT_PROTOCOL:
12697 if (filter != NULL((void*)0))
12698 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12699 break;
12700
12701 case FT_NONE:
12702 /*
12703 * If the length is 0, just match the name of the
12704 * field.
12705 *
12706 * (Also check for negative values, just in case,
12707 * as we'll cast it to an unsigned value later.)
12708 */
12709 length = finfo->length;
12710 if (length == 0) {
12711 if (filter != NULL((void*)0))
12712 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12713 break;
12714 }
12715 if (length < 0)
12716 return false0;
12717
12718 /*
12719 * This doesn't have a value, so we'd match
12720 * on the raw bytes at this address.
12721 *
12722 * Should we be allowed to access to the raw bytes?
12723 * If "edt" is NULL, the answer is "no".
12724 */
12725 if (edt == NULL((void*)0))
12726 return false0;
12727
12728 /*
12729 * Is this field part of the raw frame tvbuff?
12730 * If not, we can't use "frame[N:M]" to match
12731 * it.
12732 *
12733 * XXX - should this be frame-relative, or
12734 * protocol-relative?
12735 *
12736 * XXX - does this fallback for non-registered
12737 * fields even make sense?
12738 */
12739 if (finfo->ds_tvb != edt->tvb)
12740 return false0; /* you lose */
12741
12742 /*
12743 * Don't go past the end of that tvbuff.
12744 */
12745 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12746 if (length > length_remaining)
12747 length = length_remaining;
12748 if (length <= 0)
12749 return false0;
12750
12751 if (filter != NULL((void*)0)) {
12752 start = finfo->start;
12753 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12754 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12755 wmem_free(NULL((void*)0), str);
12756 }
12757 break;
12758
12759 /* By default, use the fvalue's "to_string_repr" method. */
12760 default:
12761 if (filter != NULL((void*)0)) {
12762 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12763 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12764 wmem_free(NULL((void*)0), str);
12765 }
12766 break;
12767 }
12768
12769 return true1;
12770}
12771
12772/*
12773 * Returns true if we can do a "match selected" on the field, false
12774 * otherwise.
12775 */
12776bool_Bool
12777proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12778{
12779 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12780}
12781
12782/* This function attempts to construct a "match selected" display filter
12783 * string for the specified field; if it can do so, it returns a pointer
12784 * to the string, otherwise it returns NULL.
12785 *
12786 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12787 */
12788char *
12789proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12790{
12791 char *filter = NULL((void*)0);
12792
12793 if (!construct_match_selected_string(finfo, edt, &filter))
12794 {
12795 wmem_free(NULL((void*)0), filter);
12796 return NULL((void*)0);
12797 }
12798 return filter;
12799}
12800
12801/* This function is common code for all proto_tree_add_bitmask... functions.
12802 */
12803
12804static bool_Bool
12805proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12806 const int len, const int ett, int * const *fields,
12807 const int flags, bool_Bool first,
12808 bool_Bool use_parent_tree,
12809 proto_tree* tree, uint64_t value)
12810{
12811 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12812 uint64_t bitmask = 0;
12813 uint64_t tmpval;
12814 header_field_info *hf;
12815 uint32_t integer32;
12816 int bit_offset;
12817 int no_of_bits;
12818
12819 if (!*fields)
12820 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"
)
;
12821
12822 if (len < 0 || len > 8)
12823 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12824 /**
12825 * packet-frame.c uses len=0 since the value is taken from the packet
12826 * metadata, not the packet bytes. In that case, assume that all bits
12827 * in the provided value are valid.
12828 */
12829 if (len > 0) {
12830 available_bits >>= (8 - (unsigned)len)*8;
12831 }
12832
12833 if (use_parent_tree == false0)
12834 tree = proto_item_add_subtree(item, ett);
12835
12836 while (*fields) {
12837 uint64_t present_bits;
12838 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", 12838, __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", 12838
, "**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", 12838, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12839 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", 12839
, "hf->bitmask != 0", hf->abbrev))))
;
12840
12841 bitmask |= hf->bitmask;
12842
12843 /* Skip fields that aren't fully present */
12844 present_bits = available_bits & hf->bitmask;
12845 if (present_bits != hf->bitmask) {
12846 fields++;
12847 continue;
12848 }
12849
12850 switch (hf->type) {
12851 case FT_CHAR:
12852 case FT_UINT8:
12853 case FT_UINT16:
12854 case FT_UINT24:
12855 case FT_UINT32:
12856 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12857 break;
12858
12859 case FT_INT8:
12860 case FT_INT16:
12861 case FT_INT24:
12862 case FT_INT32:
12863 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12864 break;
12865
12866 case FT_UINT40:
12867 case FT_UINT48:
12868 case FT_UINT56:
12869 case FT_UINT64:
12870 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12871 break;
12872
12873 case FT_INT40:
12874 case FT_INT48:
12875 case FT_INT56:
12876 case FT_INT64:
12877 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12878 break;
12879
12880 case FT_BOOLEAN:
12881 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12882 break;
12883
12884 default:
12885 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))
12886 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))
12887 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))
12888 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))
;
12889 break;
12890 }
12891 if (flags & BMT_NO_APPEND0x01) {
12892 fields++;
12893 continue;
12894 }
12895 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12896
12897 /* XXX: README.developer and the comments have always defined
12898 * BMT_NO_INT as "only boolean flags are added to the title /
12899 * don't add non-boolean (integral) fields", but the
12900 * implementation has always added BASE_CUSTOM and fields with
12901 * value_strings, though not fields with unit_strings.
12902 * Possibly this is because some dissectors use a FT_UINT8
12903 * with a value_string for fields that should be a FT_BOOLEAN.
12904 */
12905 switch (hf->type) {
12906 case FT_CHAR:
12907 if (hf->display == BASE_CUSTOM) {
12908 char lbl[ITEM_LABEL_LENGTH240];
12909 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12910
12911 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12911, "fmtfunc"))))
;
12912 fmtfunc(lbl, (uint32_t) tmpval);
12913 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12914 hf->name, lbl);
12915 first = false0;
12916 }
12917 else if (hf->strings) {
12918 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12919 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12920 first = false0;
12921 }
12922 else if (!(flags & BMT_NO_INT0x02)) {
12923 char buf[32];
12924 const char *out;
12925
12926 if (!first) {
12927 proto_item_append_text(item, ", ");
12928 }
12929
12930 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12931 proto_item_append_text(item, "%s: %s", hf->name, out);
12932 first = false0;
12933 }
12934
12935 break;
12936
12937 case FT_UINT8:
12938 case FT_UINT16:
12939 case FT_UINT24:
12940 case FT_UINT32:
12941 if (hf->display == BASE_CUSTOM) {
12942 char lbl[ITEM_LABEL_LENGTH240];
12943 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12944
12945 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12945, "fmtfunc"))))
;
12946 fmtfunc(lbl, (uint32_t) tmpval);
12947 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12948 hf->name, lbl);
12949 first = false0;
12950 }
12951 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12952 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12953 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12954 first = false0;
12955 }
12956 else if (!(flags & BMT_NO_INT0x02)) {
12957 char buf[NUMBER_LABEL_LENGTH80];
12958 const char *out = NULL((void*)0);
12959
12960 if (!first) {
12961 proto_item_append_text(item, ", ");
12962 }
12963
12964 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12965 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12966 }
12967 if (out == NULL((void*)0)) {
12968 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12969 }
12970 proto_item_append_text(item, "%s: %s", hf->name, out);
12971 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12972 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12973 }
12974 first = false0;
12975 }
12976
12977 break;
12978
12979 case FT_INT8:
12980 case FT_INT16:
12981 case FT_INT24:
12982 case FT_INT32:
12983 integer32 = (uint32_t) tmpval;
12984 if (hf->bitmask) {
12985 no_of_bits = ws_count_ones(hf->bitmask);
12986 integer32 = ws_sign_ext32(integer32, no_of_bits);
12987 }
12988 if (hf->display == BASE_CUSTOM) {
12989 char lbl[ITEM_LABEL_LENGTH240];
12990 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12991
12992 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12992, "fmtfunc"))))
;
12993 fmtfunc(lbl, (int32_t) integer32);
12994 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12995 hf->name, lbl);
12996 first = false0;
12997 }
12998 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12999 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13000 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13001 first = false0;
13002 }
13003 else if (!(flags & BMT_NO_INT0x02)) {
13004 char buf[NUMBER_LABEL_LENGTH80];
13005 const char *out = NULL((void*)0);
13006
13007 if (!first) {
13008 proto_item_append_text(item, ", ");
13009 }
13010
13011 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13012 out = hf_try_val_to_str((int32_t) integer32, hf);
13013 }
13014 if (out == NULL((void*)0)) {
13015 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13016 }
13017 proto_item_append_text(item, "%s: %s", hf->name, out);
13018 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13019 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13020 }
13021 first = false0;
13022 }
13023
13024 break;
13025
13026 case FT_UINT40:
13027 case FT_UINT48:
13028 case FT_UINT56:
13029 case FT_UINT64:
13030 if (hf->display == BASE_CUSTOM) {
13031 char lbl[ITEM_LABEL_LENGTH240];
13032 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13033
13034 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13034, "fmtfunc"))))
;
13035 fmtfunc(lbl, tmpval);
13036 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13037 hf->name, lbl);
13038 first = false0;
13039 }
13040 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13041 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13042 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13043 first = false0;
13044 }
13045 else if (!(flags & BMT_NO_INT0x02)) {
13046 char buf[NUMBER_LABEL_LENGTH80];
13047 const char *out = NULL((void*)0);
13048
13049 if (!first) {
13050 proto_item_append_text(item, ", ");
13051 }
13052
13053 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13054 out = hf_try_val64_to_str(tmpval, hf);
13055 }
13056 if (out == NULL((void*)0)) {
13057 out = hfinfo_number_value_format64(hf, buf, tmpval);
13058 }
13059 proto_item_append_text(item, "%s: %s", hf->name, out);
13060 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13061 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13062 }
13063 first = false0;
13064 }
13065
13066 break;
13067
13068 case FT_INT40:
13069 case FT_INT48:
13070 case FT_INT56:
13071 case FT_INT64:
13072 if (hf->bitmask) {
13073 no_of_bits = ws_count_ones(hf->bitmask);
13074 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13075 }
13076 if (hf->display == BASE_CUSTOM) {
13077 char lbl[ITEM_LABEL_LENGTH240];
13078 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13079
13080 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13080, "fmtfunc"))))
;
13081 fmtfunc(lbl, (int64_t) tmpval);
13082 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13083 hf->name, lbl);
13084 first = false0;
13085 }
13086 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13087 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13088 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13089 first = false0;
13090 }
13091 else if (!(flags & BMT_NO_INT0x02)) {
13092 char buf[NUMBER_LABEL_LENGTH80];
13093 const char *out = NULL((void*)0);
13094
13095 if (!first) {
13096 proto_item_append_text(item, ", ");
13097 }
13098
13099 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13100 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13101 }
13102 if (out == NULL((void*)0)) {
13103 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13104 }
13105 proto_item_append_text(item, "%s: %s", hf->name, out);
13106 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13107 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13108 }
13109 first = false0;
13110 }
13111
13112 break;
13113
13114 case FT_BOOLEAN:
13115 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13116 /* If we have true/false strings, emit full - otherwise messages
13117 might look weird */
13118 const struct true_false_string *tfs =
13119 (const struct true_false_string *)hf->strings;
13120
13121 if (tmpval) {
13122 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13123 hf->name, tfs->true_string);
13124 first = false0;
13125 } else if (!(flags & BMT_NO_FALSE0x04)) {
13126 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13127 hf->name, tfs->false_string);
13128 first = false0;
13129 }
13130 } else if (hf->bitmask & value) {
13131 /* If the flag is set, show the name */
13132 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13133 first = false0;
13134 }
13135 break;
13136 default:
13137 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))
13138 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))
13139 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))
13140 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))
;
13141 break;
13142 }
13143
13144 fields++;
13145 }
13146
13147 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13148 * but then again most dissectors don't set the bitmask field for
13149 * the higher level bitmask hfi, so calculate the bitmask from the
13150 * fields present. */
13151 if (item) {
13152 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13153 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13154 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)
;
13155 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)
;
13156 }
13157 return first;
13158}
13159
13160/* This function will dissect a sequence of bytes that describe a
13161 * bitmask and supply the value of that sequence through a pointer.
13162 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13163 * to be dissected.
13164 * This field will form an expansion under which the individual fields of the
13165 * bitmask is dissected and displayed.
13166 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13167 *
13168 * fields is an array of pointers to int that lists all the fields of the
13169 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13170 * or another integer of the same type/size as hf_hdr with a mask specified.
13171 * This array is terminated by a NULL entry.
13172 *
13173 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13174 * FT_integer fields that have a value_string attached will have the
13175 * matched string displayed on the expansion line.
13176 */
13177proto_item *
13178proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13179 const unsigned offset, const int hf_hdr,
13180 const int ett, int * const *fields,
13181 const unsigned encoding, uint64_t *retval)
13182{
13183 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);
13184}
13185
13186/* This function will dissect a sequence of bytes that describe a
13187 * bitmask.
13188 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13189 * to be dissected.
13190 * This field will form an expansion under which the individual fields of the
13191 * bitmask is dissected and displayed.
13192 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13193 *
13194 * fields is an array of pointers to int that lists all the fields of the
13195 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13196 * or another integer of the same type/size as hf_hdr with a mask specified.
13197 * This array is terminated by a NULL entry.
13198 *
13199 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13200 * FT_integer fields that have a value_string attached will have the
13201 * matched string displayed on the expansion line.
13202 */
13203proto_item *
13204proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13205 const unsigned offset, const int hf_hdr,
13206 const int ett, int * const *fields,
13207 const unsigned encoding)
13208{
13209 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13210}
13211
13212/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13213 * what data is appended to the header.
13214 */
13215proto_item *
13216proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13217 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13218 uint64_t *retval)
13219{
13220 proto_item *item = NULL((void*)0);
13221 header_field_info *hf;
13222 int len;
13223 uint64_t value;
13224
13225 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", 13225, __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", 13225
, "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", 13225, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13226 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", 13226, (hf)->abbrev)))
;
13227 len = ftype_wire_size(hf->type);
13228 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13229
13230 if (parent_tree) {
13231 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13232 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13233 flags, false0, false0, NULL((void*)0), value);
13234 }
13235
13236 *retval = value;
13237 if (hf->bitmask) {
13238 /* Mask out irrelevant portions */
13239 *retval &= hf->bitmask;
13240 /* Shift bits */
13241 *retval >>= hfinfo_bitshift(hf);
13242 }
13243
13244 return item;
13245}
13246
13247/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13248 * what data is appended to the header.
13249 */
13250proto_item *
13251proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13252 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13253{
13254 proto_item *item = NULL((void*)0);
13255 header_field_info *hf;
13256 int len;
13257 uint64_t value;
13258
13259 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", 13259, __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", 13259
, "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", 13259, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13260 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", 13260, (hf)->abbrev)))
;
13261
13262 if (parent_tree) {
13263 len = ftype_wire_size(hf->type);
13264 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13265 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13266 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13267 flags, false0, false0, NULL((void*)0), value);
13268 }
13269
13270 return item;
13271}
13272
13273/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13274 can't be retrieved directly from tvb) */
13275proto_item *
13276proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13277 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13278{
13279 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13280 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13281}
13282
13283/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13284WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13285proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13286 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13287{
13288 proto_item *item = NULL((void*)0);
13289 header_field_info *hf;
13290 int len;
13291
13292 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", 13292, __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", 13292
, "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", 13292, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13293 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", 13293, (hf)->abbrev)))
;
13294 /* the proto_tree_add_uint/_uint64() calls below
13295 will fail if tvb==NULL and len!=0 */
13296 len = tvb ? ftype_wire_size(hf->type) : 0;
13297
13298 if (parent_tree) {
13299 if (len <= 4)
13300 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13301 else
13302 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13303
13304 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13305 flags, false0, false0, NULL((void*)0), value);
13306 }
13307
13308 return item;
13309}
13310
13311/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13312void
13313proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13314 const int len, int * const *fields, const unsigned encoding)
13315{
13316 uint64_t value;
13317
13318 if (tree) {
13319 value = get_uint64_value(tree, tvb, offset, len, encoding);
13320 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13321 BMT_NO_APPEND0x01, false0, true1, tree, value);
13322 }
13323}
13324
13325WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13326proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13327 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13328{
13329 uint64_t value;
13330
13331 value = get_uint64_value(tree, tvb, offset, len, encoding);
13332 if (tree) {
13333 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13334 BMT_NO_APPEND0x01, false0, true1, tree, value);
13335 }
13336 if (retval) {
13337 *retval = value;
13338 }
13339}
13340
13341WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13342proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13343 const int len, int * const *fields, const uint64_t value)
13344{
13345 if (tree) {
13346 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13347 BMT_NO_APPEND0x01, false0, true1, tree, value);
13348 }
13349}
13350
13351
13352/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13353 * This is intended to support bitmask fields whose lengths can vary, perhaps
13354 * as the underlying standard evolves over time.
13355 * With this API there is the possibility of being called to display more or
13356 * less data than the dissector was coded to support.
13357 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13358 * Thus when presented with "too much" or "too little" data, MSbits will be
13359 * ignored or MSfields sacrificed.
13360 *
13361 * Only fields for which all defined bits are available are displayed.
13362 */
13363proto_item *
13364proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13365 const unsigned offset, const unsigned len, const int hf_hdr,
13366 const int ett, int * const *fields, struct expert_field* exp,
13367 const unsigned encoding)
13368{
13369 proto_item *item = NULL((void*)0);
13370 header_field_info *hf;
13371 unsigned decodable_len;
13372 unsigned decodable_offset;
13373 uint32_t decodable_value;
13374 uint64_t value;
13375
13376 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", 13376, __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", 13376
, "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", 13376, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13377 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", 13377, (hf)->abbrev)))
;
13378
13379 decodable_offset = offset;
13380 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13381
13382 /* If we are ftype_wire_size-limited,
13383 * make sure we decode as many LSBs as possible.
13384 */
13385 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13386 decodable_offset += (len - decodable_len);
13387 }
13388
13389 if (parent_tree) {
13390 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13391 decodable_len, encoding);
13392
13393 /* The root item covers all the bytes even if we can't decode them all */
13394 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13395 decodable_value);
13396 }
13397
13398 if (decodable_len < len) {
13399 /* Dissector likely requires updating for new protocol revision */
13400 expert_add_info_format(NULL((void*)0), item, exp,
13401 "Only least-significant %d of %d bytes decoded",
13402 decodable_len, len);
13403 }
13404
13405 if (item) {
13406 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13407 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13408 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13409 }
13410
13411 return item;
13412}
13413
13414/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13415proto_item *
13416proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13417 const unsigned offset, const unsigned len,
13418 const char *name, const char *fallback,
13419 const int ett, int * const *fields,
13420 const unsigned encoding, const int flags)
13421{
13422 proto_item *item = NULL((void*)0);
13423 uint64_t value;
13424
13425 if (parent_tree) {
13426 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13427 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13428 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13429 flags, true1, false0, NULL((void*)0), value) && fallback) {
13430 /* Still at first item - append 'fallback' text if any */
13431 proto_item_append_text(item, "%s", fallback);
13432 }
13433 }
13434
13435 return item;
13436}
13437
13438proto_item *
13439proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13440 const unsigned bit_offset, const int no_of_bits,
13441 const unsigned encoding)
13442{
13443 header_field_info *hfinfo;
13444 int octet_length;
13445 int octet_offset;
13446
13447 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", 13447, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13447
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13447, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13448
13449 if (no_of_bits < 0) {
13450 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13451 }
13452 octet_length = (no_of_bits + 7) >> 3;
13453 octet_offset = bit_offset >> 3;
13454 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13455
13456 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13457 * but only after doing a bunch more work (which we can, in the common
13458 * case, shortcut here).
13459 */
13460 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13461 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", 13461
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13461, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13461, "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", 13461, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13462
13463 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13464}
13465
13466/*
13467 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13468 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13469 * Offset should be given in bits from the start of the tvb.
13470 */
13471
13472static proto_item *
13473_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13474 const unsigned bit_offset, const int no_of_bits,
13475 uint64_t *return_value, const unsigned encoding)
13476{
13477 int offset;
13478 unsigned length;
13479 uint8_t tot_no_bits;
13480 char *bf_str;
13481 char lbl_str[ITEM_LABEL_LENGTH240];
13482 uint64_t value = 0;
13483 uint8_t *bytes = NULL((void*)0);
13484 size_t bytes_length = 0;
13485
13486 proto_item *pi;
13487 header_field_info *hf_field;
13488
13489 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13490 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", 13490, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13490
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13490, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13491
13492 if (hf_field->bitmask != 0) {
13493 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)
13494 " 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)
13495 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)
;
13496 }
13497
13498 if (no_of_bits < 0) {
13499 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13500 } else if (no_of_bits == 0) {
13501 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)
13502 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)
;
13503 }
13504
13505 /* Byte align offset */
13506 offset = bit_offset>>3;
13507
13508 /*
13509 * Calculate the number of octets used to hold the bits
13510 */
13511 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13512 length = (tot_no_bits + 7) >> 3;
13513
13514 if (no_of_bits < 65) {
13515 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13516 } else if (hf_field->type != FT_BYTES) {
13517 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)
13518 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)
;
13519 return NULL((void*)0);
13520 }
13521
13522 /* Sign extend for signed types */
13523 switch (hf_field->type) {
13524 case FT_INT8:
13525 case FT_INT16:
13526 case FT_INT24:
13527 case FT_INT32:
13528 case FT_INT40:
13529 case FT_INT48:
13530 case FT_INT56:
13531 case FT_INT64:
13532 value = ws_sign_ext64(value, no_of_bits);
13533 break;
13534
13535 default:
13536 break;
13537 }
13538
13539 if (return_value) {
13540 *return_value = value;
13541 }
13542
13543 /* Coast clear. Try and fake it */
13544 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13545 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", 13545
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13545, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13545, "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", 13545, __func__, "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); } } }
;
13546
13547 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13548
13549 switch (hf_field->type) {
13550 case FT_BOOLEAN:
13551 /* Boolean field */
13552 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13553 "%s = %s: %s",
13554 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13555 break;
13556
13557 case FT_CHAR:
13558 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13559 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13560 break;
13561
13562 case FT_UINT8:
13563 case FT_UINT16:
13564 case FT_UINT24:
13565 case FT_UINT32:
13566 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13567 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13568 break;
13569
13570 case FT_INT8:
13571 case FT_INT16:
13572 case FT_INT24:
13573 case FT_INT32:
13574 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13575 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13576 break;
13577
13578 case FT_UINT40:
13579 case FT_UINT48:
13580 case FT_UINT56:
13581 case FT_UINT64:
13582 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13583 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13584 break;
13585
13586 case FT_INT40:
13587 case FT_INT48:
13588 case FT_INT56:
13589 case FT_INT64:
13590 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13591 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13592 break;
13593
13594 case FT_BYTES:
13595 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13596 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13597 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13598 proto_item_set_text(pi, "%s", lbl_str);
13599 return pi;
13600
13601 /* TODO: should handle FT_UINT_BYTES ? */
13602
13603 default:
13604 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))
13605 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))
13606 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))
13607 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))
;
13608 return NULL((void*)0);
13609 }
13610
13611 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13612 return pi;
13613}
13614
13615proto_item *
13616proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13617 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13618 uint64_t *return_value)
13619{
13620 proto_item *pi;
13621 int no_of_bits;
13622 int octet_offset;
13623 unsigned mask_initial_bit_offset;
13624 unsigned mask_greatest_bit_offset;
13625 unsigned octet_length;
13626 uint8_t i;
13627 char bf_str[256];
13628 char lbl_str[ITEM_LABEL_LENGTH240];
13629 uint64_t value;
13630 uint64_t composite_bitmask;
13631 uint64_t composite_bitmap;
13632
13633 header_field_info *hf_field;
13634
13635 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13636 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", 13636, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13636
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13636, "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
13637
13638 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13639 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)
13640 " 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)
13641 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)
;
13642 }
13643
13644 mask_initial_bit_offset = bit_offset % 8;
13645
13646 no_of_bits = 0;
13647 value = 0;
13648 i = 0;
13649 mask_greatest_bit_offset = 0;
13650 composite_bitmask = 0;
13651 composite_bitmap = 0;
13652
13653 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
13654 uint64_t crumb_mask, crumb_value;
13655 uint8_t crumb_end_bit_offset;
13656
13657 crumb_value = tvb_get_bits64(tvb,
13658 bit_offset + crumb_spec[i].crumb_bit_offset,
13659 crumb_spec[i].crumb_bit_length,
13660 ENC_BIG_ENDIAN0x00000000);
13661 value += crumb_value;
13662 no_of_bits += crumb_spec[i].crumb_bit_length;
13663 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", 13663
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13664
13665 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13666 octet containing the initial offset.
13667 If the mask is beyond 32 bits, then give up on bit map display.
13668 This could be improved in future, probably showing a table
13669 of 32 or 64 bits per row */
13670 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13671 crumb_end_bit_offset = mask_initial_bit_offset
13672 + crumb_spec[i].crumb_bit_offset
13673 + crumb_spec[i].crumb_bit_length;
13674 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'
13675
13676 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13677 mask_greatest_bit_offset = crumb_end_bit_offset;
13678 }
13679 /* Currently the bitmap of the crumbs are only shown if
13680 * smaller than 32 bits. Do not bother calculating the
13681 * mask if it is larger than that. */
13682 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13683 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'
13684 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13685 }
13686 }
13687 /* Shift left for the next segment */
13688 value <<= crumb_spec[++i].crumb_bit_length;
13689 }
13690
13691 /* Sign extend for signed types */
13692 switch (hf_field->type) {
13693 case FT_INT8:
13694 case FT_INT16:
13695 case FT_INT24:
13696 case FT_INT32:
13697 case FT_INT40:
13698 case FT_INT48:
13699 case FT_INT56:
13700 case FT_INT64:
13701 value = ws_sign_ext64(value, no_of_bits);
13702 break;
13703 default:
13704 break;
13705 }
13706
13707 if (return_value) {
13708 *return_value = value;
13709 }
13710
13711 /* Coast clear. Try and fake it */
13712 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13713 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", 13713
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13713, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13713, "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", 13713, __func__, "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); } } }
;
13714
13715 /* initialise the format string */
13716 bf_str[0] = '\0';
13717
13718 octet_offset = bit_offset >> 3;
13719
13720 /* Round up mask length to nearest octet */
13721 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13722 mask_greatest_bit_offset = octet_length << 3;
13723
13724 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13725 It would be a useful enhancement to eliminate this restriction. */
13726 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13727 other_decode_bitfield_value(bf_str,
13728 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13729 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13730 mask_greatest_bit_offset);
13731 } else {
13732 /* If the bitmask is too large, try to describe its contents. */
13733 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13734 }
13735
13736 switch (hf_field->type) {
13737 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13738 /* Boolean field */
13739 return proto_tree_add_boolean_format(tree, hfindex,
13740 tvb, octet_offset, octet_length, value,
13741 "%s = %s: %s",
13742 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13743 break;
13744
13745 case FT_CHAR:
13746 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13747 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13748 break;
13749
13750 case FT_UINT8:
13751 case FT_UINT16:
13752 case FT_UINT24:
13753 case FT_UINT32:
13754 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13755 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13756 break;
13757
13758 case FT_INT8:
13759 case FT_INT16:
13760 case FT_INT24:
13761 case FT_INT32:
13762 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13763 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13764 break;
13765
13766 case FT_UINT40:
13767 case FT_UINT48:
13768 case FT_UINT56:
13769 case FT_UINT64:
13770 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13771 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13772 break;
13773
13774 case FT_INT40:
13775 case FT_INT48:
13776 case FT_INT56:
13777 case FT_INT64:
13778 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13779 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13780 break;
13781
13782 default:
13783 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))
13784 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))
13785 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))
13786 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))
;
13787 return NULL((void*)0);
13788 }
13789 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13790 return pi;
13791}
13792
13793void
13794proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13795 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13796{
13797 header_field_info *hfinfo;
13798 int start = bit_offset >> 3;
13799 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13800
13801 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13802 * so that we can use the tree's memory scope in calculating the string */
13803 if (length == -1) {
13804 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13805 } else {
13806 tvb_ensure_bytes_exist(tvb, start, length);
13807 }
13808 if (!tree) return;
13809
13810 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", 13810, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13810
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13810, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13811 proto_tree_add_text_internal(tree, tvb, start, length,
13812 "%s crumb %d of %s (decoded above)",
13813 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13814 tvb_get_bits32(tvb,
13815 bit_offset,
13816 crumb_spec[crumb_index].crumb_bit_length,
13817 ENC_BIG_ENDIAN0x00000000),
13818 ENC_BIG_ENDIAN0x00000000),
13819 crumb_index,
13820 hfinfo->name);
13821}
13822
13823proto_item *
13824proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13825 const unsigned bit_offset, const int no_of_bits,
13826 uint64_t *return_value, const unsigned encoding)
13827{
13828 proto_item *item;
13829
13830 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13831 bit_offset, no_of_bits,
13832 return_value, encoding))) {
13833 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)
;
13834 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)
;
13835 }
13836 return item;
13837}
13838
13839static proto_item *
13840_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13841 tvbuff_t *tvb, const unsigned bit_offset,
13842 const int no_of_bits, void *value_ptr,
13843 const unsigned encoding, char *value_str)
13844{
13845 int offset;
13846 unsigned length;
13847 uint8_t tot_no_bits;
13848 char *str;
13849 uint64_t value = 0;
13850 header_field_info *hf_field;
13851
13852 /* We do not have to return a value, try to fake it as soon as possible */
13853 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13854 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", 13854
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13854, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13854, "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", 13854, __func__, "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); } } }
;
13855
13856 if (hf_field->bitmask != 0) {
13857 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)
13858 " 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)
13859 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)
;
13860 }
13861
13862 if (no_of_bits < 0) {
13863 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13864 } else if (no_of_bits == 0) {
13865 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)
13866 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)
;
13867 }
13868
13869 /* Byte align offset */
13870 offset = bit_offset>>3;
13871
13872 /*
13873 * Calculate the number of octets used to hold the bits
13874 */
13875 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13876 length = tot_no_bits>>3;
13877 /* If we are using part of the next octet, increase length by 1 */
13878 if (tot_no_bits & 0x07)
13879 length++;
13880
13881 if (no_of_bits < 65) {
13882 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13883 } else {
13884 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)
13885 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)
;
13886 return NULL((void*)0);
13887 }
13888
13889 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13890
13891 (void) g_strlcat(str, " = ", 256+64);
13892 (void) g_strlcat(str, hf_field->name, 256+64);
13893
13894 /*
13895 * This function does not receive an actual value but a dimensionless pointer to that value.
13896 * For this reason, the type of the header field is examined in order to determine
13897 * what kind of value we should read from this address.
13898 * The caller of this function must make sure that for the specific header field type the address of
13899 * a compatible value is provided.
13900 */
13901 switch (hf_field->type) {
13902 case FT_BOOLEAN:
13903 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13904 "%s: %s", str, value_str);
13905 break;
13906
13907 case FT_CHAR:
13908 case FT_UINT8:
13909 case FT_UINT16:
13910 case FT_UINT24:
13911 case FT_UINT32:
13912 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13913 "%s: %s", str, value_str);
13914 break;
13915
13916 case FT_UINT40:
13917 case FT_UINT48:
13918 case FT_UINT56:
13919 case FT_UINT64:
13920 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13921 "%s: %s", str, value_str);
13922 break;
13923
13924 case FT_INT8:
13925 case FT_INT16:
13926 case FT_INT24:
13927 case FT_INT32:
13928 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13929 "%s: %s", str, value_str);
13930 break;
13931
13932 case FT_INT40:
13933 case FT_INT48:
13934 case FT_INT56:
13935 case FT_INT64:
13936 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13937 "%s: %s", str, value_str);
13938 break;
13939
13940 case FT_FLOAT:
13941 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13942 "%s: %s", str, value_str);
13943 break;
13944
13945 default:
13946 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))
13947 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))
13948 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))
13949 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))
;
13950 return NULL((void*)0);
13951 }
13952}
13953
13954static proto_item *
13955proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13956 tvbuff_t *tvb, const unsigned bit_offset,
13957 const int no_of_bits, void *value_ptr,
13958 const unsigned encoding, char *value_str)
13959{
13960 proto_item *item;
13961
13962 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13963 tvb, bit_offset, no_of_bits,
13964 value_ptr, encoding, value_str))) {
13965 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)
;
13966 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)
;
13967 }
13968 return item;
13969}
13970
13971#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);
\
13972 va_start(ap, format)__builtin_va_start(ap, format); \
13973 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13974 va_end(ap)__builtin_va_end(ap);
13975
13976proto_item *
13977proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13978 tvbuff_t *tvb, const unsigned bit_offset,
13979 const int no_of_bits, uint32_t value,
13980 const unsigned encoding,
13981 const char *format, ...)
13982{
13983 va_list ap;
13984 char *dst;
13985 header_field_info *hf_field;
13986
13987 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13988
13989 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", 13989
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13989, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13989, "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", 13989, __func__, "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); } } }
;
13990
13991 switch (hf_field->type) {
13992 case FT_UINT8:
13993 case FT_UINT16:
13994 case FT_UINT24:
13995 case FT_UINT32:
13996 break;
13997
13998 default:
13999 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)
14000 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)
;
14001 return NULL((void*)0);
14002 }
14003
14004 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);
;
14005
14006 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14007}
14008
14009proto_item *
14010proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14011 tvbuff_t *tvb, const unsigned bit_offset,
14012 const int no_of_bits, uint64_t value,
14013 const unsigned encoding,
14014 const char *format, ...)
14015{
14016 va_list ap;
14017 char *dst;
14018 header_field_info *hf_field;
14019
14020 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14021
14022 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", 14022
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14022, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14022, "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", 14022, __func__, "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); } } }
;
14023
14024 switch (hf_field->type) {
14025 case FT_UINT40:
14026 case FT_UINT48:
14027 case FT_UINT56:
14028 case FT_UINT64:
14029 break;
14030
14031 default:
14032 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)
14033 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)
;
14034 return NULL((void*)0);
14035 }
14036
14037 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);
;
14038
14039 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14040}
14041
14042proto_item *
14043proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14044 tvbuff_t *tvb, const unsigned bit_offset,
14045 const int no_of_bits, float value,
14046 const unsigned encoding,
14047 const char *format, ...)
14048{
14049 va_list ap;
14050 char *dst;
14051 header_field_info *hf_field;
14052
14053 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14054
14055 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", 14055
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14055, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14055, "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", 14055, __func__, "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); } } }
;
14056
14057 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",
14057, ((hf_field))->abbrev))))
;
14058
14059 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);
;
14060
14061 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14062}
14063
14064proto_item *
14065proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14066 tvbuff_t *tvb, const unsigned bit_offset,
14067 const int no_of_bits, int32_t value,
14068 const unsigned encoding,
14069 const char *format, ...)
14070{
14071 va_list ap;
14072 char *dst;
14073 header_field_info *hf_field;
14074
14075 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14076
14077 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", 14077
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14077, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14077, "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", 14077, __func__, "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); } } }
;
14078
14079 switch (hf_field->type) {
14080 case FT_INT8:
14081 case FT_INT16:
14082 case FT_INT24:
14083 case FT_INT32:
14084 break;
14085
14086 default:
14087 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)
14088 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)
;
14089 return NULL((void*)0);
14090 }
14091
14092 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);
;
14093
14094 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14095}
14096
14097proto_item *
14098proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14099 tvbuff_t *tvb, const unsigned bit_offset,
14100 const int no_of_bits, int64_t value,
14101 const unsigned encoding,
14102 const char *format, ...)
14103{
14104 va_list ap;
14105 char *dst;
14106 header_field_info *hf_field;
14107
14108 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14109
14110 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", 14110
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14110, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14110, "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", 14110, __func__, "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); } } }
;
14111
14112 switch (hf_field->type) {
14113 case FT_INT40:
14114 case FT_INT48:
14115 case FT_INT56:
14116 case FT_INT64:
14117 break;
14118
14119 default:
14120 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)
14121 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)
;
14122 return NULL((void*)0);
14123 }
14124
14125 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);
;
14126
14127 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14128}
14129
14130proto_item *
14131proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14132 tvbuff_t *tvb, const unsigned bit_offset,
14133 const int no_of_bits, uint64_t value,
14134 const unsigned encoding,
14135 const char *format, ...)
14136{
14137 va_list ap;
14138 char *dst;
14139 header_field_info *hf_field;
14140
14141 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14142
14143 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", 14143
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14143, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14143, "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", 14143, __func__, "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); } } }
;
14144
14145 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"
, 14145, ((hf_field))->abbrev))))
;
14146
14147 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);
;
14148
14149 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14150}
14151
14152proto_item *
14153proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14154 const unsigned bit_offset, const int no_of_chars)
14155{
14156 proto_item *pi;
14157 header_field_info *hfinfo;
14158 int byte_length;
14159 int byte_offset;
14160 char *string;
14161
14162 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14163
14164 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", 14164
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14164, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14164, "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", 14164, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14165
14166 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"
, 14166, ((hfinfo))->abbrev))))
;
14167
14168 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14169 byte_offset = bit_offset >> 3;
14170
14171 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14172
14173 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14174 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14174, "byte_length >= 0"
))))
;
14175 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14176
14177 return pi;
14178}
14179
14180proto_item *
14181proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14182 const unsigned bit_offset, const int no_of_chars)
14183{
14184 proto_item *pi;
14185 header_field_info *hfinfo;
14186 int byte_length;
14187 int byte_offset;
14188 char *string;
14189
14190 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14191
14192 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", 14192
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14192, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14192, "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", 14192, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14193
14194 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"
, 14194, ((hfinfo))->abbrev))))
;
14195
14196 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14197 byte_offset = bit_offset >> 3;
14198
14199 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14200
14201 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14202 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14202, "byte_length >= 0"
))))
;
14203 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14204
14205 return pi;
14206}
14207
14208const value_string proto_checksum_vals[] = {
14209 { PROTO_CHECKSUM_E_BAD, "Bad" },
14210 { PROTO_CHECKSUM_E_GOOD, "Good" },
14211 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14212 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14213 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14214
14215 { 0, NULL((void*)0) }
14216};
14217
14218#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14219
14220proto_item *
14221proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14222 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14223 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14224{
14225 header_field_info *hfinfo;
14226 uint32_t checksum;
14227 uint32_t len;
14228 proto_item* ti = NULL((void*)0);
14229 proto_item* ti2;
14230 bool_Bool incorrect_checksum = true1;
14231
14232 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", 14232, __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", 14232
, "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", 14232, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14233
14234 switch (hfinfo->type) {
14235 case FT_UINT8:
14236 len = 1;
14237 break;
14238 case FT_UINT16:
14239 len = 2;
14240 break;
14241 case FT_UINT24:
14242 len = 3;
14243 break;
14244 case FT_UINT32:
14245 len = 4;
14246 break;
14247 default:
14248 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)
14249 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14250 }
14251
14252 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14253 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14254 proto_item_set_generated(ti);
14255 // Backward compatible with use of -1
14256 if (hf_checksum_status > 0) {
14257 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14258 proto_item_set_generated(ti2);
14259 }
14260 return ti;
14261 }
14262
14263 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14264 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14265 proto_item_set_generated(ti);
14266 } else {
14267 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14268 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14269 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14270 if (computed_checksum == 0) {
14271 proto_item_append_text(ti, " [correct]");
14272 // Backward compatible with use of -1
14273 if (hf_checksum_status > 0) {
14274 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14275 proto_item_set_generated(ti2);
14276 }
14277 incorrect_checksum = false0;
14278 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14279 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14280 /* XXX - This can't distinguish between "shouldbe"
14281 * 0x0000 and 0xFFFF unless we know whether there
14282 * were any nonzero bits (other than the checksum).
14283 * Protocols should not use this path if they might
14284 * have an all zero packet.
14285 * Some implementations put the wrong zero; maybe
14286 * we should have a special expert info for that?
14287 */
14288 }
14289 } else {
14290 if (checksum == computed_checksum) {
14291 proto_item_append_text(ti, " [correct]");
14292 // Backward compatible with use of -1
14293 if (hf_checksum_status > 0) {
14294 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14295 proto_item_set_generated(ti2);
14296 }
14297 incorrect_checksum = false0;
14298 }
14299 }
14300
14301 if (incorrect_checksum) {
14302 // Backward compatible with use of -1
14303 if (hf_checksum_status > 0) {
14304 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14305 proto_item_set_generated(ti2);
14306 }
14307 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14308 proto_item_append_text(ti, " [incorrect]");
14309 if (bad_checksum_expert != NULL((void*)0))
14310 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14311 } else {
14312 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14313 if (bad_checksum_expert != NULL((void*)0))
14314 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);
14315 }
14316 }
14317 } else {
14318 // Backward compatible with use of -1
14319 if (hf_checksum_status > 0) {
14320 proto_item_append_text(ti, " [unverified]");
14321 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14322 proto_item_set_generated(ti2);
14323 }
14324 }
14325 }
14326
14327 return ti;
14328}
14329
14330proto_item *
14331proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14332 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14333 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14334{
14335 header_field_info *hfinfo;
14336 uint8_t *checksum = NULL((void*)0);
14337 proto_item* ti = NULL((void*)0);
14338 proto_item* ti2;
14339 bool_Bool incorrect_checksum = true1;
14340
14341 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", 14341, __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", 14341
, "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", 14341, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14342
14343 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",
14343, ((hfinfo))->abbrev))))
;
14344
14345 /* Make sure a NULL computed_checksum isn't dereferenced.
14346 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14347 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14348 * cases the behavior is unexpected and still a programmer error;
14349 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14350 * _NOT_PRESENT nor _GENERATED is correct.
14351 */
14352 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", 14352, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14353
14354 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14355 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14356 proto_item_set_generated(ti);
14357 // Backward compatible with use of -1
14358 if (hf_checksum_status > 0) {
14359 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14360 proto_item_set_generated(ti2);
14361 }
14362 return ti;
14363 }
14364
14365 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14366 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14367 proto_item_set_generated(ti);
14368 return ti;
14369 }
14370
14371 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14372 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14373 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14374 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14375 bool_Bool non_zero_flag = false0;
14376 for (size_t index = 0; index < checksum_len; index++) {
14377 if (computed_checksum[index]) {
14378 non_zero_flag = true1;
14379 break;
14380 }
14381 }
14382 if (!non_zero_flag) {
14383 proto_item_append_text(ti, " [correct]");
14384 // Backward compatible with use of -1
14385 if (hf_checksum_status > 0) {
14386 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14387 proto_item_set_generated(ti2);
14388 }
14389 incorrect_checksum = false0;
14390 }
14391 } else {
14392 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14393 proto_item_append_text(ti, " [correct]");
14394 // Backward compatible with use of -1
14395 if (hf_checksum_status > 0) {
14396 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14397 proto_item_set_generated(ti2);
14398 }
14399 incorrect_checksum = false0;
14400 }
14401 }
14402
14403 if (incorrect_checksum) {
14404 // Backward compatible with use of -1
14405 if (hf_checksum_status > 0) {
14406 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14407 proto_item_set_generated(ti2);
14408 }
14409 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14410 proto_item_append_text(ti, " [incorrect]");
14411 if (bad_checksum_expert != NULL((void*)0))
14412 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14413 } else {
14414 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14415 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14416 if (bad_checksum_expert != NULL((void*)0))
14417 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14418 }
14419 }
14420 } else {
14421 // Backward compatible with use of -1
14422 if (hf_checksum_status > 0) {
14423 proto_item_append_text(ti, " [unverified]");
14424 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14425 proto_item_set_generated(ti2);
14426 }
14427 }
14428
14429 return ti;
14430}
14431
14432unsigned char
14433proto_check_field_name(const char *field_name)
14434{
14435 return module_check_valid_name(field_name, false0);
14436}
14437
14438unsigned char
14439proto_check_field_name_lower(const char *field_name)
14440{
14441 return module_check_valid_name(field_name, true1);
14442}
14443
14444bool_Bool
14445tree_expanded(int tree_type)
14446{
14447 if (tree_type <= 0) {
14448 return false0;
14449 }
14450 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", 14450, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14451 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14452}
14453
14454void
14455tree_expanded_set(int tree_type, bool_Bool value)
14456{
14457 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", 14457, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14458
14459 if (value)
14460 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14461 else
14462 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14463}
14464
14465/*
14466 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14467 *
14468 * Local variables:
14469 * c-basic-offset: 8
14470 * tab-width: 8
14471 * indent-tabs-mode: t
14472 * End:
14473 *
14474 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14475 * :indentSize=8:tabSize=8:noTabs=false:
14476 */