Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-10-31-100325-3623-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#include "register-int.h"
57
58#include <wsutil/crash_info.h>
59#include <wsutil/epochs.h>
60
61/* Ptvcursor limits */
62#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
63#define SUBTREE_MAX_LEVELS256 256
64
65typedef struct __subtree_lvl {
66 int cursor_offset;
67 proto_item *it;
68 proto_tree *tree;
69} subtree_lvl;
70
71struct ptvcursor {
72 wmem_allocator_t *scope;
73 subtree_lvl *pushed_tree;
74 uint8_t pushed_tree_index;
75 uint8_t pushed_tree_max;
76 proto_tree *tree;
77 tvbuff_t *tvb;
78 int offset;
79};
80
81#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
82
83/** See inlined comments.
84 @param tree the tree to append this item to
85 @param free_block a code block to call to free resources if this returns
86 @return NULL if 'tree' is null */
87#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
88 if (!tree) { \
89 free_block; \
90 return NULL((void*)0); \
91 }
92
93/** See inlined comments.
94 @param tree the tree to append this item to
95 @return NULL if 'tree' is null */
96#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
97 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
98
99/** See inlined comments.
100 @param length the length of this item
101 @param cleanup_block a code block to call to free resources if this returns
102 @return NULL if 'length' is lower -1 or equal 0 */
103#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
104 if (length < -1 || length == 0 ) { \
105 cleanup_block; \
106 return NULL((void*)0); \
107 }
108
109/** See inlined comments.
110 @param length the length of this item
111 @return NULL if 'length' is lower -1 or equal 0 */
112#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
113 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
114
115/** See inlined comments.
116 @param tree the tree to append this item to
117 @param hfindex field index
118 @param hfinfo header_field
119 @param free_block a code block to call to free resources if this returns
120 @return the header field matching 'hfinfo' */
121#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", 121
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 121, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 121, "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", 121, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
); } } }
\
122 /* If the tree is not visible and this item is not referenced \
123 we don't have to do much work at all but we should still \
124 return a node so that referenced field items below this node \
125 (think proto_item_add_subtree()) will still have somewhere \
126 to attach to or else filtering will not work (they would be \
127 ignored since tree would be NULL). \
128 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
129 because that means we can change its length or repr, and we \
130 don't want to do so with calls intended for this faked new \
131 item, so this item needs a new (hidden) child node. \
132 We fake FT_PROTOCOL unless some clients have requested us \
133 not to do so. \
134 */ \
135 PTREE_DATA(tree)((tree)->tree_data)->count++; \
136 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", 136, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 136, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 136, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
137 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
138 free_block; \
139 if (wireshark_abort_on_too_many_items) \
140 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", 141
, __func__, "Adding %s would put more than %d 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 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 141
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
142 /* Let the exception handler add items to the tree */ \
143 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
144 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)))
145 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)))
146 "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)))
147 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)))
; \
148 } \
149 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
150 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
151 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
152 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
153 && (hfinfo->type != FT_PROTOCOL || \
154 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
155 free_block; \
156 /* return fake node with no field info */\
157 return proto_tree_add_fake_node(tree, hfinfo); \
158 } \
159 } \
160 }
161
162/** See inlined comments.
163 @param tree the tree to append this item to
164 @param hfindex field index
165 @param hfinfo header_field
166 @return the header field matching 'hfinfo' */
167#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", 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 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", 168
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 168, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 168, "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", 168, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
169
170
171/** See inlined comments.
172 @param pi the created protocol item we're about to return */
173#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
174 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 174, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
175 if (!PITEM_FINFO(pi)((pi)->finfo)) \
176 return pi; \
177 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
178 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
179 /* If the tree (GUI) or item isn't visible it's pointless for \
180 * us to generate the protocol item's string representation */ \
181 return pi; \
182 }
183/* Same as above but returning void */
184#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
185 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
186 return; \
187 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
188 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
189 /* If the tree (GUI) or item isn't visible it's pointless for \
190 * us to generate the protocol item's string representation */ \
191 return; \
192 }
193/* Similar to above, but allows a NULL tree */
194#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; }
\
195 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
196 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
197 /* If the tree (GUI) or item isn't visible it's pointless for \
198 * us to generate the protocol item's string representation */ \
199 return pi; \
200 }
201
202#ifdef ENABLE_CHECK_FILTER
203#define CHECK_HF_VALUE(type, spec, start_values) \
204{ \
205 const type *current; \
206 int n, m; \
207 current = start_values; \
208 for (n=0; current; n++, current++) { \
209 /* Drop out if we reached the end. */ \
210 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
211 break; \
212 } \
213 /* Check value against all previous */ \
214 for (m=0; m < n; m++) { \
215 /* There are lots of duplicates with the same string, \
216 so only report if different... */ \
217 if ((start_values[m].value == current->value) && \
218 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
219 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222
, __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 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222
, __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 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222
, __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 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222
, __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)
; \
223 } \
224 } \
225 } \
226}
227#endif
228
229/* The longest NUMBER-like field label we have is for BASE_OUI, which
230 * can have up to 64 bytes for the manufacturer name if resolved plus
231 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
232 */
233#define NUMBER_LABEL_LENGTH80 80
234
235static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
236static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
237static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
238static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
239static int hfinfo_bitoffset(const header_field_info *hfinfo);
240static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
241static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
242
243#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
244 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
245
246static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
247static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
248
249static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
251static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
253static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
254static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
256
257static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
258static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
259static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
260static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
261
262static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
263static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
264static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
265static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
266static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
269static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
270static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
271static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
272static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
273
274static void proto_cleanup_base(void);
275
276static proto_item *
277proto_tree_add_node(proto_tree *tree, field_info *fi);
278
279static proto_item *
280proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
281
282static void
283get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
284 int *item_length, const unsigned encoding);
285
286static int
287get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
288 int length, unsigned item_length, const int encoding);
289
290static field_info *
291new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
292 const int start, const int item_length);
293
294static proto_item *
295proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
296 int start, int *length);
297
298static void
299proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
300static void
301proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
302
303static void
304proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
305static void
306proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
307static void
308proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
309static void
310proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
311static void
312proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
313static void
314proto_tree_set_string(field_info *fi, const char* value);
315static void
316proto_tree_set_ax25(field_info *fi, const uint8_t* value);
317static void
318proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
319static void
320proto_tree_set_vines(field_info *fi, const uint8_t* value);
321static void
322proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
323static void
324proto_tree_set_ether(field_info *fi, const uint8_t* value);
325static void
326proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
327static void
328proto_tree_set_ipxnet(field_info *fi, uint32_t value);
329static void
330proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
331static void
332proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
333static void
334proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
335static void
336proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
337static void
338proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
339static void
340proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
341static void
342proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
343static void
344proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
345static void
346proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
347static void
348proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
349static void
350proto_tree_set_boolean(field_info *fi, uint64_t value);
351static void
352proto_tree_set_float(field_info *fi, float value);
353static void
354proto_tree_set_double(field_info *fi, double value);
355static void
356proto_tree_set_uint(field_info *fi, uint32_t value);
357static void
358proto_tree_set_int(field_info *fi, int32_t value);
359static void
360proto_tree_set_uint64(field_info *fi, uint64_t value);
361static void
362proto_tree_set_int64(field_info *fi, int64_t value);
363static void
364proto_tree_set_eui64(field_info *fi, const uint64_t value);
365static void
366proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
367
368/* Handle type length mismatch (now filterable) expert info */
369static int proto_type_length_mismatch;
370static expert_field ei_type_length_mismatch_error;
371static expert_field ei_type_length_mismatch_warn;
372static void register_type_length_mismatch(void);
373
374/* Handle byte array string decoding errors with expert info */
375static int proto_byte_array_string_decoding_error;
376static expert_field ei_byte_array_string_decoding_failed_error;
377static void register_byte_array_string_decodinws_error(void);
378
379/* Handle date and time string decoding errors with expert info */
380static int proto_date_time_string_decoding_error;
381static expert_field ei_date_time_string_decoding_failed_error;
382static void register_date_time_string_decodinws_error(void);
383
384/* Handle string errors expert info */
385static int proto_string_errors;
386static expert_field ei_string_trailing_characters;
387static void register_string_errors(void);
388
389static int proto_register_field_init(header_field_info *hfinfo, const int parent);
390
391/* special-case header field used within proto.c */
392static header_field_info hfi_text_only =
393 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
394int hf_text_only;
395
396/* Structure for information about a protocol */
397struct _protocol {
398 const char *name; /* long description */
399 const char *short_name; /* short description */
400 const char *filter_name; /* name of this protocol in filters */
401 GPtrArray *fields; /* fields for this protocol */
402 int proto_id; /* field ID for this protocol */
403 bool_Bool is_enabled; /* true if protocol is enabled */
404 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
405 bool_Bool can_toggle; /* true if is_enabled can be changed */
406 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
407 For dissectors that need a protocol name so they
408 can be added to a dissector table, but use the
409 parent_proto_id for things like enable/disable */
410 GList *heur_list; /* Heuristic dissectors associated with this protocol */
411};
412
413/* List of all protocols */
414static GList *protocols;
415
416/* Structure stored for deregistered g_slice */
417struct g_slice_data {
418 size_t block_size;
419 void *mem_block;
420};
421
422/* Deregistered fields */
423static GPtrArray *deregistered_fields;
424static GPtrArray *deregistered_data;
425static GPtrArray *deregistered_slice;
426
427/* indexed by prefix, contains initializers */
428static GHashTable* prefixes;
429
430/* Contains information about a field when a dissector calls
431 * proto_tree_add_item. */
432#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)))
433#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
434
435/* Contains the space for proto_nodes. */
436#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
437 node->first_child = NULL((void*)0); \
438 node->last_child = NULL((void*)0); \
439 node->next = NULL((void*)0);
440
441#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
442 wmem_free(pool, node)
443
444/* String space for protocol and field items for the GUI */
445#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;
\
446 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
447 il->value_pos = 0; \
448 il->value_len = 0;
449#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
450 wmem_free(pool, il);
451
452#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", 452, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 452, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 452, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
453 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
454 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 454
, __func__, "Unregistered hf! index=%d", hfindex)
; \
455 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", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
456 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", 456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
457 hfinfo = gpa_hfinfo.hfi[hfindex];
458
459#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
460
461/* List which stores protocols and fields that have been registered */
462typedef struct _gpa_hfinfo_t {
463 uint32_t len;
464 uint32_t allocated_len;
465 header_field_info **hfi;
466} gpa_hfinfo_t;
467
468static gpa_hfinfo_t gpa_hfinfo;
469
470/* Hash table of abbreviations and IDs */
471static wmem_map_t *gpa_name_map;
472static header_field_info *same_name_hfinfo;
473
474/* Hash table protocol aliases. const char * -> const char * */
475static GHashTable *gpa_protocol_aliases;
476
477/*
478 * We're called repeatedly with the same field name when sorting a column.
479 * Cache our last gpa_name_map hit for faster lookups.
480 */
481static char *last_field_name;
482static header_field_info *last_hfinfo;
483
484/* Points to the first element of an array of bits, indexed by
485 a subtree item type; that array element is true if subtrees of
486 an item of that type are to be expanded. */
487static uint32_t *tree_is_expanded;
488
489/* Number of elements in that array. The entry with index 0 is not used. */
490int num_tree_types = 1;
491
492/* Name hashtables for fast detection of duplicate names */
493static GHashTable* proto_names;
494static GHashTable* proto_short_names;
495static GHashTable* proto_filter_names;
496
497static const char *reserved_filter_names[] = {
498 /* Display filter keywords. */
499 "eq",
500 "ne",
501 "all_eq",
502 "any_eq",
503 "all_ne",
504 "any_ne",
505 "gt",
506 "ge",
507 "lt",
508 "le",
509 "bitand",
510 "bitwise_and",
511 "contains",
512 "matches",
513 "not",
514 "and",
515 "or",
516 "xor",
517 "in",
518 "any",
519 "all",
520 "true",
521 "false",
522 "nan",
523 "inf",
524 "infinity",
525 NULL((void*)0)
526};
527
528static GHashTable *proto_reserved_filter_names;
529static GQueue* saved_dir_queue;
530
531static int
532proto_compare_name(const void *p1_arg, const void *p2_arg)
533{
534 const protocol_t *p1 = (const protocol_t *)p1_arg;
535 const protocol_t *p2 = (const protocol_t *)p2_arg;
536
537 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
538}
539
540static GSList *dissector_plugins;
541
542#ifdef HAVE_PLUGINS1
543void
544proto_register_plugin(const proto_plugin *plug)
545{
546 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
547}
548#else /* HAVE_PLUGINS */
549void
550proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
551{
552 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 552, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
553}
554#endif /* HAVE_PLUGINS */
555
556static void
557call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
558{
559 proto_plugin *plug = (proto_plugin *)data;
560
561 if (plug->register_protoinfo) {
562 plug->register_protoinfo();
563 }
564}
565
566static void
567call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
568{
569 proto_plugin *plug = (proto_plugin *)data;
570
571 if (plug->register_handoff) {
572 plug->register_handoff();
573 }
574}
575
576void proto_pre_init(void)
577{
578 saved_dir_queue = g_queue_new();
579
580 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
581 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
582 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
583
584 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 for (const char** ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
586 /* GHashTable has no key destructor so the cast is safe. */
587 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
588 }
589
590 gpa_hfinfo.len = 0;
591 gpa_hfinfo.allocated_len = 0;
592 gpa_hfinfo.hfi = NULL((void*)0);
593 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
594 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
595 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
596 deregistered_fields = g_ptr_array_new();
597 deregistered_data = g_ptr_array_new();
598 deregistered_slice = g_ptr_array_new();
599}
600
601/* initialize data structures and register protocols and fields */
602void
603proto_init(GSList *register_all_plugin_protocols_list,
604 GSList *register_all_plugin_handoffs_list,
605 register_cb cb,
606 void *client_data)
607{
608 /* Initialize the ftype subsystem */
609 ftypes_initialize();
610
611 /* Initialize the address type subsystem */
612 address_types_initialize();
613
614 /* Register one special-case FT_TEXT_ONLY field for use when
615 converting wireshark to new-style proto_tree. These fields
616 are merely strings on the GUI tree; they are not filterable */
617 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
618
619 /* Register the pseudo-protocols used for exceptions. */
620 register_show_exception();
621 register_type_length_mismatch();
622 register_byte_array_string_decodinws_error();
623 register_date_time_string_decodinws_error();
624 register_string_errors();
625 ftypes_register_pseudofields();
626 col_register_protocol();
627
628 /* Have each built-in dissector register its protocols, fields,
629 dissector tables, and dissectors to be called through a
630 handle, and do whatever one-time initialization it needs to
631 do. */
632 register_all_protocols(cb, client_data);
633
634 /* Now call the registration routines for all epan plugins. */
635 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
636 ((void (*)(register_cb, void *))l->data)(cb, client_data);
637 }
638
639 /* Now call the registration routines for all dissector plugins. */
640 if (cb)
641 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
642 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
643
644 /* Now call the "handoff registration" routines of all built-in
645 dissectors; those routines register the dissector in other
646 dissectors' handoff tables, and fetch any dissector handles
647 they need. */
648 register_all_protocol_handoffs(cb, client_data);
649
650 /* Now do the same with epan plugins. */
651 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
652 ((void (*)(register_cb, void *))l->data)(cb, client_data);
653 }
654
655 /* Now do the same with dissector plugins. */
656 if (cb)
657 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
658 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
659
660 /* sort the protocols by protocol name */
661 protocols = g_list_sort(protocols, proto_compare_name);
662
663 /* sort the dissector handles in dissector tables (for -G reports
664 * and -d error messages. The GUI sorts the handles itself.) */
665 packet_all_tables_sort_handles();
666
667 /* We've assigned all the subtree type values; allocate the array
668 for them, and zero it out. */
669 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
)))
;
670}
671
672static void
673proto_cleanup_base(void)
674{
675 protocol_t *protocol;
676 header_field_info *hfinfo;
677
678 /* Free the abbrev/ID hash table */
679 if (gpa_name_map) {
680 // XXX - We don't have a wmem_map_destroy, but
681 // it does get cleaned up when epan scope is
682 // destroyed
683 //g_hash_table_destroy(gpa_name_map);
684 gpa_name_map = NULL((void*)0);
685 }
686 if (gpa_protocol_aliases) {
687 g_hash_table_destroy(gpa_protocol_aliases);
688 gpa_protocol_aliases = NULL((void*)0);
689 }
690 g_free(last_field_name);
691 last_field_name = NULL((void*)0);
692
693 while (protocols) {
694 protocol = (protocol_t *)protocols->data;
695 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", 695
, __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", 695, "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", 695, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
696 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", 696, "protocol->proto_id == hfinfo->id"
))))
;
697
698 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)
;
699 if (protocol->parent_proto_id != -1) {
700 // pino protocol
701 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 701, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
702 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"
, 702, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
703 } else {
704 if (protocol->fields) {
705 g_ptr_array_free(protocol->fields, true1);
706 }
707 g_list_free(protocol->heur_list);
708 }
709 protocols = g_list_remove(protocols, protocol);
710 g_free(protocol);
711 }
712
713 if (proto_names) {
714 g_hash_table_destroy(proto_names);
715 proto_names = NULL((void*)0);
716 }
717
718 if (proto_short_names) {
719 g_hash_table_destroy(proto_short_names);
720 proto_short_names = NULL((void*)0);
721 }
722
723 if (proto_filter_names) {
724 g_hash_table_destroy(proto_filter_names);
725 proto_filter_names = NULL((void*)0);
726 }
727
728 if (proto_reserved_filter_names) {
729 g_hash_table_destroy(proto_reserved_filter_names);
730 proto_reserved_filter_names = NULL((void*)0);
731 }
732
733 if (gpa_hfinfo.allocated_len) {
734 gpa_hfinfo.len = 0;
735 gpa_hfinfo.allocated_len = 0;
736 g_free(gpa_hfinfo.hfi);
737 gpa_hfinfo.hfi = NULL((void*)0);
738 }
739
740 if (deregistered_fields) {
741 g_ptr_array_free(deregistered_fields, true1);
742 deregistered_fields = NULL((void*)0);
743 }
744
745 if (deregistered_data) {
746 g_ptr_array_free(deregistered_data, true1);
747 deregistered_data = NULL((void*)0);
748 }
749
750 if (deregistered_slice) {
751 g_ptr_array_free(deregistered_slice, true1);
752 deregistered_slice = NULL((void*)0);
753 }
754
755 g_free(tree_is_expanded);
756 tree_is_expanded = NULL((void*)0);
757
758 if (prefixes)
759 g_hash_table_destroy(prefixes);
760
761 if (saved_dir_queue != NULL((void*)0)) {
762 g_queue_clear_full(saved_dir_queue, g_free);
763 g_queue_free(saved_dir_queue);
764 saved_dir_queue = NULL((void*)0);
765 }
766}
767
768void
769proto_cleanup(void)
770{
771 proto_free_deregistered_fields();
772 proto_cleanup_base();
773
774 g_slist_free(dissector_plugins);
775 dissector_plugins = NULL((void*)0);
776}
777
778static bool_Bool
779ws_pushd(const char* dir)
780{
781 //Save the current working directory
782 const char* save_wd = get_current_working_dir();
783 if (save_wd != NULL((void*)0))
784 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
785
786 //Change to the new one
787#ifdef _WIN32
788 SetCurrentDirectory(utf_8to16(dir));
789 return true1;
790#else
791 return (chdir(dir) == 0);
792#endif
793}
794
795static bool_Bool
796ws_popd(void)
797{
798 int ret = 0;
799 char* saved_wd = g_queue_pop_head(saved_dir_queue);
800 if (saved_wd == NULL((void*)0))
801 return false0;
802
803 //Restore the previous one
804#ifdef _WIN32
805 SetCurrentDirectory(utf_8to16(saved_wd));
806#else
807 ret = chdir(saved_wd);
808#endif
809 g_free(saved_wd);
810 return (ret == 0);
811}
812
813void
814proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
815{
816 if (ws_pushd(dir))
817 {
818 func(param);
819 ws_popd();
820 }
821}
822
823static bool_Bool
824// NOLINTNEXTLINE(misc-no-recursion)
825proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
826 void *data)
827{
828 proto_node *pnode = tree;
829 proto_node *child;
830 proto_node *current;
831
832 if (func(pnode, data))
833 return true1;
834
835 child = pnode->first_child;
836 while (child != NULL((void*)0)) {
837 /*
838 * The routine we call might modify the child, e.g. by
839 * freeing it, so we get the child's successor before
840 * calling that routine.
841 */
842 current = child;
843 child = current->next;
844 // We recurse here, but we're limited by prefs.gui_max_tree_depth
845 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
846 return true1;
847 }
848
849 return false0;
850}
851
852void
853proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
854 void *data)
855{
856 proto_node *node = tree;
857 proto_node *current;
858
859 if (!node)
860 return;
861
862 node = node->first_child;
863 while (node != NULL((void*)0)) {
864 current = node;
865 node = current->next;
866 func((proto_tree *)current, data);
867 }
868}
869
870static void
871free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
872{
873 GPtrArray *ptrs = (GPtrArray *)value;
874 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
875 header_field_info *hfinfo;
876
877 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", 877, __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", 877, "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", 877, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
878 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
879 /* when a field is referenced by a filter this also
880 affects the refcount for the parent protocol so we need
881 to adjust the refcount for the parent as well
882 */
883 if (hfinfo->parent != -1) {
884 header_field_info *parent_hfinfo;
885 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", 885
, __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", 885, "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", 885, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
886 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
887 }
888 hfinfo->ref_type = HF_REF_TYPE_NONE;
889 }
890
891 g_ptr_array_free(ptrs, true1);
892}
893
894static void
895proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
896{
897 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
898
899 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
900
901 if (finfo) {
902 fvalue_free(finfo->value);
903 finfo->value = NULL((void*)0);
904 }
905}
906
907void
908proto_tree_reset(proto_tree *tree)
909{
910 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
911
912 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
913
914 /* free tree data */
915 if (tree_data->interesting_hfids) {
916 /* Free all the GPtrArray's in the interesting_hfids hash. */
917 g_hash_table_foreach(tree_data->interesting_hfids,
918 free_GPtrArray_value, NULL((void*)0));
919
920 /* And then remove all values. */
921 g_hash_table_remove_all(tree_data->interesting_hfids);
922 }
923
924 /* Reset track of the number of children */
925 tree_data->count = 0;
926
927 /* Reset our loop checks */
928 tree_data->idle_count_ds_tvb = NULL((void*)0);
929 tree_data->max_start = 0;
930 tree_data->start_idle_count = 0;
931
932 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
933}
934
935/* frees the resources that the dissection a proto_tree uses */
936void
937proto_tree_free(proto_tree *tree)
938{
939 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
940
941 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
942
943 /* free tree data */
944 if (tree_data->interesting_hfids) {
945 /* Free all the GPtrArray's in the interesting_hfids hash. */
946 g_hash_table_foreach(tree_data->interesting_hfids,
947 free_GPtrArray_value, NULL((void*)0));
948
949 /* And then destroy the hash. */
950 g_hash_table_destroy(tree_data->interesting_hfids);
951 }
952
953 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)
;
954
955 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
956}
957
958/* Is the parsing being done for a visible proto_tree or an invisible one?
959 * By setting this correctly, the proto_tree creation is sped up by not
960 * having to call vsnprintf and copy strings around.
961 */
962bool_Bool
963proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
964{
965 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
966
967 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
968
969 return old_visible;
970}
971
972void
973proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
974{
975 if (tree)
976 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
977}
978
979/* Assume dissector set only its protocol fields.
980 This function is called by dissectors and allows the speeding up of filtering
981 in wireshark; if this function returns false it is safe to reset tree to NULL
982 and thus skip calling most of the expensive proto_tree_add_...()
983 functions.
984 If the tree is visible we implicitly assume the field is referenced.
985*/
986bool_Bool
987proto_field_is_referenced(proto_tree *tree, int proto_id)
988{
989 register header_field_info *hfinfo;
990
991
992 if (!tree)
993 return false0;
994
995 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
996 return true1;
997
998 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", 998, __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", 998, "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", 998, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
999 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1000 return true1;
1001
1002 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1003 return true1;
1004
1005 return false0;
1006}
1007
1008
1009/* Finds a record in the hfinfo array by id. */
1010header_field_info *
1011proto_registrar_get_nth(unsigned hfindex)
1012{
1013 register header_field_info *hfinfo;
1014
1015 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", 1015, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1015,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1015, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1016 return hfinfo;
1017}
1018
1019
1020/* Prefix initialization
1021 * this allows for a dissector to register a display filter name prefix
1022 * so that it can delay the initialization of the hf array as long as
1023 * possible.
1024 */
1025
1026/* compute a hash for the part before the dot of a display filter */
1027static unsigned
1028prefix_hash (const void *key) {
1029 /* end the string at the dot and compute its hash */
1030 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1031 char* c = copy;
1032 unsigned tmp;
1033
1034 for (; *c; c++) {
1035 if (*c == '.') {
1036 *c = 0;
1037 break;
1038 }
1039 }
1040
1041 tmp = wmem_str_hash(copy);
1042 g_free(copy);
1043 return tmp;
1044}
1045
1046/* are both strings equal up to the end or the dot? */
1047static gboolean
1048prefix_equal (const void *ap, const void *bp) {
1049 const char* a = (const char *)ap;
1050 const char* b = (const char *)bp;
1051
1052 do {
1053 char ac = *a++;
1054 char bc = *b++;
1055
1056 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1057
1058 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1059 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1060
1061 if (ac != bc) return FALSE(0);
1062 } while (1);
1063
1064 return FALSE(0);
1065}
1066
1067/* Register a new prefix for "delayed" initialization of field arrays */
1068void
1069proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1070 if (! prefixes ) {
1071 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1072 }
1073
1074 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1075}
1076
1077/* helper to call all prefix initializers */
1078static gboolean
1079initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1080 ((prefix_initializer_t)v)((const char *)k);
1081 return TRUE(!(0));
1082}
1083
1084/** Initialize every remaining uninitialized prefix. */
1085void
1086proto_initialize_all_prefixes(void) {
1087 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1088}
1089
1090/* Finds a record in the hfinfo array by name.
1091 * If it fails to find it in the already registered fields,
1092 * it tries to find and call an initializer in the prefixes
1093 * table and if so it looks again.
1094 */
1095
1096header_field_info *
1097proto_registrar_get_byname(const char *field_name)
1098{
1099 header_field_info *hfinfo;
1100 prefix_initializer_t pi;
1101
1102 if (!field_name)
1103 return NULL((void*)0);
1104
1105 if (g_strcmp0(field_name, last_field_name) == 0) {
1106 return last_hfinfo;
1107 }
1108
1109 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1110
1111 if (hfinfo) {
1112 g_free(last_field_name);
1113 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1114 last_hfinfo = hfinfo;
1115 return hfinfo;
1116 }
1117
1118 if (!prefixes)
1119 return NULL((void*)0);
1120
1121 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1122 pi(field_name);
1123 g_hash_table_remove(prefixes, field_name);
1124 } else {
1125 return NULL((void*)0);
1126 }
1127
1128 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1129
1130 if (hfinfo) {
1131 g_free(last_field_name);
1132 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1133 last_hfinfo = hfinfo;
1134 }
1135 return hfinfo;
1136}
1137
1138header_field_info*
1139proto_registrar_get_byalias(const char *alias_name)
1140{
1141 if (!alias_name) {
1142 return NULL((void*)0);
1143 }
1144
1145 /* Find our aliased protocol. */
1146 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1147 char *dot = strchr(an_copy, '.');
1148 if (dot) {
1149 *dot = '\0';
1150 }
1151 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1152 if (!proto_pfx) {
1153 g_free(an_copy);
1154 return NULL((void*)0);
1155 }
1156
1157 /* Construct our aliased field and look it up. */
1158 GString *filter_name = g_string_new(proto_pfx);
1159 if (dot) {
1160 g_string_append_printf(filter_name, ".%s", dot+1);
1161 }
1162 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1163 g_free(an_copy);
1164 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)))))
;
1165
1166 return hfinfo;
1167}
1168
1169int
1170proto_registrar_get_id_byname(const char *field_name)
1171{
1172 header_field_info *hfinfo;
1173
1174 hfinfo = proto_registrar_get_byname(field_name);
1175
1176 if (!hfinfo)
1177 return -1;
1178
1179 return hfinfo->id;
1180}
1181
1182static int
1183label_strcat_flags(const header_field_info *hfinfo)
1184{
1185 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1186 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1187
1188 return 0;
1189}
1190
1191static char *
1192format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1193 const uint8_t *bytes, unsigned length, size_t max_str_len)
1194{
1195 char *str = NULL((void*)0);
1196 const uint8_t *p;
1197 bool_Bool is_printable;
1198
1199 if (bytes) {
1200 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1201 /*
1202 * If all bytes are valid and printable UTF-8, show the
1203 * bytes as a string - in quotes to indicate that it's
1204 * a string.
1205 */
1206 if (isprint_utf8_string(bytes, length)) {
1207 str = wmem_strdup_printf(scope, "\"%.*s\"",
1208 (int)length, bytes);
1209 return str;
1210 }
1211 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1212 /*
1213 * Check whether all bytes are printable.
1214 */
1215 is_printable = true1;
1216 for (p = bytes; p < bytes+length; p++) {
1217 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1218 /* Not printable. */
1219 is_printable = false0;
1220 break;
1221 }
1222 }
1223
1224 /*
1225 * If all bytes are printable ASCII, show the bytes
1226 * as a string - in quotes to indicate that it's
1227 * a string.
1228 */
1229 if (is_printable) {
1230 str = wmem_strdup_printf(scope, "\"%.*s\"",
1231 (int)length, bytes);
1232 return str;
1233 }
1234 }
1235
1236 /*
1237 * Either it's not printable ASCII, or we don't care whether
1238 * it's printable ASCII; show it as hex bytes.
1239 */
1240 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1241 case SEP_DOT:
1242 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1243 break;
1244 case SEP_DASH:
1245 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1246 break;
1247 case SEP_COLON:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1249 break;
1250 case SEP_SPACE:
1251 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1252 break;
1253 case BASE_NONE:
1254 default:
1255 if (prefs.display_byte_fields_with_spaces) {
1256 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1257 } else {
1258 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1259 }
1260 break;
1261 }
1262 }
1263 else {
1264 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1265 str = wmem_strdup(scope, "<none>");
1266 } else {
1267 str = wmem_strdup(scope, "<MISSING>");
1268 }
1269 }
1270 return str;
1271}
1272
1273static char *
1274format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1275 const uint8_t *bytes, unsigned length)
1276{
1277 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1278}
1279
1280static void
1281ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1282{
1283 subtree_lvl *pushed_tree;
1284
1285 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"
, 1285, "ptvc->pushed_tree_max <= 256-8"))))
;
1286 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1287
1288 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1289 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1289, "pushed_tree != ((void*)0)"
))))
;
1290 ptvc->pushed_tree = pushed_tree;
1291}
1292
1293static void
1294ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1295{
1296 ptvc->pushed_tree = NULL((void*)0);
1297 ptvc->pushed_tree_max = 0;
1298 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", 1298, "ptvc->pushed_tree_index == 0"
))))
;
1299 ptvc->pushed_tree_index = 0;
1300}
1301
1302/* Allocates an initializes a ptvcursor_t with 3 variables:
1303 * proto_tree, tvbuff, and offset. */
1304ptvcursor_t *
1305ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1306{
1307 ptvcursor_t *ptvc;
1308
1309 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1310 ptvc->scope = scope;
1311 ptvc->tree = tree;
1312 ptvc->tvb = tvb;
1313 ptvc->offset = offset;
1314 ptvc->pushed_tree = NULL((void*)0);
1315 ptvc->pushed_tree_max = 0;
1316 ptvc->pushed_tree_index = 0;
1317 return ptvc;
1318}
1319
1320
1321/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1322void
1323ptvcursor_free(ptvcursor_t *ptvc)
1324{
1325 ptvcursor_free_subtree_levels(ptvc);
1326 /*g_free(ptvc);*/
1327}
1328
1329/* Returns tvbuff. */
1330tvbuff_t *
1331ptvcursor_tvbuff(ptvcursor_t *ptvc)
1332{
1333 return ptvc->tvb;
1334}
1335
1336/* Returns current offset. */
1337int
1338ptvcursor_current_offset(ptvcursor_t *ptvc)
1339{
1340 return ptvc->offset;
1341}
1342
1343proto_tree *
1344ptvcursor_tree(ptvcursor_t *ptvc)
1345{
1346 if (!ptvc)
1347 return NULL((void*)0);
1348
1349 return ptvc->tree;
1350}
1351
1352void
1353ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1354{
1355 ptvc->tree = tree;
1356}
1357
1358/* creates a subtree, sets it as the working tree and pushes the old working tree */
1359proto_tree *
1360ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1361{
1362 subtree_lvl *subtree;
1363 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1364 ptvcursor_new_subtree_levels(ptvc);
1365
1366 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1367 subtree->tree = ptvc->tree;
1368 subtree->it= NULL((void*)0);
1369 ptvc->pushed_tree_index++;
1370 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1371}
1372
1373/* pops a subtree */
1374void
1375ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1376{
1377 subtree_lvl *subtree;
1378
1379 if (ptvc->pushed_tree_index <= 0)
1380 return;
1381
1382 ptvc->pushed_tree_index--;
1383 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1384 if (subtree->it != NULL((void*)0))
1385 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1386
1387 ptvc->tree = subtree->tree;
1388}
1389
1390/* saves the current tvb offset and the item in the current subtree level */
1391static void
1392ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1393{
1394 subtree_lvl *subtree;
1395
1396 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", 1396, "ptvc->pushed_tree_index > 0"
))))
;
1397
1398 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1399 subtree->it = it;
1400 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1401}
1402
1403/* Creates a subtree and adds it to the cursor as the working tree but does not
1404 * save the old working tree */
1405proto_tree *
1406ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1407{
1408 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1409 return ptvc->tree;
1410}
1411
1412static proto_tree *
1413ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1414{
1415 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1416 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1417 ptvcursor_subtree_set_item(ptvc, it);
1418 return ptvcursor_tree(ptvc);
1419}
1420
1421/* Add an item to the tree and create a subtree
1422 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1423 * In this case, when the subtree will be closed, the parent item length will
1424 * be equal to the advancement of the cursor since the creation of the subtree.
1425 */
1426proto_tree *
1427ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1428 const unsigned encoding, int ett_subtree)
1429{
1430 proto_item *it;
1431
1432 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1433 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1434}
1435
1436static proto_item *
1437proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1438
1439/* Add a text node to the tree and create a subtree
1440 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1441 * In this case, when the subtree will be closed, the item length will be equal
1442 * to the advancement of the cursor since the creation of the subtree.
1443 */
1444proto_tree *
1445ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1446 int ett_subtree, const char *format, ...)
1447{
1448 proto_item *pi;
1449 va_list ap;
1450 header_field_info *hfinfo;
1451 proto_tree *tree;
1452
1453 tree = ptvcursor_tree(ptvc);
1454
1455 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1456
1457 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", 1457
, __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", 1457, "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", 1457, "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", 1457, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1458
1459 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1460 ptvcursor_current_offset(ptvc), length);
1461
1462 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1462, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1463
1464 va_start(ap, format)__builtin_va_start(ap, format);
1465 proto_tree_set_representation(pi, format, ap);
1466 va_end(ap)__builtin_va_end(ap);
1467
1468 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1469}
1470
1471/* Add a text-only node, leaving it to our caller to fill the text in */
1472static proto_item *
1473proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1474{
1475 proto_item *pi;
1476
1477 if (tree == NULL((void*)0))
1478 return NULL((void*)0);
1479
1480 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1481
1482 return pi;
1483}
1484
1485/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1486proto_item *
1487proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1488 const char *format, ...)
1489{
1490 proto_item *pi;
1491 va_list ap;
1492 header_field_info *hfinfo;
1493
1494 if (length == -1) {
1495 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1496 } else {
1497 tvb_ensure_bytes_exist(tvb, start, length);
1498 }
1499
1500 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1501
1502 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", 1502
, __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", 1502, "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", 1502, "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", 1502, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1503
1504 pi = proto_tree_add_text_node(tree, tvb, start, length);
1505
1506 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1506, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1507
1508 va_start(ap, format)__builtin_va_start(ap, format);
1509 proto_tree_set_representation(pi, format, ap);
1510 va_end(ap)__builtin_va_end(ap);
1511
1512 return pi;
1513}
1514
1515/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1516proto_item *
1517proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1518 int length, const char *format, va_list ap)
1519{
1520 proto_item *pi;
1521 header_field_info *hfinfo;
1522
1523 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1524 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1525 * the length to be what's in the tvbuff if length is -1, and the
1526 * minimum of length and what's in the tvbuff if not.
1527 */
1528
1529 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1530
1531 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", 1531
, __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", 1531, "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", 1531, "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", 1531, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1532
1533 pi = proto_tree_add_text_node(tree, tvb, start, length);
1534
1535 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1535, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1536
1537 proto_tree_set_representation(pi, format, ap);
1538
1539 return pi;
1540}
1541
1542/* Add a text-only node that creates a subtree underneath.
1543 */
1544proto_tree *
1545proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1546{
1547 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1548}
1549
1550/* Add a text-only node that creates a subtree underneath.
1551 */
1552proto_tree *
1553proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1554{
1555 proto_tree *pt;
1556 proto_item *pi;
1557 va_list ap;
1558
1559 va_start(ap, format)__builtin_va_start(ap, format);
1560 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1561 va_end(ap)__builtin_va_end(ap);
1562
1563 if (tree_item != NULL((void*)0))
1564 *tree_item = pi;
1565
1566 pt = proto_item_add_subtree(pi, idx);
1567
1568 return pt;
1569}
1570
1571/* Add a text-only node for debugging purposes. The caller doesn't need
1572 * to worry about tvbuff, start, or length. Debug message gets sent to
1573 * STDOUT, too */
1574proto_item *
1575proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1576{
1577 proto_item *pi;
1578 va_list ap;
1579
1580 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1581
1582 if (pi) {
1583 va_start(ap, format)__builtin_va_start(ap, format);
1584 proto_tree_set_representation(pi, format, ap);
1585 va_end(ap)__builtin_va_end(ap);
1586 }
1587 va_start(ap, format)__builtin_va_start(ap, format);
1588 vprintf(format, ap);
1589 va_end(ap)__builtin_va_end(ap);
1590 printf("\n");
1591
1592 return pi;
1593}
1594
1595proto_item *
1596proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1597{
1598 proto_item *pi;
1599 header_field_info *hfinfo;
1600
1601 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1602
1603 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", 1603
, __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", 1603, "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", 1603, "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", 1603, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1604
1605 pi = proto_tree_add_text_node(tree, tvb, start, length);
1606
1607 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1607, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1608
1609 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1610
1611 return pi;
1612}
1613
1614proto_item *
1615proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1616{
1617 proto_item *pi;
1618 header_field_info *hfinfo;
1619 char *str;
1620
1621 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1622
1623 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", 1623
, __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", 1623, "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", 1623, "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", 1623, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1624
1625 pi = proto_tree_add_text_node(tree, tvb, start, length);
1626
1627 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1627, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1628
1629 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1630 proto_item_set_text(pi, "%s", str);
1631 wmem_free(NULL((void*)0), str);
1632
1633 return pi;
1634}
1635
1636void proto_report_dissector_bug(const char *format, ...)
1637{
1638 va_list args;
1639
1640 if (wireshark_abort_on_dissector_bug) {
1641 /*
1642 * Try to have the error message show up in the crash
1643 * information.
1644 */
1645 va_start(args, format)__builtin_va_start(args, format);
1646 ws_vadd_crash_info(format, args);
1647 va_end(args)__builtin_va_end(args);
1648
1649 /*
1650 * Print the error message.
1651 */
1652 va_start(args, format)__builtin_va_start(args, format);
1653 vfprintf(stderrstderr, format, args);
1654 va_end(args)__builtin_va_end(args);
1655 putc('\n', stderrstderr);
1656
1657 /*
1658 * And crash.
1659 */
1660 abort();
1661 } else {
1662 va_start(args, format)__builtin_va_start(args, format);
1663 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1664 va_end(args)__builtin_va_end(args);
1665 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1665
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1666 }
1667}
1668
1669/* We could probably get away with changing is_error to a minimum length value. */
1670static void
1671report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1672{
1673 if (is_error) {
1674 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1675 } else {
1676 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1677 }
1678
1679 if (is_error) {
1680 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1681 }
1682}
1683
1684static uint32_t
1685get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1686{
1687 uint32_t value;
1688 bool_Bool length_error;
1689
1690 switch (length) {
1691
1692 case 1:
1693 value = tvb_get_uint8(tvb, offset);
1694 if (encoding & ENC_ZIGBEE0x40000000) {
1695 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1696 value = 0;
1697 }
1698 }
1699 break;
1700
1701 case 2:
1702 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1703 : tvb_get_ntohs(tvb, offset);
1704 if (encoding & ENC_ZIGBEE0x40000000) {
1705 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1706 value = 0;
1707 }
1708 }
1709 break;
1710
1711 case 3:
1712 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1713 : tvb_get_ntoh24(tvb, offset);
1714 break;
1715
1716 case 4:
1717 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1718 : tvb_get_ntohl(tvb, offset);
1719 break;
1720
1721 default:
1722 if (length < 1) {
1723 length_error = true1;
1724 value = 0;
1725 } else {
1726 length_error = false0;
1727 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1728 : tvb_get_ntohl(tvb, offset);
1729 }
1730 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1731 break;
1732 }
1733 return value;
1734}
1735
1736static inline uint64_t
1737get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1738{
1739 uint64_t value;
1740
1741 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1742
1743 if (length < 1 || length > 8) {
1744 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1745 }
1746
1747 return value;
1748}
1749
1750static int32_t
1751get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1752{
1753 int32_t value;
1754 bool_Bool length_error;
1755
1756 switch (length) {
1757
1758 case 1:
1759 value = tvb_get_int8(tvb, offset);
1760 break;
1761
1762 case 2:
1763 value = encoding ? tvb_get_letohis(tvb, offset)
1764 : tvb_get_ntohis(tvb, offset);
1765 break;
1766
1767 case 3:
1768 value = encoding ? tvb_get_letohi24(tvb, offset)
1769 : tvb_get_ntohi24(tvb, offset);
1770 break;
1771
1772 case 4:
1773 value = encoding ? tvb_get_letohil(tvb, offset)
1774 : tvb_get_ntohil(tvb, offset);
1775 break;
1776
1777 default:
1778 if (length < 1) {
1779 length_error = true1;
1780 value = 0;
1781 } else {
1782 length_error = false0;
1783 value = encoding ? tvb_get_letohil(tvb, offset)
1784 : tvb_get_ntohil(tvb, offset);
1785 }
1786 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1787 break;
1788 }
1789 return value;
1790}
1791
1792/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1793 * be cast-able as a int64_t. This is weird, but what the code has always done.
1794 */
1795static inline uint64_t
1796get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1797{
1798 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1799
1800 switch (length) {
1801 case 7:
1802 value = ws_sign_ext64(value, 56);
1803 break;
1804 case 6:
1805 value = ws_sign_ext64(value, 48);
1806 break;
1807 case 5:
1808 value = ws_sign_ext64(value, 40);
1809 break;
1810 case 4:
1811 value = ws_sign_ext64(value, 32);
1812 break;
1813 case 3:
1814 value = ws_sign_ext64(value, 24);
1815 break;
1816 case 2:
1817 value = ws_sign_ext64(value, 16);
1818 break;
1819 case 1:
1820 value = ws_sign_ext64(value, 8);
1821 break;
1822 }
1823
1824 return value;
1825}
1826
1827/* For FT_STRING */
1828static inline const uint8_t *
1829get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1830 int length, int *ret_length, const unsigned encoding)
1831{
1832 if (length == -1) {
1833 length = tvb_ensure_captured_length_remaining(tvb, start);
1834 }
1835 *ret_length = length;
1836 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1837}
1838
1839/* For FT_STRINGZ */
1840static inline const uint8_t *
1841get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1842 int start, int length, int *ret_length, const unsigned encoding)
1843{
1844 const uint8_t *value;
1845
1846 if (length < -1) {
1847 report_type_length_mismatch(tree, "a string", length, true1);
1848 }
1849 if (length == -1) {
1850 /* This can throw an exception */
1851 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1852 } else {
1853 /* In this case, length signifies the length of the string.
1854 *
1855 * This could either be a null-padded string, which doesn't
1856 * necessarily have a '\0' at the end, or a null-terminated
1857 * string, with a trailing '\0'. (Yes, there are cases
1858 * where you have a string that's both counted and null-
1859 * terminated.)
1860 *
1861 * In the first case, we must allocate a buffer of length
1862 * "length+1", to make room for a trailing '\0'.
1863 *
1864 * In the second case, we don't assume that there is a
1865 * trailing '\0' there, as the packet might be malformed.
1866 * (XXX - should we throw an exception if there's no
1867 * trailing '\0'?) Therefore, we allocate a buffer of
1868 * length "length+1", and put in a trailing '\0', just to
1869 * be safe.
1870 *
1871 * (XXX - this would change if we made string values counted
1872 * rather than null-terminated.)
1873 */
1874 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1875 }
1876 *ret_length = length;
1877 return value;
1878}
1879
1880/* For FT_UINT_STRING */
1881static inline const uint8_t *
1882get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1883 tvbuff_t *tvb, int start, int length, int *ret_length,
1884 const unsigned encoding)
1885{
1886 uint32_t n;
1887 const uint8_t *value;
1888
1889 /* I believe it's ok if this is called with a NULL tree */
1890 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1891 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1892 length += n;
1893 *ret_length = length;
1894 return value;
1895}
1896
1897/* For FT_STRINGZPAD */
1898static inline const uint8_t *
1899get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1900 int length, int *ret_length, const unsigned encoding)
1901{
1902 /*
1903 * XXX - currently, string values are null-
1904 * terminated, so a "zero-padded" string
1905 * isn't special. If we represent string
1906 * values as something that includes a counted
1907 * array of bytes, we'll need to strip the
1908 * trailing NULs.
1909 */
1910 if (length == -1) {
1911 length = tvb_ensure_captured_length_remaining(tvb, start);
1912 }
1913 *ret_length = length;
1914 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1915}
1916
1917/* For FT_STRINGZTRUNC */
1918static inline const uint8_t *
1919get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1920 int length, int *ret_length, const unsigned encoding)
1921{
1922 /*
1923 * XXX - currently, string values are null-
1924 * terminated, so a "zero-truncated" string
1925 * isn't special. If we represent string
1926 * values as something that includes a counted
1927 * array of bytes, we'll need to strip everything
1928 * starting with the terminating NUL.
1929 */
1930 if (length == -1) {
1931 length = tvb_ensure_captured_length_remaining(tvb, start);
1932 }
1933 *ret_length = length;
1934 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1935}
1936
1937/*
1938 * Deltas between the epochs for various non-UN*X time stamp formats and
1939 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1940 * stamp format.
1941 */
1942
1943/*
1944 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1945 * XXX - if it's OK if this is unsigned, can we just use
1946 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1947 */
1948#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1949
1950/*
1951 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1952 */
1953#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1954
1955/* this can be called when there is no tree, so tree may be null */
1956static void
1957get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1958 const int length, const unsigned encoding, nstime_t *time_stamp,
1959 const bool_Bool is_relative)
1960{
1961 uint32_t tmpsecs;
1962 uint64_t tmp64secs;
1963 uint64_t todusecs;
1964
1965 switch (encoding) {
1966
1967 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1968 /*
1969 * If the length is 16, 8-byte seconds, followed
1970 * by 8-byte fractional time in nanoseconds,
1971 * both big-endian.
1972 *
1973 * If the length is 12, 8-byte seconds, followed
1974 * by 4-byte fractional time in nanoseconds,
1975 * both big-endian.
1976 *
1977 * If the length is 8, 4-byte seconds, followed
1978 * by 4-byte fractional time in nanoseconds,
1979 * both big-endian.
1980 *
1981 * For absolute times, the seconds are seconds
1982 * since the UN*X epoch.
1983 */
1984 if (length == 16) {
1985 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1986 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1987 } else if (length == 12) {
1988 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1989 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1990 } else if (length == 8) {
1991 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1992 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1993 } else if (length == 4) {
1994 /*
1995 * Backwards compatibility.
1996 * ENC_TIME_SECS_NSECS is 0; using
1997 * ENC_BIG_ENDIAN by itself with a 4-byte
1998 * time-in-seconds value was done in the
1999 * past.
2000 */
2001 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2002 time_stamp->nsecs = 0;
2003 } else {
2004 time_stamp->secs = 0;
2005 time_stamp->nsecs = 0;
2006 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2007 }
2008 break;
2009
2010 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2011 /*
2012 * If the length is 16, 8-byte seconds, followed
2013 * by 8-byte fractional time in nanoseconds,
2014 * both little-endian.
2015 *
2016 * If the length is 12, 8-byte seconds, followed
2017 * by 4-byte fractional time in nanoseconds,
2018 * both little-endian.
2019 *
2020 * If the length is 8, 4-byte seconds, followed
2021 * by 4-byte fractional time in nanoseconds,
2022 * both little-endian.
2023 *
2024 * For absolute times, the seconds are seconds
2025 * since the UN*X epoch.
2026 */
2027 if (length == 16) {
2028 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2029 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2030 } else if (length == 12) {
2031 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2032 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2033 } else if (length == 8) {
2034 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2035 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2036 } else if (length == 4) {
2037 /*
2038 * Backwards compatibility.
2039 * ENC_TIME_SECS_NSECS is 0; using
2040 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2041 * time-in-seconds value was done in the
2042 * past.
2043 */
2044 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2045 time_stamp->nsecs = 0;
2046 } else {
2047 time_stamp->secs = 0;
2048 time_stamp->nsecs = 0;
2049 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2050 }
2051 break;
2052
2053 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2054 /*
2055 * NTP time stamp, big-endian.
2056 * Only supported for absolute times.
2057 */
2058 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2058, "!is_relative"
))))
;
2059
2060 /* We need a temporary variable here so the unsigned math
2061 * works correctly (for years > 2036 according to RFC 2030
2062 * chapter 3).
2063 *
2064 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2065 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2066 * If bit 0 is not set, the time is in the range 2036-2104 and
2067 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2068 */
2069 tmpsecs = tvb_get_ntohl(tvb, start);
2070 if ((tmpsecs & 0x80000000) != 0)
2071 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2072 else
2073 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2074
2075 if (length == 8) {
2076 tmp64secs = tvb_get_ntoh64(tvb, start);
2077 if (tmp64secs == 0) {
2078 //This is "NULL" time
2079 time_stamp->secs = 0;
2080 time_stamp->nsecs = 0;
2081 } else {
2082 /*
2083 * Convert 1/2^32s of a second to
2084 * nanoseconds.
2085 */
2086 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2087 }
2088 } else if (length == 4) {
2089 /*
2090 * Backwards compatibility.
2091 */
2092 if (tmpsecs == 0) {
2093 //This is "NULL" time
2094 time_stamp->secs = 0;
2095 }
2096 time_stamp->nsecs = 0;
2097 } else {
2098 time_stamp->secs = 0;
2099 time_stamp->nsecs = 0;
2100 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2101 }
2102 break;
2103
2104 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2105 /*
2106 * NTP time stamp, little-endian.
2107 * Only supported for absolute times.
2108 *
2109 * NTP doesn't use this, because it's an Internet format
2110 * and hence big-endian. Any implementation must decide
2111 * whether the NTP timestamp is a 64-bit unsigned fixed
2112 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2113 * with a 32-bit unsigned seconds field followed by a
2114 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2115 * the previous two).
2116 *
2117 * XXX: We do the latter, but no dissector uses this format.
2118 * OTOH, ERF timestamps do the former, so perhaps we
2119 * should switch the interpretation so that packet-erf.c
2120 * could use this directly?
2121 */
2122 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2122, "!is_relative"
))))
;
2123
2124 /* We need a temporary variable here so the unsigned math
2125 * works correctly (for years > 2036 according to RFC 2030
2126 * chapter 3).
2127 *
2128 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2129 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2130 * If bit 0 is not set, the time is in the range 2036-2104 and
2131 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2132 */
2133 tmpsecs = tvb_get_letohl(tvb, start);
2134 if ((tmpsecs & 0x80000000) != 0)
2135 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2136 else
2137 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2138
2139 if (length == 8) {
2140 tmp64secs = tvb_get_letoh64(tvb, start);
2141 if (tmp64secs == 0) {
2142 //This is "NULL" time
2143 time_stamp->secs = 0;
2144 time_stamp->nsecs = 0;
2145 } else {
2146 /*
2147 * Convert 1/2^32s of a second to
2148 * nanoseconds.
2149 */
2150 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2151 }
2152 } else if (length == 4) {
2153 /*
2154 * Backwards compatibility.
2155 */
2156 if (tmpsecs == 0) {
2157 //This is "NULL" time
2158 time_stamp->secs = 0;
2159 }
2160 time_stamp->nsecs = 0;
2161 } else {
2162 time_stamp->secs = 0;
2163 time_stamp->nsecs = 0;
2164 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2165 }
2166 break;
2167
2168 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2169 /*
2170 * S/3x0 and z/Architecture TOD clock time stamp,
2171 * big-endian. The epoch is January 1, 1900,
2172 * 00:00:00 (proleptic?) UTC.
2173 *
2174 * Only supported for absolute times.
2175 */
2176 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2176, "!is_relative"
))))
;
2177 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2177, "length == 8"
))))
;
2178
2179 if (length == 8) {
2180 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2181 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2182 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2183 } else {
2184 time_stamp->secs = 0;
2185 time_stamp->nsecs = 0;
2186 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2187 }
2188 break;
2189
2190 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2191 /*
2192 * S/3x0 and z/Architecture TOD clock time stamp,
2193 * little-endian. The epoch is January 1, 1900,
2194 * 00:00:00 (proleptic?) UTC.
2195 *
2196 * Only supported for absolute times.
2197 */
2198 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2198, "!is_relative"
))))
;
2199
2200 if (length == 8) {
2201 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2202 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2203 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2204 } else {
2205 time_stamp->secs = 0;
2206 time_stamp->nsecs = 0;
2207 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2208 }
2209 break;
2210
2211 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2212 /*
2213 * Time stamp using the same seconds/fraction format
2214 * as NTP, but with the origin of the time stamp being
2215 * the UNIX epoch rather than the NTP epoch; big-
2216 * endian.
2217 *
2218 * Only supported for absolute times.
2219 */
2220 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2220, "!is_relative"
))))
;
2221
2222 if (length == 8) {
2223 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2224 /*
2225 * Convert 1/2^32s of a second to nanoseconds.
2226 */
2227 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2228 } else {
2229 time_stamp->secs = 0;
2230 time_stamp->nsecs = 0;
2231 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2232 }
2233 break;
2234
2235 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2236 /*
2237 * Time stamp using the same seconds/fraction format
2238 * as NTP, but with the origin of the time stamp being
2239 * the UNIX epoch rather than the NTP epoch; little-
2240 * endian.
2241 *
2242 * Only supported for absolute times.
2243 *
2244 * The RTPS specification explicitly supports Little
2245 * Endian encoding. In one place, it states that its
2246 * Time_t representation "is the one defined by ...
2247 * RFC 1305", but in another explicitly defines it as
2248 * a struct consisting of an 32 bit unsigned seconds
2249 * field and a 32 bit unsigned fraction field, not a 64
2250 * bit fixed point, so we do that here.
2251 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2252 */
2253 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2253, "!is_relative"
))))
;
2254
2255 if (length == 8) {
2256 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2257 /*
2258 * Convert 1/2^32s of a second to nanoseconds.
2259 */
2260 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2261 } else {
2262 time_stamp->secs = 0;
2263 time_stamp->nsecs = 0;
2264 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2265 }
2266 break;
2267
2268 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2269 /*
2270 * MIP6 time stamp, big-endian.
2271 * A 64-bit unsigned integer field containing a timestamp. The
2272 * value indicates the number of seconds since January 1, 1970,
2273 * 00:00 UTC, by using a fixed point format. In this format, the
2274 * integer number of seconds is contained in the first 48 bits of
2275 * the field, and the remaining 16 bits indicate the number of
2276 * 1/65536 fractions of a second.
2277
2278 * Only supported for absolute times.
2279 */
2280 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2280, "!is_relative"
))))
;
2281
2282 if (length == 8) {
2283 /* We need a temporary variable here so the casting and fractions
2284 * of a second work correctly.
2285 */
2286 tmp64secs = tvb_get_ntoh48(tvb, start);
2287 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2288 tmpsecs <<= 16;
2289
2290 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2291 //This is "NULL" time
2292 time_stamp->secs = 0;
2293 time_stamp->nsecs = 0;
2294 } else {
2295 time_stamp->secs = (time_t)tmp64secs;
2296 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2297 }
2298 } else {
2299 time_stamp->secs = 0;
2300 time_stamp->nsecs = 0;
2301 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2302 }
2303 break;
2304
2305 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2306 /*
2307 * If the length is 16, 8-byte seconds, followed
2308 * by 8-byte fractional time in microseconds,
2309 * both big-endian.
2310 *
2311 * If the length is 12, 8-byte seconds, followed
2312 * by 4-byte fractional time in microseconds,
2313 * both big-endian.
2314 *
2315 * If the length is 8, 4-byte seconds, followed
2316 * by 4-byte fractional time in microseconds,
2317 * both big-endian.
2318 *
2319 * For absolute times, the seconds are seconds
2320 * since the UN*X epoch.
2321 */
2322 if (length == 16) {
2323 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2324 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2325 } else if (length == 12) {
2326 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2327 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2328 } else if (length == 8) {
2329 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2330 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2331 } else {
2332 time_stamp->secs = 0;
2333 time_stamp->nsecs = 0;
2334 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2335 }
2336 break;
2337
2338 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2339 /*
2340 * If the length is 16, 8-byte seconds, followed
2341 * by 8-byte fractional time in microseconds,
2342 * both little-endian.
2343 *
2344 * If the length is 12, 8-byte seconds, followed
2345 * by 4-byte fractional time in microseconds,
2346 * both little-endian.
2347 *
2348 * If the length is 8, 4-byte seconds, followed
2349 * by 4-byte fractional time in microseconds,
2350 * both little-endian.
2351 *
2352 * For absolute times, the seconds are seconds
2353 * since the UN*X epoch.
2354 */
2355 if (length == 16) {
2356 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2357 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2358 } else if (length == 12) {
2359 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2360 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2361 } else if (length == 8) {
2362 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2363 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2364 } else {
2365 time_stamp->secs = 0;
2366 time_stamp->nsecs = 0;
2367 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2368 }
2369 break;
2370
2371 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2372 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2373 /*
2374 * Seconds, 1 to 8 bytes.
2375 * For absolute times, it's seconds since the
2376 * UN*X epoch.
2377 */
2378 if (length >= 1 && length <= 8) {
2379 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2380 time_stamp->nsecs = 0;
2381 } else {
2382 time_stamp->secs = 0;
2383 time_stamp->nsecs = 0;
2384 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2385 }
2386 break;
2387
2388 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2389 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2390 /*
2391 * Milliseconds, 1 to 8 bytes.
2392 * For absolute times, it's milliseconds since the
2393 * UN*X epoch.
2394 */
2395 if (length >= 1 && length <= 8) {
2396 uint64_t msecs;
2397
2398 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2399 time_stamp->secs = (time_t)(msecs / 1000);
2400 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2401 } else {
2402 time_stamp->secs = 0;
2403 time_stamp->nsecs = 0;
2404 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2405 }
2406 break;
2407
2408 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2409 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2410 /*
2411 * Microseconds, 1 to 8 bytes.
2412 * For absolute times, it's microseconds since the
2413 * UN*X epoch.
2414 */
2415 if (length >= 1 && length <= 8) {
2416 uint64_t usecs;
2417
2418 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2419 time_stamp->secs = (time_t)(usecs / 1000000);
2420 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2421 } else {
2422 time_stamp->secs = 0;
2423 time_stamp->nsecs = 0;
2424 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2425 }
2426 break;
2427
2428 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2429 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2430 /*
2431 * nanoseconds, 1 to 8 bytes.
2432 * For absolute times, it's nanoseconds since the
2433 * UN*X epoch.
2434 */
2435
2436 if (length >= 1 && length <= 8) {
2437 uint64_t nsecs;
2438
2439 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2440 time_stamp->secs = (time_t)(nsecs / 1000000000);
2441 time_stamp->nsecs = (int)(nsecs % 1000000000);
2442 } else {
2443 time_stamp->secs = 0;
2444 time_stamp->nsecs = 0;
2445 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2446 }
2447 break;
2448
2449 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2450 /*
2451 * 1/64ths of a second since the UN*X epoch,
2452 * big-endian.
2453 *
2454 * Only supported for absolute times.
2455 */
2456 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2456, "!is_relative"
))))
;
2457
2458 if (length == 8) {
2459 /*
2460 * The upper 48 bits are seconds since the
2461 * UN*X epoch.
2462 */
2463 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2464 /*
2465 * The lower 16 bits are 1/2^16s of a second;
2466 * convert them to nanoseconds.
2467 *
2468 * XXX - this may give the impression of higher
2469 * precision than you actually get.
2470 */
2471 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2472 } else {
2473 time_stamp->secs = 0;
2474 time_stamp->nsecs = 0;
2475 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2476 }
2477 break;
2478
2479 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2480 /*
2481 * 1/64ths of a second since the UN*X epoch,
2482 * little-endian.
2483 *
2484 * Only supported for absolute times.
2485 */
2486 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2486, "!is_relative"
))))
;
2487
2488 if (length == 8) {
2489 /*
2490 * XXX - this is assuming that, if anybody
2491 * were ever to use this format - RFC 3971
2492 * doesn't, because that's an Internet
2493 * protocol, and those use network byte
2494 * order, i.e. big-endian - they'd treat it
2495 * as a 64-bit count of 1/2^16s of a second,
2496 * putting the upper 48 bits at the end.
2497 *
2498 * The lower 48 bits are seconds since the
2499 * UN*X epoch.
2500 */
2501 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2502 /*
2503 * The upper 16 bits are 1/2^16s of a second;
2504 * convert them to nanoseconds.
2505 *
2506 * XXX - this may give the impression of higher
2507 * precision than you actually get.
2508 */
2509 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2510 } else {
2511 time_stamp->secs = 0;
2512 time_stamp->nsecs = 0;
2513 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2514 }
2515 break;
2516
2517 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2518 /*
2519 * NTP time stamp, with 1-second resolution (i.e.,
2520 * seconds since the NTP epoch), big-endian.
2521 * Only supported for absolute times.
2522 */
2523 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2523, "!is_relative"
))))
;
2524
2525 if (length == 4) {
2526 /*
2527 * We need a temporary variable here so the unsigned math
2528 * works correctly (for years > 2036 according to RFC 2030
2529 * chapter 3).
2530 *
2531 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2532 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2533 * If bit 0 is not set, the time is in the range 2036-2104 and
2534 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2535 */
2536 tmpsecs = tvb_get_ntohl(tvb, start);
2537 if ((tmpsecs & 0x80000000) != 0)
2538 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2539 else
2540 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2541 time_stamp->nsecs = 0;
2542 } else {
2543 time_stamp->secs = 0;
2544 time_stamp->nsecs = 0;
2545 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2546 }
2547 break;
2548
2549 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2550 /*
2551 * NTP time stamp, with 1-second resolution (i.e.,
2552 * seconds since the NTP epoch), little-endian.
2553 * Only supported for absolute times.
2554 */
2555 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2555, "!is_relative"
))))
;
2556
2557 /*
2558 * We need a temporary variable here so the unsigned math
2559 * works correctly (for years > 2036 according to RFC 2030
2560 * chapter 3).
2561 *
2562 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2563 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2564 * If bit 0 is not set, the time is in the range 2036-2104 and
2565 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2566 */
2567 if (length == 4) {
2568 tmpsecs = tvb_get_letohl(tvb, start);
2569 if ((tmpsecs & 0x80000000) != 0)
2570 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2571 else
2572 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2573 time_stamp->nsecs = 0;
2574 } else {
2575 time_stamp->secs = 0;
2576 time_stamp->nsecs = 0;
2577 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2578 }
2579 break;
2580
2581 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2582 /*
2583 * Milliseconds, 6 to 8 bytes.
2584 * For absolute times, it's milliseconds since the
2585 * NTP epoch.
2586 *
2587 * ETSI TS 129.274 8.119 defines this as:
2588 * "a 48 bit unsigned integer in network order format
2589 * ...encoded as the number of milliseconds since
2590 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2591 * rounded value of 1000 x the value of the 64-bit
2592 * timestamp (Seconds + (Fraction / (1<<32))) defined
2593 * in clause 6 of IETF RFC 5905."
2594 *
2595 * Taken literally, the part after "i.e." would
2596 * mean that the value rolls over before reaching
2597 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2598 * when the 64 bit timestamp rolls over, and we have
2599 * to pick an NTP Era equivalence class to support
2600 * (such as 1968-01-20 to 2104-02-06).
2601 *
2602 * OTOH, the extra room might be used to store Era
2603 * information instead, in which case times until
2604 * 10819-08-03 can be represented with 6 bytes without
2605 * ambiguity. We handle both implementations, and assume
2606 * that times before 1968-01-20 are not represented.
2607 *
2608 * Only 6 bytes or more makes sense as an absolute
2609 * time. 5 bytes or fewer could express a span of
2610 * less than 35 years, either 1900-1934 or 2036-2070.
2611 */
2612 if (length >= 6 && length <= 8) {
2613 uint64_t msecs;
2614
2615 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2616 tmp64secs = (msecs / 1000);
2617 /*
2618 * Assume that times in the first half of NTP
2619 * Era 0 really represent times in the NTP
2620 * Era 1.
2621 */
2622 if (tmp64secs >= 0x80000000)
2623 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2624 else
2625 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2626 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2627 }
2628 else {
2629 time_stamp->secs = 0;
2630 time_stamp->nsecs = 0;
2631 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2632 }
2633 break;
2634
2635 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2636 /*
2637 * MP4 file time stamps, big-endian.
2638 * Only supported for absolute times.
2639 */
2640 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2640, "!is_relative"
))))
;
2641
2642 if (length == 8) {
2643 tmp64secs = tvb_get_ntoh64(tvb, start);
2644 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2645 time_stamp->nsecs = 0;
2646 } else if (length == 4) {
2647 tmpsecs = tvb_get_ntohl(tvb, start);
2648 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2649 time_stamp->nsecs = 0;
2650 } else {
2651 time_stamp->secs = 0;
2652 time_stamp->nsecs = 0;
2653 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2654 }
2655 break;
2656
2657 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2658 /*
2659 * Zigbee ZCL time stamps, big-endian.
2660 * Only supported for absolute times.
2661 */
2662 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2662, "!is_relative"
))))
;
2663
2664 if (length == 8) {
2665 tmp64secs = tvb_get_ntoh64(tvb, start);
2666 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);
2667 time_stamp->nsecs = 0;
2668 } else if (length == 4) {
2669 tmpsecs = tvb_get_ntohl(tvb, start);
2670 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2671 time_stamp->nsecs = 0;
2672 } else {
2673 time_stamp->secs = 0;
2674 time_stamp->nsecs = 0;
2675 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2676 }
2677 break;
2678
2679 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2680 /*
2681 * Zigbee ZCL time stamps, little-endian.
2682 * Only supported for absolute times.
2683 */
2684 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2684, "!is_relative"
))))
;
2685
2686 if (length == 8) {
2687 tmp64secs = tvb_get_letoh64(tvb, start);
2688 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);
2689 time_stamp->nsecs = 0;
2690 } else if (length == 4) {
2691 tmpsecs = tvb_get_letohl(tvb, start);
2692 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2693 time_stamp->nsecs = 0;
2694 } else {
2695 time_stamp->secs = 0;
2696 time_stamp->nsecs = 0;
2697 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2698 }
2699 break;
2700
2701 default:
2702 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2702))
;
2703 break;
2704 }
2705}
2706
2707static void
2708tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2709{
2710 const header_field_info *hfinfo = fi->hfinfo;
2711
2712 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2713 GPtrArray *ptrs = NULL((void*)0);
2714
2715 if (tree_data->interesting_hfids == NULL((void*)0)) {
2716 /* Initialize the hash because we now know that it is needed */
2717 tree_data->interesting_hfids =
2718 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2719 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2720 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2721 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2722 }
2723
2724 if (!ptrs) {
2725 /* First element triggers the creation of pointer array */
2726 ptrs = g_ptr_array_new();
2727 g_hash_table_insert(tree_data->interesting_hfids,
2728 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2729 }
2730
2731 g_ptr_array_add(ptrs, fi);
2732 }
2733}
2734
2735
2736/*
2737 * Validates that field length bytes are available starting from
2738 * start (pos/neg). Throws an exception if they aren't.
2739 */
2740static void
2741test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2742 int start, int length, const unsigned encoding)
2743{
2744 int size = length;
2745
2746 if (!tvb)
2747 return;
2748
2749 if ((hfinfo->type == FT_STRINGZ) ||
2750 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2751 (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
))
))) {
2752 /* If we're fetching until the end of the TVB, only validate
2753 * that the offset is within range.
2754 */
2755 if (length == -1)
2756 size = 0;
2757 }
2758
2759 tvb_ensure_bytes_exist(tvb, start, size);
2760}
2761
2762static void
2763detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2764{
2765 bool_Bool found_stray_character = false0;
2766
2767 if (!string)
2768 return;
2769
2770 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2771 case ENC_ASCII0x00000000:
2772 case ENC_UTF_80x00000002:
2773 for (int i = (int)strlen(string); i < length; i++) {
2774 if (string[i] != '\0') {
2775 found_stray_character = true1;
2776 break;
2777 }
2778 }
2779 break;
2780
2781 default:
2782 break;
2783 }
2784
2785 if (found_stray_character) {
2786 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2787 }
2788}
2789
2790static void
2791free_fvalue_cb(void *data)
2792{
2793 fvalue_t *fv = (fvalue_t*)data;
2794 fvalue_free(fv);
2795}
2796
2797/* Add an item to a proto_tree, using the text label registered to that item;
2798 the item is extracted from the tvbuff handed to it. */
2799static proto_item *
2800proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2801 tvbuff_t *tvb, int start, int length,
2802 unsigned encoding)
2803{
2804 proto_item *pi;
2805 uint32_t value, n;
2806 uint64_t value64;
2807 ws_in4_addr ipv4_value;
2808 float floatval;
2809 double doubleval;
2810 const char *stringval = NULL((void*)0);
2811 nstime_t time_stamp;
2812 bool_Bool length_error;
2813
2814 /* Ensure that the newly created fvalue_t is freed if we throw an
2815 * exception before adding it to the tree. (gcc creates clobbering
2816 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2817 * XXX: Move the new_field_info() call inside here?
2818 */
2819 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))
;
2820
2821 switch (new_fi->hfinfo->type) {
2822 case FT_NONE:
2823 /* no value to set for FT_NONE */
2824 break;
2825
2826 case FT_PROTOCOL:
2827 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2828 break;
2829
2830 case FT_BYTES:
2831 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2832 break;
2833
2834 case FT_UINT_BYTES:
2835 n = get_uint_value(tree, tvb, start, length, encoding);
2836 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2837
2838 /* Instead of calling proto_item_set_len(), since we don't yet
2839 * have a proto_item, we set the field_info's length ourselves. */
2840 new_fi->length = n + length;
2841 break;
2842
2843 case FT_BOOLEAN:
2844 /*
2845 * Map all non-zero values to little-endian for
2846 * backwards compatibility.
2847 */
2848 if (encoding)
2849 encoding = ENC_LITTLE_ENDIAN0x80000000;
2850 proto_tree_set_boolean(new_fi,
2851 get_uint64_value(tree, tvb, start, length, encoding));
2852 break;
2853
2854 case FT_CHAR:
2855 /* XXX - make these just FT_UINT? */
2856 case FT_UINT8:
2857 case FT_UINT16:
2858 case FT_UINT24:
2859 case FT_UINT32:
2860 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2861 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2862 value = (uint32_t)value64;
2863 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2864 new_fi->flags |= FI_VARINT0x00040000;
2865 }
2866 }
2867 else {
2868 /*
2869 * Map all non-zero values to little-endian for
2870 * backwards compatibility.
2871 */
2872 if (encoding)
2873 encoding = ENC_LITTLE_ENDIAN0x80000000;
2874
2875 value = get_uint_value(tree, tvb, start, length, encoding);
2876 }
2877 proto_tree_set_uint(new_fi, value);
2878 break;
2879
2880 case FT_UINT40:
2881 case FT_UINT48:
2882 case FT_UINT56:
2883 case FT_UINT64:
2884 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2885 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2886 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2887 new_fi->flags |= FI_VARINT0x00040000;
2888 }
2889 }
2890 else {
2891 /*
2892 * Map all other non-zero values to little-endian for
2893 * backwards compatibility.
2894 */
2895 if (encoding)
2896 encoding = ENC_LITTLE_ENDIAN0x80000000;
2897
2898 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2899 }
2900 proto_tree_set_uint64(new_fi, value64);
2901 break;
2902
2903 /* XXX - make these just FT_INT? */
2904 case FT_INT8:
2905 case FT_INT16:
2906 case FT_INT24:
2907 case FT_INT32:
2908 /*
2909 * Map all non-zero values to little-endian for
2910 * backwards compatibility.
2911 */
2912 if (encoding)
2913 encoding = ENC_LITTLE_ENDIAN0x80000000;
2914 proto_tree_set_int(new_fi,
2915 get_int_value(tree, tvb, start, length, encoding));
2916 break;
2917
2918 case FT_INT40:
2919 case FT_INT48:
2920 case FT_INT56:
2921 case FT_INT64:
2922 /*
2923 * Map all non-zero values to little-endian for
2924 * backwards compatibility.
2925 */
2926 if (encoding)
2927 encoding = ENC_LITTLE_ENDIAN0x80000000;
2928 proto_tree_set_int64(new_fi,
2929 get_int64_value(tree, tvb, start, length, encoding));
2930 break;
2931
2932 case FT_IPv4:
2933 /*
2934 * Map all non-zero values to little-endian for
2935 * backwards compatibility.
2936 */
2937 if (encoding)
2938 encoding = ENC_LITTLE_ENDIAN0x80000000;
2939 if (length != FT_IPv4_LEN4) {
2940 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2941 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2942 }
2943 ipv4_value = tvb_get_ipv4(tvb, start);
2944 /*
2945 * NOTE: to support code written when
2946 * proto_tree_add_item() took a bool as its
2947 * last argument, with false meaning "big-endian"
2948 * and true meaning "little-endian", we treat any
2949 * non-zero value of "encoding" as meaning
2950 * "little-endian".
2951 */
2952 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);
2953 break;
2954
2955 case FT_IPXNET:
2956 if (length != FT_IPXNET_LEN4) {
2957 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2958 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2959 }
2960 proto_tree_set_ipxnet(new_fi,
2961 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2962 break;
2963
2964 case FT_IPv6:
2965 if (length != FT_IPv6_LEN16) {
2966 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2967 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2968 }
2969 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2970 break;
2971
2972 case FT_FCWWN:
2973 if (length != FT_FCWWN_LEN8) {
2974 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2975 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2976 }
2977 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2978 break;
2979
2980 case FT_AX25:
2981 if (length != 7) {
2982 length_error = length < 7 ? true1 : false0;
2983 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2984 }
2985 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2986 break;
2987
2988 case FT_VINES:
2989 if (length != VINES_ADDR_LEN6) {
2990 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2991 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2992 }
2993 proto_tree_set_vines_tvb(new_fi, tvb, start);
2994 break;
2995
2996 case FT_ETHER:
2997 if (length != FT_ETHER_LEN6) {
2998 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2999 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3000 }
3001 proto_tree_set_ether_tvb(new_fi, tvb, start);
3002 break;
3003
3004 case FT_EUI64:
3005 /*
3006 * Map all non-zero values to little-endian for
3007 * backwards compatibility.
3008 */
3009 if (encoding)
3010 encoding = ENC_LITTLE_ENDIAN0x80000000;
3011 if (length != FT_EUI64_LEN8) {
3012 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3013 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3014 }
3015 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3016 break;
3017 case FT_GUID:
3018 /*
3019 * Map all non-zero values to little-endian for
3020 * backwards compatibility.
3021 */
3022 if (encoding)
3023 encoding = ENC_LITTLE_ENDIAN0x80000000;
3024 if (length != FT_GUID_LEN16) {
3025 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3026 report_type_length_mismatch(tree, "a GUID", length, length_error);
3027 }
3028 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3029 break;
3030
3031 case FT_OID:
3032 case FT_REL_OID:
3033 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3034 break;
3035
3036 case FT_SYSTEM_ID:
3037 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3038 break;
3039
3040 case FT_FLOAT:
3041 /*
3042 * NOTE: to support code written when
3043 * proto_tree_add_item() took a bool as its
3044 * last argument, with false meaning "big-endian"
3045 * and true meaning "little-endian", we treat any
3046 * non-zero value of "encoding" as meaning
3047 * "little-endian".
3048 *
3049 * At some point in the future, we might
3050 * support non-IEEE-binary floating-point
3051 * formats in the encoding as well
3052 * (IEEE decimal, System/3x0, VAX).
3053 */
3054 if (encoding)
3055 encoding = ENC_LITTLE_ENDIAN0x80000000;
3056 if (length != 4) {
3057 length_error = length < 4 ? true1 : false0;
3058 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3059 }
3060 if (encoding)
3061 floatval = tvb_get_letohieee_float(tvb, start);
3062 else
3063 floatval = tvb_get_ntohieee_float(tvb, start);
3064 proto_tree_set_float(new_fi, floatval);
3065 break;
3066
3067 case FT_DOUBLE:
3068 /*
3069 * NOTE: to support code written when
3070 * proto_tree_add_item() took a bool as its
3071 * last argument, with false meaning "big-endian"
3072 * and true meaning "little-endian", we treat any
3073 * non-zero value of "encoding" as meaning
3074 * "little-endian".
3075 *
3076 * At some point in the future, we might
3077 * support non-IEEE-binary floating-point
3078 * formats in the encoding as well
3079 * (IEEE decimal, System/3x0, VAX).
3080 */
3081 if (encoding == true1)
3082 encoding = ENC_LITTLE_ENDIAN0x80000000;
3083 if (length != 8) {
3084 length_error = length < 8 ? true1 : false0;
3085 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3086 }
3087 if (encoding)
3088 doubleval = tvb_get_letohieee_double(tvb, start);
3089 else
3090 doubleval = tvb_get_ntohieee_double(tvb, start);
3091 proto_tree_set_double(new_fi, doubleval);
3092 break;
3093
3094 case FT_STRING:
3095 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3096 tvb, start, length, &length, encoding);
3097 proto_tree_set_string(new_fi, stringval);
3098
3099 /* Instead of calling proto_item_set_len(), since we
3100 * don't yet have a proto_item, we set the
3101 * field_info's length ourselves.
3102 *
3103 * XXX - our caller can't use that length to
3104 * advance an offset unless they arrange that
3105 * there always be a protocol tree into which
3106 * we're putting this item.
3107 */
3108 new_fi->length = length;
3109 break;
3110
3111 case FT_STRINGZ:
3112 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3113 tree, tvb, start, length, &length, encoding);
3114 proto_tree_set_string(new_fi, stringval);
3115
3116 /* Instead of calling proto_item_set_len(),
3117 * since we don't yet have a proto_item, we
3118 * set the field_info's length ourselves.
3119 *
3120 * XXX - our caller can't use that length to
3121 * advance an offset unless they arrange that
3122 * there always be a protocol tree into which
3123 * we're putting this item.
3124 */
3125 new_fi->length = length;
3126 break;
3127
3128 case FT_UINT_STRING:
3129 /*
3130 * NOTE: to support code written when
3131 * proto_tree_add_item() took a bool as its
3132 * last argument, with false meaning "big-endian"
3133 * and true meaning "little-endian", if the
3134 * encoding value is true, treat that as
3135 * ASCII with a little-endian length.
3136 *
3137 * This won't work for code that passes
3138 * arbitrary non-zero values; that code
3139 * will need to be fixed.
3140 */
3141 if (encoding == true1)
3142 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3143 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3144 tree, tvb, start, length, &length, encoding);
3145 proto_tree_set_string(new_fi, stringval);
3146
3147 /* Instead of calling proto_item_set_len(), since we
3148 * don't yet have a proto_item, we set the
3149 * field_info's length ourselves.
3150 *
3151 * XXX - our caller can't use that length to
3152 * advance an offset unless they arrange that
3153 * there always be a protocol tree into which
3154 * we're putting this item.
3155 */
3156 new_fi->length = length;
3157 break;
3158
3159 case FT_STRINGZPAD:
3160 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3161 tvb, start, length, &length, encoding);
3162 proto_tree_set_string(new_fi, stringval);
3163
3164 /* Instead of calling proto_item_set_len(), since we
3165 * don't yet have a proto_item, we set the
3166 * field_info's length ourselves.
3167 *
3168 * XXX - our caller can't use that length to
3169 * advance an offset unless they arrange that
3170 * there always be a protocol tree into which
3171 * we're putting this item.
3172 */
3173 new_fi->length = length;
3174 break;
3175
3176 case FT_STRINGZTRUNC:
3177 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3178 tvb, start, length, &length, encoding);
3179 proto_tree_set_string(new_fi, stringval);
3180
3181 /* Instead of calling proto_item_set_len(), since we
3182 * don't yet have a proto_item, we set the
3183 * field_info's length ourselves.
3184 *
3185 * XXX - our caller can't use that length to
3186 * advance an offset unless they arrange that
3187 * there always be a protocol tree into which
3188 * we're putting this item.
3189 */
3190 new_fi->length = length;
3191 break;
3192
3193 case FT_ABSOLUTE_TIME:
3194 /*
3195 * Absolute times can be in any of a number of
3196 * formats, and they can be big-endian or
3197 * little-endian.
3198 *
3199 * Historically FT_TIMEs were only timespecs;
3200 * the only question was whether they were stored
3201 * in big- or little-endian format.
3202 *
3203 * For backwards compatibility, we interpret an
3204 * encoding of 1 as meaning "little-endian timespec",
3205 * so that passing true is interpreted as that.
3206 */
3207 if (encoding == true1)
3208 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3209
3210 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3211
3212 proto_tree_set_time(new_fi, &time_stamp);
3213 break;
3214
3215 case FT_RELATIVE_TIME:
3216 /*
3217 * Relative times can be in any of a number of
3218 * formats, and they can be big-endian or
3219 * little-endian.
3220 *
3221 * Historically FT_TIMEs were only timespecs;
3222 * the only question was whether they were stored
3223 * in big- or little-endian format.
3224 *
3225 * For backwards compatibility, we interpret an
3226 * encoding of 1 as meaning "little-endian timespec",
3227 * so that passing true is interpreted as that.
3228 */
3229 if (encoding == true1)
3230 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3231
3232 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3233
3234 proto_tree_set_time(new_fi, &time_stamp);
3235 break;
3236 case FT_IEEE_11073_SFLOAT:
3237 if (encoding)
3238 encoding = ENC_LITTLE_ENDIAN0x80000000;
3239 if (length != 2) {
3240 length_error = length < 2 ? true1 : false0;
3241 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3242 }
3243
3244 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3245
3246 break;
3247 case FT_IEEE_11073_FLOAT:
3248 if (encoding)
3249 encoding = ENC_LITTLE_ENDIAN0x80000000;
3250 if (length != 4) {
3251 length_error = length < 4 ? true1 : false0;
3252 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3253 }
3254 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3255
3256 break;
3257 default:
3258 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))
3259 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))
3260 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))
3261 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))
;
3262 break;
3263 }
3264 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)
;
3265
3266 /* Don't add new node to proto_tree until now so that any exceptions
3267 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3268 /* XXX. wouldn't be better to add this item to tree, with some special
3269 * flag (FI_EXCEPTION?) to know which item caused exception? For
3270 * strings and bytes, we would have to set new_fi->value to something
3271 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3272 * could handle NULL values. */
3273 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3274 pi = proto_tree_add_node(tree, new_fi);
3275
3276 switch (new_fi->hfinfo->type) {
3277
3278 case FT_STRING:
3279 /* XXX: trailing stray character detection should be done
3280 * _before_ conversion to UTF-8, because conversion can change
3281 * the length, or else get_string_length should return a value
3282 * for the "length in bytes of the string after conversion
3283 * including internal nulls." (Noting that we do, for other
3284 * reasons, still need the "length in bytes in the field",
3285 * especially for FT_STRINGZ.)
3286 *
3287 * This is true even for ASCII and UTF-8, because
3288 * substituting REPLACEMENT CHARACTERS for illegal characters
3289 * can also do so (and for UTF-8 possibly even make the
3290 * string _shorter_).
3291 */
3292 detect_trailing_stray_characters(encoding, stringval, length, pi);
3293 break;
3294
3295 default:
3296 break;
3297 }
3298
3299 return pi;
3300}
3301
3302proto_item *
3303proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3304 const int start, int length,
3305 const unsigned encoding, int32_t *retval)
3306{
3307 header_field_info *hfinfo;
3308 field_info *new_fi;
3309 int32_t value;
3310
3311 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", 3311, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3311,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3311, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3312
3313 switch (hfinfo->type) {
3314 case FT_INT8:
3315 case FT_INT16:
3316 case FT_INT24:
3317 case FT_INT32:
3318 break;
3319 case FT_INT64:
3320 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)
3321 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3322 default:
3323 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)
3324 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3325 }
3326
3327 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3328 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3329 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3330 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3331 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3332 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3333 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3334
3335 if (encoding & ENC_STRING0x03000000) {
3336 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3337 }
3338 /* I believe it's ok if this is called with a NULL tree */
3339 value = get_int_value(tree, tvb, start, length, encoding);
3340
3341 if (retval) {
3342 int no_of_bits;
3343 *retval = value;
3344 if (hfinfo->bitmask) {
3345 /* Mask out irrelevant portions */
3346 *retval &= (uint32_t)(hfinfo->bitmask);
3347 /* Shift bits */
3348 *retval >>= hfinfo_bitshift(hfinfo);
3349 }
3350 no_of_bits = ws_count_ones(hfinfo->bitmask);
3351 *retval = ws_sign_ext32(*retval, no_of_bits);
3352 }
3353
3354 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3355
3356 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", 3356
, __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", 3356, "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", 3356, "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", 3356, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3357
3358 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3359
3360 proto_tree_set_int(new_fi, value);
3361
3362 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3363
3364 return proto_tree_add_node(tree, new_fi);
3365}
3366
3367proto_item *
3368proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3369 const int start, int length,
3370 const unsigned encoding, uint32_t *retval)
3371{
3372 header_field_info *hfinfo;
3373 field_info *new_fi;
3374 uint32_t value;
3375
3376 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", 3376, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3376,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3376, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3377
3378 switch (hfinfo->type) {
3379 case FT_CHAR:
3380 case FT_UINT8:
3381 case FT_UINT16:
3382 case FT_UINT24:
3383 case FT_UINT32:
3384 break;
3385 default:
3386 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)
3387 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)
;
3388 }
3389
3390 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3391 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3392 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3393 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3394 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3395 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3396 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3397
3398 if (encoding & ENC_STRING0x03000000) {
3399 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3400 }
3401 /* I believe it's ok if this is called with a NULL tree */
3402 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3403 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3404 uint64_t temp64;
3405 tvb_get_varint(tvb, start, length, &temp64, encoding);
3406 value = (uint32_t)temp64;
3407 } else {
3408 value = get_uint_value(tree, tvb, start, length, encoding);
3409 }
3410
3411 if (retval) {
3412 *retval = value;
3413 if (hfinfo->bitmask) {
3414 /* Mask out irrelevant portions */
3415 *retval &= (uint32_t)(hfinfo->bitmask);
3416 /* Shift bits */
3417 *retval >>= hfinfo_bitshift(hfinfo);
3418 }
3419 }
3420
3421 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3422
3423 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", 3423
, __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", 3423, "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", 3423, "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", 3423, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3424
3425 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3426
3427 proto_tree_set_uint(new_fi, value);
3428
3429 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3430 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3431 new_fi->flags |= FI_VARINT0x00040000;
3432 }
3433 return proto_tree_add_node(tree, new_fi);
3434}
3435
3436/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3437 * and returns proto_item* and uint value retrieved*/
3438proto_item *
3439ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3440 const unsigned encoding, uint32_t *retval)
3441{
3442 field_info *new_fi;
3443 header_field_info *hfinfo;
3444 int item_length;
3445 int offset;
3446 uint32_t value;
3447
3448 offset = ptvc->offset;
3449 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", 3449, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3449,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3449, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3450
3451 switch (hfinfo->type) {
3452 case FT_CHAR:
3453 case FT_UINT8:
3454 case FT_UINT16:
3455 case FT_UINT24:
3456 case FT_UINT32:
3457 break;
3458 default:
3459 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)
3460 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)
;
3461 }
3462
3463 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3464 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3465
3466 /* I believe it's ok if this is called with a NULL tree */
3467 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3468 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3469
3470 if (retval) {
3471 *retval = value;
3472 if (hfinfo->bitmask) {
3473 /* Mask out irrelevant portions */
3474 *retval &= (uint32_t)(hfinfo->bitmask);
3475 /* Shift bits */
3476 *retval >>= hfinfo_bitshift(hfinfo);
3477 }
3478 }
3479
3480 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3481
3482 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3483
3484 /* Coast clear. Try and fake it */
3485 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", 3485
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3485, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3485, "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", 3485, __func__, "Adding %s would put more than %d 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); } } }
;
3486
3487 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3488
3489 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3490 offset, length, encoding);
3491}
3492
3493/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3494 * and returns proto_item* and int value retrieved*/
3495proto_item *
3496ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3497 const unsigned encoding, int32_t *retval)
3498{
3499 field_info *new_fi;
3500 header_field_info *hfinfo;
3501 int item_length;
3502 int offset;
3503 uint32_t value;
3504
3505 offset = ptvc->offset;
3506 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", 3506, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3506,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3506, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3507
3508 switch (hfinfo->type) {
3509 case FT_INT8:
3510 case FT_INT16:
3511 case FT_INT24:
3512 case FT_INT32:
3513 break;
3514 default:
3515 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)
3516 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3517 }
3518
3519 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3520 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3521
3522 /* I believe it's ok if this is called with a NULL tree */
3523 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3524 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3525
3526 if (retval) {
3527 int no_of_bits;
3528 *retval = value;
3529 if (hfinfo->bitmask) {
3530 /* Mask out irrelevant portions */
3531 *retval &= (uint32_t)(hfinfo->bitmask);
3532 /* Shift bits */
3533 *retval >>= hfinfo_bitshift(hfinfo);
3534 }
3535 no_of_bits = ws_count_ones(hfinfo->bitmask);
3536 *retval = ws_sign_ext32(*retval, no_of_bits);
3537 }
3538
3539 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3540
3541 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3542
3543 /* Coast clear. Try and fake it */
3544 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", 3544
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3544, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3544, "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", 3544, __func__, "Adding %s would put more than %d 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); } } }
;
3545
3546 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3547
3548 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3549 offset, length, encoding);
3550}
3551
3552/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3553 * and returns proto_item* and string value retrieved */
3554proto_item*
3555ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3556{
3557 header_field_info *hfinfo;
3558 field_info *new_fi;
3559 const uint8_t *value;
3560 int item_length;
3561 int offset;
3562
3563 offset = ptvc->offset;
3564
3565 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", 3565
, __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", 3565, "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", 3565, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3566
3567 switch (hfinfo->type) {
3568 case FT_STRING:
3569 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3570 break;
3571 case FT_STRINGZ:
3572 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3573 break;
3574 case FT_UINT_STRING:
3575 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3576 break;
3577 case FT_STRINGZPAD:
3578 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3579 break;
3580 case FT_STRINGZTRUNC:
3581 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3582 break;
3583 default:
3584 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)
3585 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)
;
3586 }
3587
3588 if (retval)
3589 *retval = value;
3590
3591 ptvcursor_advance(ptvc, item_length);
3592
3593 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3594
3595 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", 3595, __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", 3595,
"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", 3595, "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", 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 boolean value retrieved */
3605proto_item*
3606ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3607{
3608 header_field_info *hfinfo;
3609 field_info *new_fi;
3610 int item_length;
3611 int offset;
3612 uint64_t value, bitval;
3613
3614 offset = ptvc->offset;
3615 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", 3615, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3615,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3615, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3616
3617 if (hfinfo->type != FT_BOOLEAN) {
3618 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)
3619 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3620 }
3621
3622 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3623 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3628 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3629
3630 if (encoding & ENC_STRING0x03000000) {
3631 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3632 }
3633
3634 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3635 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3636
3637 /* I believe it's ok if this is called with a NULL tree */
3638 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3639
3640 if (retval) {
3641 bitval = value;
3642 if (hfinfo->bitmask) {
3643 /* Mask out irrelevant portions */
3644 bitval &= hfinfo->bitmask;
3645 }
3646 *retval = (bitval != 0);
3647 }
3648
3649 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3650
3651 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3652
3653 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", 3653, __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", 3653,
"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", 3653, "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", 3653
, __func__, "Adding %s would put more than %d 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); } } }
;
3654
3655 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3656
3657 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3658 offset, length, encoding);
3659}
3660
3661proto_item *
3662proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3663 const int start, int length, const unsigned encoding, uint64_t *retval)
3664{
3665 header_field_info *hfinfo;
3666 field_info *new_fi;
3667 uint64_t value;
3668
3669 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", 3669, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3669,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3669, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3670
3671 switch (hfinfo->type) {
3672 case FT_UINT40:
3673 case FT_UINT48:
3674 case FT_UINT56:
3675 case FT_UINT64:
3676 break;
3677 default:
3678 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)
3679 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3680 }
3681
3682 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3683 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3684 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3685 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3686 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3687 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3688 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3689
3690 if (encoding & ENC_STRING0x03000000) {
3691 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3692 }
3693 /* I believe it's ok if this is called with a NULL tree */
3694 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3695 tvb_get_varint(tvb, start, length, &value, encoding);
3696 } else {
3697 value = get_uint64_value(tree, tvb, start, length, encoding);
3698 }
3699
3700 if (retval) {
3701 *retval = value;
3702 if (hfinfo->bitmask) {
3703 /* Mask out irrelevant portions */
3704 *retval &= hfinfo->bitmask;
3705 /* Shift bits */
3706 *retval >>= hfinfo_bitshift(hfinfo);
3707 }
3708 }
3709
3710 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3711
3712 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", 3712
, __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", 3712, "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", 3712, "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", 3712, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3713
3714 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3715
3716 proto_tree_set_uint64(new_fi, value);
3717
3718 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3719 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3720 new_fi->flags |= FI_VARINT0x00040000;
3721 }
3722
3723 return proto_tree_add_node(tree, new_fi);
3724}
3725
3726proto_item *
3727proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3728 const int start, int length, const unsigned encoding, int64_t *retval)
3729{
3730 header_field_info *hfinfo;
3731 field_info *new_fi;
3732 int64_t value;
3733
3734 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3734, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3734,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3735
3736 switch (hfinfo->type) {
3737 case FT_INT40:
3738 case FT_INT48:
3739 case FT_INT56:
3740 case FT_INT64:
3741 break;
3742 default:
3743 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)
3744 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3745 }
3746
3747 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3748 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3749 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3750 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3751 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3752 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3753 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3754
3755 if (encoding & ENC_STRING0x03000000) {
3756 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3757 }
3758 /* I believe it's ok if this is called with a NULL tree */
3759 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3760 tvb_get_varint(tvb, start, length, &value, encoding);
3761 }
3762 else {
3763 value = get_int64_value(tree, tvb, start, length, encoding);
3764 }
3765
3766 if (retval) {
3767 *retval = value;
3768 }
3769
3770 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3771
3772 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", 3772
, __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", 3772, "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", 3772, "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", 3772, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3773
3774 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3775
3776 proto_tree_set_int64(new_fi, value);
3777
3778 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3779 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3780 new_fi->flags |= FI_VARINT0x00040000;
3781 }
3782
3783 return proto_tree_add_node(tree, new_fi);
3784}
3785
3786proto_item *
3787proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3788 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3789{
3790 header_field_info *hfinfo;
3791 field_info *new_fi;
3792 uint64_t value;
3793
3794 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", 3794, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3794,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3794, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3795
3796 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
))
)) {
3797 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)
3798 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3799 }
3800
3801 /* length validation for native number encoding caught by get_uint64_value() */
3802 /* length has to be -1 or > 0 regardless of encoding */
3803 if (length == 0)
3804 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)
3805 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3806
3807 if (encoding & ENC_STRING0x03000000) {
3808 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3809 }
3810
3811 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3812
3813 if (retval) {
3814 *retval = value;
3815 if (hfinfo->bitmask) {
3816 /* Mask out irrelevant portions */
3817 *retval &= hfinfo->bitmask;
3818 /* Shift bits */
3819 *retval >>= hfinfo_bitshift(hfinfo);
3820 }
3821 }
3822
3823 if (lenretval) {
3824 *lenretval = length;
3825 }
3826
3827 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3828
3829 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", 3829
, __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", 3829, "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", 3829, "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", 3829, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3830
3831 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3832
3833 proto_tree_set_uint64(new_fi, value);
3834
3835 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3836 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3837 new_fi->flags |= FI_VARINT0x00040000;
3838 }
3839
3840 return proto_tree_add_node(tree, new_fi);
3841
3842}
3843
3844proto_item *
3845proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3846 const int start, int length,
3847 const unsigned encoding, bool_Bool *retval)
3848{
3849 header_field_info *hfinfo;
3850 field_info *new_fi;
3851 uint64_t value, bitval;
3852
3853 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", 3853, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3853,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3853, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3854
3855 if (hfinfo->type != FT_BOOLEAN) {
3856 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)
3857 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3858 }
3859
3860 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3861 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3862 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3863 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3864 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3865 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3866 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3867
3868 if (encoding & ENC_STRING0x03000000) {
3869 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3870 }
3871 /* I believe it's ok if this is called with a NULL tree */
3872 value = get_uint64_value(tree, tvb, start, length, encoding);
3873
3874 if (retval) {
3875 bitval = value;
3876 if (hfinfo->bitmask) {
3877 /* Mask out irrelevant portions */
3878 bitval &= hfinfo->bitmask;
3879 }
3880 *retval = (bitval != 0);
3881 }
3882
3883 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3884
3885 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", 3885
, __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", 3885, "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", 3885, "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", 3885, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3886
3887 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3888
3889 proto_tree_set_boolean(new_fi, value);
3890
3891 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3892
3893 return proto_tree_add_node(tree, new_fi);
3894}
3895
3896proto_item *
3897proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3898 const int start, int length,
3899 const unsigned encoding, float *retval)
3900{
3901 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3902 field_info *new_fi;
3903 float value;
3904
3905 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", 3905,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3906
3907 if (hfinfo->type != FT_FLOAT) {
3908 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)
;
3909 }
3910
3911 if (length != 4) {
3912 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3913 }
3914
3915 /* treat any nonzero encoding as little endian for backwards compatibility */
3916 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3917 if (retval) {
3918 *retval = value;
3919 }
3920
3921 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3922
3923 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", 3923
, __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", 3923, "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", 3923, "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", 3923, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3924
3925 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3926 if (encoding) {
3927 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3928 }
3929
3930 proto_tree_set_float(new_fi, value);
3931
3932 return proto_tree_add_node(tree, new_fi);
3933}
3934
3935proto_item *
3936proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3937 const int start, int length,
3938 const unsigned encoding, double *retval)
3939{
3940 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3941 field_info *new_fi;
3942 double value;
3943
3944 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", 3944,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3945
3946 if (hfinfo->type != FT_DOUBLE) {
3947 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)
;
3948 }
3949
3950 if (length != 8) {
3951 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3952 }
3953
3954 /* treat any nonzero encoding as little endian for backwards compatibility */
3955 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3956 if (retval) {
3957 *retval = value;
3958 }
3959
3960 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3961
3962 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", 3962
, __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", 3962, "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", 3962, "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", 3962, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3963
3964 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3965 if (encoding) {
3966 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3967 }
3968
3969 proto_tree_set_double(new_fi, value);
3970
3971 return proto_tree_add_node(tree, new_fi);
3972}
3973
3974proto_item *
3975proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3976 const int start, int length,
3977 const unsigned encoding, ws_in4_addr *retval)
3978{
3979 header_field_info *hfinfo;
3980 field_info *new_fi;
3981 ws_in4_addr value;
3982
3983 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", 3983, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3983,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3983, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3984
3985 switch (hfinfo->type) {
3986 case FT_IPv4:
3987 break;
3988 default:
3989 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)
3990 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3991 }
3992
3993 if (length != FT_IPv4_LEN4)
3994 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)
3995 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3996
3997 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3998 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3999 }
4000
4001 /*
4002 * NOTE: to support code written when proto_tree_add_item() took
4003 * a bool as its last argument, with false meaning "big-endian"
4004 * and true meaning "little-endian", we treat any non-zero value
4005 * of "encoding" as meaning "little-endian".
4006 */
4007 value = tvb_get_ipv4(tvb, start);
4008 if (encoding)
4009 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))))
;
4010
4011 if (retval) {
4012 *retval = value;
4013 }
4014
4015 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4016
4017 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", 4017
, __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", 4017, "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", 4017, "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", 4017, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4018
4019 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4020
4021 proto_tree_set_ipv4(new_fi, value);
4022
4023 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4024 return proto_tree_add_node(tree, new_fi);
4025}
4026
4027proto_item *
4028proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4029 const int start, int length,
4030 const unsigned encoding, ws_in6_addr *addr)
4031{
4032 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4033 field_info *new_fi;
4034
4035 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", 4035,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4036
4037 switch (hfinfo->type) {
4038 case FT_IPv6:
4039 break;
4040 default:
4041 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)
4042 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4043 }
4044
4045 if (length != FT_IPv6_LEN16)
4046 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)
4047 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4048
4049 if (encoding) {
4050 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"
)
;
4051 }
4052
4053 tvb_get_ipv6(tvb, start, addr);
4054
4055 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4056
4057 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", 4057
, __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", 4057, "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", 4057, "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", 4057, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4058
4059 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4060
4061 proto_tree_set_ipv6(new_fi, addr);
4062
4063 return proto_tree_add_node(tree, new_fi);
4064}
4065
4066proto_item *
4067proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4068 const int start, int length, const unsigned encoding, uint8_t *retval) {
4069
4070 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4071 field_info *new_fi;
4072
4073 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", 4073,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4074
4075 switch (hfinfo->type) {
4076 case FT_ETHER:
4077 break;
4078 default:
4079 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)
4080 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4081 }
4082
4083 if (length != FT_ETHER_LEN6)
4084 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)
4085 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4086
4087 if (encoding) {
4088 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"
)
;
4089 }
4090
4091 tvb_memcpy(tvb, retval, start, length);
4092
4093 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4094
4095 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", 4095
, __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", 4095, "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", 4095, "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", 4095, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4096
4097 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4098
4099 proto_tree_set_ether(new_fi, retval);
4100
4101 return proto_tree_add_node(tree, new_fi);
4102}
4103
4104
4105proto_item *
4106proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4107 tvbuff_t *tvb,
4108 const int start, int length,
4109 const unsigned encoding,
4110 wmem_allocator_t *scope,
4111 const uint8_t **retval,
4112 int *lenretval)
4113{
4114 proto_item *pi;
4115 header_field_info *hfinfo;
4116 field_info *new_fi;
4117 const uint8_t *value;
4118
4119 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", 4119, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4119,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4119, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4120
4121 switch (hfinfo->type) {
4122 case FT_STRING:
4123 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4124 break;
4125 case FT_STRINGZ:
4126 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4127 break;
4128 case FT_UINT_STRING:
4129 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4130 break;
4131 case FT_STRINGZPAD:
4132 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4133 break;
4134 case FT_STRINGZTRUNC:
4135 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4136 break;
4137 default:
4138 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)
4139 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)
;
4140 }
4141
4142 if (retval)
4143 *retval = value;
4144
4145 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4146
4147 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", 4147
, __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", 4147, "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", 4147, "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", 4147, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4148
4149 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4150
4151 proto_tree_set_string(new_fi, value);
4152
4153 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4154
4155 pi = proto_tree_add_node(tree, new_fi);
4156
4157 switch (hfinfo->type) {
4158
4159 case FT_STRINGZ:
4160 case FT_STRINGZPAD:
4161 case FT_STRINGZTRUNC:
4162 case FT_UINT_STRING:
4163 break;
4164
4165 case FT_STRING:
4166 detect_trailing_stray_characters(encoding, value, length, pi);
4167 break;
4168
4169 default:
4170 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4170
, __func__, "assertion \"not reached\" failed")
;
4171 }
4172
4173 return pi;
4174}
4175
4176proto_item *
4177proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4178 const int start, int length,
4179 const unsigned encoding, wmem_allocator_t *scope,
4180 const uint8_t **retval)
4181{
4182 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4183 tvb, start, length, encoding, scope, retval, &length);
4184}
4185
4186proto_item *
4187proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4188 tvbuff_t *tvb,
4189 const int start, int length,
4190 const unsigned encoding,
4191 wmem_allocator_t *scope,
4192 char **retval,
4193 int *lenretval)
4194{
4195 proto_item *pi;
4196 header_field_info *hfinfo;
4197 field_info *new_fi;
4198 const uint8_t *value;
4199 uint32_t n = 0;
4200
4201 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", 4201, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4201,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4201, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4202
4203 switch (hfinfo->type) {
4204 case FT_STRING:
4205 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4206 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4207 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4208 break;
4209 case FT_STRINGZ:
4210 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4211 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4212 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4213 break;
4214 case FT_UINT_STRING:
4215 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4216 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4217 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4218 break;
4219 case FT_STRINGZPAD:
4220 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4221 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4222 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4223 break;
4224 case FT_STRINGZTRUNC:
4225 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4226 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4227 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4228 break;
4229 case FT_BYTES:
4230 tvb_ensure_bytes_exist(tvb, start, length);
4231 value = tvb_get_ptr(tvb, start, length);
4232 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4233 *lenretval = length;
4234 break;
4235 case FT_UINT_BYTES:
4236 n = get_uint_value(tree, tvb, start, length, encoding);
4237 tvb_ensure_bytes_exist(tvb, start + length, n);
4238 value = tvb_get_ptr(tvb, start + length, n);
4239 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4240 *lenretval = length + n;
4241 break;
4242 default:
4243 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)
4244 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)
;
4245 }
4246
4247 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4248
4249 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", 4249
, __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", 4249, "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", 4249, "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", 4249, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4250
4251 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4252
4253 switch (hfinfo->type) {
4254
4255 case FT_STRING:
4256 case FT_STRINGZ:
4257 case FT_UINT_STRING:
4258 case FT_STRINGZPAD:
4259 case FT_STRINGZTRUNC:
4260 proto_tree_set_string(new_fi, value);
4261 break;
4262
4263 case FT_BYTES:
4264 proto_tree_set_bytes(new_fi, value, length);
4265 break;
4266
4267 case FT_UINT_BYTES:
4268 proto_tree_set_bytes(new_fi, value, n);
4269 break;
4270
4271 default:
4272 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4272
, __func__, "assertion \"not reached\" failed")
;
4273 }
4274
4275 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4276
4277 pi = proto_tree_add_node(tree, new_fi);
4278
4279 switch (hfinfo->type) {
4280
4281 case FT_STRINGZ:
4282 case FT_STRINGZPAD:
4283 case FT_STRINGZTRUNC:
4284 case FT_UINT_STRING:
4285 break;
4286
4287 case FT_STRING:
4288 detect_trailing_stray_characters(encoding, value, length, pi);
4289 break;
4290
4291 case FT_BYTES:
4292 case FT_UINT_BYTES:
4293 break;
4294
4295 default:
4296 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4296
, __func__, "assertion \"not reached\" failed")
;
4297 }
4298
4299 return pi;
4300}
4301
4302proto_item *
4303proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4304 tvbuff_t *tvb,
4305 const int start, int length,
4306 const unsigned encoding,
4307 wmem_allocator_t *scope,
4308 char **retval)
4309{
4310 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4311 tvb, start, length, encoding, scope, retval, &length);
4312}
4313
4314proto_item *
4315proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4316 tvbuff_t *tvb,
4317 const int start, int length, const unsigned encoding,
4318 wmem_allocator_t *scope, char **retval)
4319{
4320 header_field_info *hfinfo;
4321 field_info *new_fi;
4322 nstime_t time_stamp;
4323 int flags;
4324
4325 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", 4325, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4325,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4325, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4326
4327 switch (hfinfo->type) {
4328 case FT_ABSOLUTE_TIME:
4329 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4330 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4331 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4332 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4333 }
4334 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4335 break;
4336 case FT_RELATIVE_TIME:
4337 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4338 *retval = rel_time_to_secs_str(scope, &time_stamp);
4339 break;
4340 default:
4341 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)
4342 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4343 }
4344
4345 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4346
4347 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", 4347
, __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", 4347, "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", 4347, "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", 4347, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4348
4349 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4350
4351 switch (hfinfo->type) {
4352
4353 case FT_ABSOLUTE_TIME:
4354 case FT_RELATIVE_TIME:
4355 proto_tree_set_time(new_fi, &time_stamp);
4356 break;
4357 default:
4358 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4358
, __func__, "assertion \"not reached\" failed")
;
4359 }
4360
4361 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4362
4363 return proto_tree_add_node(tree, new_fi);
4364}
4365
4366/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4367 and returns proto_item* */
4368proto_item *
4369ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4370 const unsigned encoding)
4371{
4372 field_info *new_fi;
4373 header_field_info *hfinfo;
4374 int item_length;
4375 int offset;
4376
4377 offset = ptvc->offset;
4378 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", 4378, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4378,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4378, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4379 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4380 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4381
4382 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4383
4384 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4385
4386 /* Coast clear. Try and fake it */
4387 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", 4387
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4387, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4387, "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", 4387, __func__, "Adding %s would put more than %d 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); } } }
;
4388
4389 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4390
4391 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4392 offset, length, encoding);
4393}
4394
4395/* Add an item to a proto_tree, using the text label registered to that item;
4396 the item is extracted from the tvbuff handed to it. */
4397proto_item *
4398proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4399 const int start, int length, const unsigned encoding)
4400{
4401 field_info *new_fi;
4402 int item_length;
4403
4404 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", 4404,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4405
4406 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4407 test_length(hfinfo, tvb, start, item_length, encoding);
4408
4409 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4410
4411 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", 4411
, __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", 4411, "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", 4411, "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", 4411, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4412
4413 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4414
4415 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4416}
4417
4418proto_item *
4419proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4420 const int start, int length, const unsigned encoding)
4421{
4422 register header_field_info *hfinfo;
4423
4424 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", 4424, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4424,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4424, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4425 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4426}
4427
4428/* Add an item to a proto_tree, using the text label registered to that item;
4429 the item is extracted from the tvbuff handed to it.
4430
4431 Return the length of the item through the pointer. */
4432proto_item *
4433proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4434 tvbuff_t *tvb, const int start,
4435 int length, const unsigned encoding,
4436 int *lenretval)
4437{
4438 field_info *new_fi;
4439 int item_length;
4440 proto_item *item;
4441
4442 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", 4442,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4443
4444 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4445 test_length(hfinfo, tvb, start, item_length, encoding);
4446
4447 if (!tree) {
4448 /*
4449 * We need to get the correct item length here.
4450 * That's normally done by proto_tree_new_item(),
4451 * but we won't be calling it.
4452 */
4453 *lenretval = get_full_length(hfinfo, tvb, start, length,
4454 item_length, encoding);
4455 return NULL((void*)0);
4456 }
4457
4458 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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4459 /*((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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4460 * 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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4461 * 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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4462 */((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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4463 *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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4464 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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4465 })((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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4466
4467 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4468
4469 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4470 *lenretval = new_fi->length;
4471 return item;
4472}
4473
4474proto_item *
4475proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4476 const int start, int length,
4477 const unsigned encoding, int *lenretval)
4478{
4479 register header_field_info *hfinfo;
4480
4481 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", 4481, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4481,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4481, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4482 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4483}
4484
4485/* which FT_ types can use proto_tree_add_bytes_item() */
4486static inline bool_Bool
4487validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4488{
4489 return (type == FT_BYTES ||
4490 type == FT_UINT_BYTES ||
4491 type == FT_OID ||
4492 type == FT_REL_OID ||
4493 type == FT_SYSTEM_ID );
4494}
4495
4496/* Note: this does no validation that the byte array of an FT_OID or
4497 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4498 so I think it's ok to continue not validating it?
4499 */
4500proto_item *
4501proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4502 const int start, int length, const unsigned encoding,
4503 GByteArray *retval, int *endoff, int *err)
4504{
4505 field_info *new_fi;
4506 GByteArray *bytes = retval;
4507 GByteArray *created_bytes = NULL((void*)0);
4508 bool_Bool failed = false0;
4509 uint32_t n = 0;
4510 header_field_info *hfinfo;
4511 bool_Bool generate = (bytes || tree) ? true1 : false0;
4512
4513 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4513, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4513,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4513, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4514
4515 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", 4515,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4516
4517 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", 4518, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4518 "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", 4518, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4519
4520 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4521
4522 if (encoding & ENC_STR_NUM0x01000000) {
4523 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"
)
;
4524 }
4525
4526 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4527 if (hfinfo->type == FT_UINT_BYTES) {
4528 /* can't decode FT_UINT_BYTES from strings */
4529 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")
4530 "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")
;
4531 }
4532
4533 unsigned hex_encoding = encoding;
4534 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4535 /* If none of the separator values are used,
4536 * assume no separator (the common case). */
4537 hex_encoding |= ENC_SEP_NONE0x00010000;
4538#if 0
4539 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")
4540 "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")
;
4541#endif
4542 }
4543
4544 if (!bytes) {
4545 /* caller doesn't care about return value, but we need it to
4546 call tvb_get_string_bytes() and set the tree later */
4547 bytes = created_bytes = g_byte_array_new();
4548 }
4549
4550 /*
4551 * bytes might be NULL after this, but can't add expert
4552 * error until later; if it's NULL, just note that
4553 * it failed.
4554 */
4555 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4556 if (bytes == NULL((void*)0))
4557 failed = true1;
4558 }
4559 else if (generate) {
4560 tvb_ensure_bytes_exist(tvb, start, length);
4561
4562 if (hfinfo->type == FT_UINT_BYTES) {
4563 n = length; /* n is now the "header" length */
4564 length = get_uint_value(tree, tvb, start, n, encoding);
4565 /* length is now the value's length; only store the value in the array */
4566 tvb_ensure_bytes_exist(tvb, start + n, length);
4567 if (!bytes) {
4568 /* caller doesn't care about return value, but
4569 * we may need it to set the tree later */
4570 bytes = created_bytes = g_byte_array_new();
4571 }
4572 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4573 }
4574 else if (length > 0) {
4575 if (!bytes) {
4576 /* caller doesn't care about return value, but
4577 * we may need it to set the tree later */
4578 bytes = created_bytes = g_byte_array_new();
4579 }
4580 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4581 }
4582
4583 if (endoff)
4584 *endoff = start + n + length;
4585 }
4586
4587 if (err)
4588 *err = failed ? EINVAL22 : 0;
4589
4590 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); }
4591 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4592 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); }
4593 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); }
4594 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); }
4595 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4596 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4597
4598 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4599 {((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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4600 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4601 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4602 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4603 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4604 } )((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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4605
4606 /* n will be zero except when it's a FT_UINT_BYTES */
4607 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4608
4609 if (encoding & ENC_STRING0x03000000) {
4610 if (failed)
4611 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4612
4613 if (bytes)
4614 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4615 else
4616 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4617
4618 if (created_bytes)
4619 g_byte_array_free(created_bytes, true1);
4620 }
4621 else {
4622 /* n will be zero except when it's a FT_UINT_BYTES */
4623 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4624
4625 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4626 * use the byte array created above in this case.
4627 */
4628 if (created_bytes)
4629 g_byte_array_free(created_bytes, true1);
4630
4631 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4632 (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)
;
4633 }
4634
4635 return proto_tree_add_node(tree, new_fi);
4636}
4637
4638
4639proto_item *
4640proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4641 const int start, int length, const unsigned encoding,
4642 nstime_t *retval, int *endoff, int *err)
4643{
4644 field_info *new_fi;
4645 nstime_t time_stamp;
4646 int saved_err = 0;
4647 header_field_info *hfinfo;
4648
4649 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", 4649, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4649,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4649, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4650
4651 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", 4651,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4652
4653 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4654 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4655 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4656 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4657 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4658 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4659 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4660
4661 nstime_set_zero(&time_stamp);
4662
4663 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4664 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", 4664, ((hfinfo))->abbrev))))
;
4665 /* The only string format that could be a relative time is
4666 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4667 * relative to "now" currently.
4668 */
4669 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4670 saved_err = EINVAL22;
4671 }
4672 else {
4673 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", 4673, ((hfinfo))->abbrev))))
;
4674 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4675
4676 tvb_ensure_bytes_exist(tvb, start, length);
4677 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4678 if (endoff) *endoff = start + length;
4679 }
4680
4681 if (err) *err = saved_err;
4682
4683 if (retval) {
4684 retval->secs = time_stamp.secs;
4685 retval->nsecs = time_stamp.nsecs;
4686 }
4687
4688 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4689
4690 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", 4690
, __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", 4690, "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", 4690, "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", 4690, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4691
4692 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4693
4694 proto_tree_set_time(new_fi, &time_stamp);
4695
4696 if (encoding & ENC_STRING0x03000000) {
4697 if (saved_err)
4698 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4699 }
4700 else {
4701 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4702 (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)
;
4703 }
4704
4705 return proto_tree_add_node(tree, new_fi);
4706}
4707
4708/* Add a FT_NONE to a proto_tree */
4709proto_item *
4710proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4711 const int start, int length, const char *format,
4712 ...)
4713{
4714 proto_item *pi;
4715 va_list ap;
4716 header_field_info *hfinfo;
4717
4718 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4719
4720 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", 4720
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4720, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4720, "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", 4720, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4721
4722 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", 4722
, ((hfinfo))->abbrev))))
;
4723
4724 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4725
4726 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4726, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4727
4728 va_start(ap, format)__builtin_va_start(ap, format);
4729 proto_tree_set_representation(pi, format, ap);
4730 va_end(ap)__builtin_va_end(ap);
4731
4732 /* no value to set for FT_NONE */
4733 return pi;
4734}
4735
4736/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4737 * offset, and returns proto_item* */
4738proto_item *
4739ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4740 const unsigned encoding)
4741{
4742 proto_item *item;
4743
4744 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4745 length, encoding);
4746
4747 return item;
4748}
4749
4750/* Advance the ptvcursor's offset within its tvbuff without
4751 * adding anything to the proto_tree. */
4752void
4753ptvcursor_advance(ptvcursor_t* ptvc, int length)
4754{
4755 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4756 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4757 }
4758}
4759
4760
4761static void
4762proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4763{
4764 fvalue_set_protocol(fi->value, tvb, field_data, length);
4765}
4766
4767/* Add a FT_PROTOCOL to a proto_tree */
4768proto_item *
4769proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4770 int start, int length, const char *format, ...)
4771{
4772 proto_item *pi;
4773 tvbuff_t *protocol_tvb;
4774 va_list ap;
4775 header_field_info *hfinfo;
4776 char* protocol_rep;
4777
4778 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4779
4780 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", 4780
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4780, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4780, "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", 4780, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4781
4782 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"
, 4782, ((hfinfo))->abbrev))))
;
4783
4784 /*
4785 * This can throw an exception, so do it before we allocate anything.
4786 */
4787 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4788
4789 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4790
4791 va_start(ap, format)__builtin_va_start(ap, format);
4792 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4793 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4794 g_free(protocol_rep);
4795 va_end(ap)__builtin_va_end(ap);
4796
4797 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4797, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4798
4799 va_start(ap, format)__builtin_va_start(ap, format);
4800 proto_tree_set_representation(pi, format, ap);
4801 va_end(ap)__builtin_va_end(ap);
4802
4803 return pi;
4804}
4805
4806/* Add a FT_BYTES to a proto_tree */
4807proto_item *
4808proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4809 int length, const uint8_t *start_ptr)
4810{
4811 proto_item *pi;
4812 header_field_info *hfinfo;
4813 int item_length;
4814
4815 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", 4815, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4815,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4815, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4816 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4817 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4818
4819 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4820
4821 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", 4821
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4821, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4821, "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", 4821, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4822
4823 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",
4823, ((hfinfo))->abbrev))))
;
4824
4825 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4826 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4827
4828 return pi;
4829}
4830
4831/* Add a FT_BYTES to a proto_tree */
4832proto_item *
4833proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4834 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4835{
4836 proto_item *pi;
4837 header_field_info *hfinfo;
4838 int item_length;
4839
4840 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", 4840, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4840,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4840, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4841 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4842 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4843
4844 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4845
4846 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", 4846
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4846, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4846, "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", 4846, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4847
4848 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",
4848, ((hfinfo))->abbrev))))
;
4849
4850 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4851 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4852
4853 return pi;
4854}
4855
4856proto_item *
4857proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4858 int start, int length,
4859 const uint8_t *start_ptr,
4860 const char *format, ...)
4861{
4862 proto_item *pi;
4863 va_list ap;
4864
4865 if (start_ptr == NULL((void*)0))
4866 start_ptr = tvb_get_ptr(tvb, start, length);
4867
4868 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4869
4870 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; }
;
4871
4872 va_start(ap, format)__builtin_va_start(ap, format);
4873 proto_tree_set_representation_value(pi, format, ap);
4874 va_end(ap)__builtin_va_end(ap);
4875
4876 return pi;
4877}
4878
4879proto_item *
4880proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4881 int start, int length, const uint8_t *start_ptr,
4882 const char *format, ...)
4883{
4884 proto_item *pi;
4885 va_list ap;
4886
4887 if (start_ptr == NULL((void*)0))
4888 start_ptr = tvb_get_ptr(tvb, start, length);
4889
4890 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4891
4892 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; }
;
4893
4894 va_start(ap, format)__builtin_va_start(ap, format);
4895 proto_tree_set_representation(pi, format, ap);
4896 va_end(ap)__builtin_va_end(ap);
4897
4898 return pi;
4899}
4900
4901static void
4902proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4903{
4904 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4904, "length >= 0"
))))
;
4905 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", 4905, "start_ptr != ((void*)0) || length == 0"
))))
;
4906
4907 fvalue_set_bytes_data(fi->value, start_ptr, length);
4908}
4909
4910
4911static void
4912proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4913{
4914 tvb_ensure_bytes_exist(tvb, offset, length);
4915 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4916}
4917
4918static void
4919proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4920{
4921 GByteArray *bytes;
4922
4923 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4923, "value != ((void*)0)"
))))
;
4924
4925 bytes = byte_array_dup(value);
4926
4927 fvalue_set_byte_array(fi->value, bytes);
4928}
4929
4930/* Add a FT_*TIME to a proto_tree */
4931proto_item *
4932proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4933 int length, const nstime_t *value_ptr)
4934{
4935 proto_item *pi;
4936 header_field_info *hfinfo;
4937
4938 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4939
4940 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", 4940
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4940, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4940, "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", 4940, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4941
4942 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", 4942, ((hfinfo))->abbrev))))
;
4943
4944 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4945 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4946
4947 return pi;
4948}
4949
4950proto_item *
4951proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4952 int start, int length, nstime_t *value_ptr,
4953 const char *format, ...)
4954{
4955 proto_item *pi;
4956 va_list ap;
4957
4958 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4959 if (pi != tree) {
4960 va_start(ap, format)__builtin_va_start(ap, format);
4961 proto_tree_set_representation_value(pi, format, ap);
4962 va_end(ap)__builtin_va_end(ap);
4963 }
4964
4965 return pi;
4966}
4967
4968proto_item *
4969proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4970 int start, int length, nstime_t *value_ptr,
4971 const char *format, ...)
4972{
4973 proto_item *pi;
4974 va_list ap;
4975
4976 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4977 if (pi != tree) {
4978 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4978, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4979
4980 va_start(ap, format)__builtin_va_start(ap, format);
4981 proto_tree_set_representation(pi, format, ap);
4982 va_end(ap)__builtin_va_end(ap);
4983 }
4984
4985 return pi;
4986}
4987
4988/* Set the FT_*TIME value */
4989static void
4990proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4991{
4992 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4992, "value_ptr != ((void*)0)"
))))
;
4993
4994 fvalue_set_time(fi->value, value_ptr);
4995}
4996
4997/* Add a FT_IPXNET to a proto_tree */
4998proto_item *
4999proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5000 int length, uint32_t value)
5001{
5002 proto_item *pi;
5003 header_field_info *hfinfo;
5004
5005 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5006
5007 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", 5007
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5007, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5007, "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", 5007, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5008
5009 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"
, 5009, ((hfinfo))->abbrev))))
;
5010
5011 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5012 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5013
5014 return pi;
5015}
5016
5017proto_item *
5018proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5019 int start, int length, uint32_t value,
5020 const char *format, ...)
5021{
5022 proto_item *pi;
5023 va_list ap;
5024
5025 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5026 if (pi != tree) {
5027 va_start(ap, format)__builtin_va_start(ap, format);
5028 proto_tree_set_representation_value(pi, format, ap);
5029 va_end(ap)__builtin_va_end(ap);
5030 }
5031
5032 return pi;
5033}
5034
5035proto_item *
5036proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5037 int start, int length, uint32_t value,
5038 const char *format, ...)
5039{
5040 proto_item *pi;
5041 va_list ap;
5042
5043 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5044 if (pi != tree) {
5045 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5045, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5046
5047 va_start(ap, format)__builtin_va_start(ap, format);
5048 proto_tree_set_representation(pi, format, ap);
5049 va_end(ap)__builtin_va_end(ap);
5050 }
5051
5052 return pi;
5053}
5054
5055/* Set the FT_IPXNET value */
5056static void
5057proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5058{
5059 fvalue_set_uinteger(fi->value, value);
5060}
5061
5062/* Add a FT_IPv4 to a proto_tree */
5063proto_item *
5064proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5065 int length, ws_in4_addr value)
5066{
5067 proto_item *pi;
5068 header_field_info *hfinfo;
5069
5070 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5071
5072 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", 5072
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5072, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5072, "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", 5072, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5073
5074 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", 5074
, ((hfinfo))->abbrev))))
;
5075
5076 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5077 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5078
5079 return pi;
5080}
5081
5082proto_item *
5083proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5084 int start, int length, ws_in4_addr value,
5085 const char *format, ...)
5086{
5087 proto_item *pi;
5088 va_list ap;
5089
5090 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5091 if (pi != tree) {
5092 va_start(ap, format)__builtin_va_start(ap, format);
5093 proto_tree_set_representation_value(pi, format, ap);
5094 va_end(ap)__builtin_va_end(ap);
5095 }
5096
5097 return pi;
5098}
5099
5100proto_item *
5101proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5102 int start, int length, ws_in4_addr value,
5103 const char *format, ...)
5104{
5105 proto_item *pi;
5106 va_list ap;
5107
5108 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5109 if (pi != tree) {
5110 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5110, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5111
5112 va_start(ap, format)__builtin_va_start(ap, format);
5113 proto_tree_set_representation(pi, format, ap);
5114 va_end(ap)__builtin_va_end(ap);
5115 }
5116
5117 return pi;
5118}
5119
5120/* Set the FT_IPv4 value */
5121static void
5122proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5123{
5124 ipv4_addr_and_mask ipv4;
5125 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5126 fvalue_set_ipv4(fi->value, &ipv4);
5127}
5128
5129/* Add a FT_IPv6 to a proto_tree */
5130proto_item *
5131proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5132 int length, const ws_in6_addr *value)
5133{
5134 proto_item *pi;
5135 header_field_info *hfinfo;
5136
5137 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5138
5139 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", 5139
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5139, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5139, "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", 5139, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5140
5141 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", 5141
, ((hfinfo))->abbrev))))
;
5142
5143 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5144 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5145
5146 return pi;
5147}
5148
5149proto_item *
5150proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5151 int start, int length,
5152 const ws_in6_addr *value_ptr,
5153 const char *format, ...)
5154{
5155 proto_item *pi;
5156 va_list ap;
5157
5158 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5159 if (pi != tree) {
5160 va_start(ap, format)__builtin_va_start(ap, format);
5161 proto_tree_set_representation_value(pi, format, ap);
5162 va_end(ap)__builtin_va_end(ap);
5163 }
5164
5165 return pi;
5166}
5167
5168proto_item *
5169proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5170 int start, int length,
5171 const ws_in6_addr *value_ptr,
5172 const char *format, ...)
5173{
5174 proto_item *pi;
5175 va_list ap;
5176
5177 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5178 if (pi != tree) {
5179 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5179, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5180
5181 va_start(ap, format)__builtin_va_start(ap, format);
5182 proto_tree_set_representation(pi, format, ap);
5183 va_end(ap)__builtin_va_end(ap);
5184 }
5185
5186 return pi;
5187}
5188
5189/* Set the FT_IPv6 value */
5190static void
5191proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5192{
5193 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5193, "value != ((void*)0)"
))))
;
5194 ipv6_addr_and_prefix ipv6;
5195 ipv6.addr = *value;
5196 ipv6.prefix = 128;
5197 fvalue_set_ipv6(fi->value, &ipv6);
5198}
5199
5200static void
5201proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5202{
5203 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5204}
5205
5206/* Set the FT_FCWWN value */
5207static void
5208proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5209{
5210 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5210, "value_ptr != ((void*)0)"
))))
;
5211 fvalue_set_fcwwn(fi->value, value_ptr);
5212}
5213
5214static void
5215proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5216{
5217 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5218}
5219
5220/* Add a FT_GUID to a proto_tree */
5221proto_item *
5222proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5223 int length, const e_guid_t *value_ptr)
5224{
5225 proto_item *pi;
5226 header_field_info *hfinfo;
5227
5228 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5229
5230 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", 5230
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5230, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5230, "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", 5230, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5231
5232 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", 5232
, ((hfinfo))->abbrev))))
;
5233
5234 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5235 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5236
5237 return pi;
5238}
5239
5240proto_item *
5241proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5242 int start, int length,
5243 const e_guid_t *value_ptr,
5244 const char *format, ...)
5245{
5246 proto_item *pi;
5247 va_list ap;
5248
5249 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5250 if (pi != tree) {
5251 va_start(ap, format)__builtin_va_start(ap, format);
5252 proto_tree_set_representation_value(pi, format, ap);
5253 va_end(ap)__builtin_va_end(ap);
5254 }
5255
5256 return pi;
5257}
5258
5259proto_item *
5260proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5261 int start, int length, const e_guid_t *value_ptr,
5262 const char *format, ...)
5263{
5264 proto_item *pi;
5265 va_list ap;
5266
5267 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5268 if (pi != tree) {
5269 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5269, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5270
5271 va_start(ap, format)__builtin_va_start(ap, format);
5272 proto_tree_set_representation(pi, format, ap);
5273 va_end(ap)__builtin_va_end(ap);
5274 }
5275
5276 return pi;
5277}
5278
5279/* Set the FT_GUID value */
5280static void
5281proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5282{
5283 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5283, "value_ptr != ((void*)0)"
))))
;
5284 fvalue_set_guid(fi->value, value_ptr);
5285}
5286
5287static void
5288proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5289 const unsigned encoding)
5290{
5291 e_guid_t guid;
5292
5293 tvb_get_guid(tvb, start, &guid, encoding);
5294 proto_tree_set_guid(fi, &guid);
5295}
5296
5297/* Add a FT_OID to a proto_tree */
5298proto_item *
5299proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5300 int length, const uint8_t* value_ptr)
5301{
5302 proto_item *pi;
5303 header_field_info *hfinfo;
5304
5305 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5306
5307 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", 5307
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5307, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5307, "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", 5307, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5308
5309 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", 5309
, ((hfinfo))->abbrev))))
;
5310
5311 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5312 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5313
5314 return pi;
5315}
5316
5317proto_item *
5318proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5319 int start, int length,
5320 const uint8_t* value_ptr,
5321 const char *format, ...)
5322{
5323 proto_item *pi;
5324 va_list ap;
5325
5326 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5327 if (pi != tree) {
5328 va_start(ap, format)__builtin_va_start(ap, format);
5329 proto_tree_set_representation_value(pi, format, ap);
5330 va_end(ap)__builtin_va_end(ap);
5331 }
5332
5333 return pi;
5334}
5335
5336proto_item *
5337proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5338 int start, int length, const uint8_t* value_ptr,
5339 const char *format, ...)
5340{
5341 proto_item *pi;
5342 va_list ap;
5343
5344 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5345 if (pi != tree) {
5346 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5346, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5347
5348 va_start(ap, format)__builtin_va_start(ap, format);
5349 proto_tree_set_representation(pi, format, ap);
5350 va_end(ap)__builtin_va_end(ap);
5351 }
5352
5353 return pi;
5354}
5355
5356/* Set the FT_OID value */
5357static void
5358proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5359{
5360 GByteArray *bytes;
5361
5362 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", 5362, "value_ptr != ((void*)0) || length == 0"
))))
;
5363
5364 bytes = g_byte_array_new();
5365 if (length > 0) {
5366 g_byte_array_append(bytes, value_ptr, length);
5367 }
5368 fvalue_set_byte_array(fi->value, bytes);
5369}
5370
5371static void
5372proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5373{
5374 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5375}
5376
5377/* Set the FT_SYSTEM_ID value */
5378static void
5379proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5380{
5381 GByteArray *bytes;
5382
5383 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", 5383, "value_ptr != ((void*)0) || length == 0"
))))
;
5384
5385 bytes = g_byte_array_new();
5386 if (length > 0) {
5387 g_byte_array_append(bytes, value_ptr, length);
5388 }
5389 fvalue_set_byte_array(fi->value, bytes);
5390}
5391
5392static void
5393proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5394{
5395 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5396}
5397
5398/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5399 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5400 * is destroyed. */
5401proto_item *
5402proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5403 int length, const char* value)
5404{
5405 proto_item *pi;
5406 header_field_info *hfinfo;
5407 int item_length;
5408
5409 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", 5409, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5409,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5409, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5410 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5411 /*
5412 * Special case - if the length is 0, skip the test, so that
5413 * we can have an empty string right after the end of the
5414 * packet. (This handles URL-encoded forms where the last field
5415 * has no value so the form ends right after the =.)
5416 */
5417 if (item_length != 0)
5418 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5419
5420 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5421
5422 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", 5422
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5422, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5422, "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", 5422, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5423
5424 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", 5424, ((hfinfo))->abbrev))))
;
5425
5426 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5427 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5427, "length >= 0"
))))
;
5428
5429 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", 5429, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5430 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5431
5432 return pi;
5433}
5434
5435proto_item *
5436proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5437 int start, int length, const char* value,
5438 const char *format,
5439 ...)
5440{
5441 proto_item *pi;
5442 va_list ap;
5443
5444 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5445 if (pi != tree) {
5446 va_start(ap, format)__builtin_va_start(ap, format);
5447 proto_tree_set_representation_value(pi, format, ap);
5448 va_end(ap)__builtin_va_end(ap);
5449 }
5450
5451 return pi;
5452}
5453
5454proto_item *
5455proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5456 int start, int length, const char* value,
5457 const char *format, ...)
5458{
5459 proto_item *pi;
5460 va_list ap;
5461
5462 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5463 if (pi != tree) {
5464 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5464, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5465
5466 va_start(ap, format)__builtin_va_start(ap, format);
5467 proto_tree_set_representation(pi, format, ap);
5468 va_end(ap)__builtin_va_end(ap);
5469 }
5470
5471 return pi;
5472}
5473
5474/* Set the FT_STRING value */
5475static void
5476proto_tree_set_string(field_info *fi, const char* value)
5477{
5478 if (value) {
5479 fvalue_set_string(fi->value, value);
5480 } else {
5481 /*
5482 * XXX - why is a null value for a string field
5483 * considered valid?
5484 */
5485 fvalue_set_string(fi->value, "[ Null ]");
5486 }
5487}
5488
5489/* Set the FT_AX25 value */
5490static void
5491proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5492{
5493 fvalue_set_ax25(fi->value, value);
5494}
5495
5496static void
5497proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5498{
5499 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5500}
5501
5502/* Set the FT_VINES value */
5503static void
5504proto_tree_set_vines(field_info *fi, const uint8_t* value)
5505{
5506 fvalue_set_vines(fi->value, value);
5507}
5508
5509static void
5510proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5511{
5512 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5513}
5514
5515/* Add a FT_ETHER to a proto_tree */
5516proto_item *
5517proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5518 int length, const uint8_t* value)
5519{
5520 proto_item *pi;
5521 header_field_info *hfinfo;
5522
5523 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5524
5525 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", 5525
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5525, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5525, "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", 5525, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5526
5527 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",
5527, ((hfinfo))->abbrev))))
;
5528
5529 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5530 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5531
5532 return pi;
5533}
5534
5535proto_item *
5536proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5537 int start, int length, const uint8_t* value,
5538 const char *format, ...)
5539{
5540 proto_item *pi;
5541 va_list ap;
5542
5543 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5544 if (pi != tree) {
5545 va_start(ap, format)__builtin_va_start(ap, format);
5546 proto_tree_set_representation_value(pi, format, ap);
5547 va_end(ap)__builtin_va_end(ap);
5548 }
5549
5550 return pi;
5551}
5552
5553proto_item *
5554proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5555 int start, int length, const uint8_t* value,
5556 const char *format, ...)
5557{
5558 proto_item *pi;
5559 va_list ap;
5560
5561 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5562 if (pi != tree) {
5563 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5563, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5564
5565 va_start(ap, format)__builtin_va_start(ap, format);
5566 proto_tree_set_representation(pi, format, ap);
5567 va_end(ap)__builtin_va_end(ap);
5568 }
5569
5570 return pi;
5571}
5572
5573/* Set the FT_ETHER value */
5574static void
5575proto_tree_set_ether(field_info *fi, const uint8_t* value)
5576{
5577 fvalue_set_ether(fi->value, value);
5578}
5579
5580static void
5581proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5582{
5583 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5584}
5585
5586/* Add a FT_BOOLEAN to a proto_tree */
5587proto_item *
5588proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5589 int length, uint64_t value)
5590{
5591 proto_item *pi;
5592 header_field_info *hfinfo;
5593
5594 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5595
5596 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", 5596
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5596, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5596, "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", 5596, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5597
5598 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"
, 5598, ((hfinfo))->abbrev))))
;
5599
5600 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5601 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5602
5603 return pi;
5604}
5605
5606proto_item *
5607proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5608 tvbuff_t *tvb, int start, int length,
5609 uint64_t value, const char *format, ...)
5610{
5611 proto_item *pi;
5612 va_list ap;
5613
5614 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5615 if (pi != tree) {
5616 va_start(ap, format)__builtin_va_start(ap, format);
5617 proto_tree_set_representation_value(pi, format, ap);
5618 va_end(ap)__builtin_va_end(ap);
5619 }
5620
5621 return pi;
5622}
5623
5624proto_item *
5625proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5626 int start, int length, uint64_t value,
5627 const char *format, ...)
5628{
5629 proto_item *pi;
5630 va_list ap;
5631
5632 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5633 if (pi != tree) {
5634 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5634, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5635
5636 va_start(ap, format)__builtin_va_start(ap, format);
5637 proto_tree_set_representation(pi, format, ap);
5638 va_end(ap)__builtin_va_end(ap);
5639 }
5640
5641 return pi;
5642}
5643
5644/* Set the FT_BOOLEAN value */
5645static void
5646proto_tree_set_boolean(field_info *fi, uint64_t value)
5647{
5648 proto_tree_set_uint64(fi, value);
5649}
5650
5651/* Generate, into "buf", a string showing the bits of a bitfield.
5652 Return a pointer to the character after that string. */
5653static char *
5654other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5655{
5656 int i = 0;
5657 uint64_t bit;
5658 char *p;
5659
5660 p = buf;
5661
5662 /* This is a devel error. It is safer to stop here. */
5663 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5663, "width >= 1"
))))
;
5664
5665 bit = UINT64_C(1)1UL << (width - 1);
5666 for (;;) {
5667 if (mask & bit) {
5668 /* This bit is part of the field. Show its value. */
5669 if (val & bit)
5670 *p++ = '1';
5671 else
5672 *p++ = '0';
5673 } else {
5674 /* This bit is not part of the field. */
5675 *p++ = '.';
5676 }
5677 bit >>= 1;
5678 i++;
5679 if (i >= width)
5680 break;
5681 if (i % 4 == 0)
5682 *p++ = ' ';
5683 }
5684 *p = '\0';
5685 return p;
5686}
5687
5688static char *
5689decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5690{
5691 char *p;
5692
5693 p = other_decode_bitfield_value(buf, val, mask, width);
5694 p = g_stpcpy(p, " = ");
5695
5696 return p;
5697}
5698
5699static char *
5700other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5701{
5702 int i = 0;
5703 uint64_t bit;
5704 char *p;
5705
5706 p = buf;
5707
5708 /* This is a devel error. It is safer to stop here. */
5709 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5709, "width >= 1"
))))
;
5710
5711 bit = UINT64_C(1)1UL << (width - 1);
5712 for (;;) {
5713 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5714 (mask & bit)) {
5715 /* This bit is part of the field. Show its value. */
5716 if (val & bit)
5717 *p++ = '1';
5718 else
5719 *p++ = '0';
5720 } else {
5721 /* This bit is not part of the field. */
5722 *p++ = '.';
5723 }
5724 bit >>= 1;
5725 i++;
5726 if (i >= width)
5727 break;
5728 if (i % 4 == 0)
5729 *p++ = ' ';
5730 }
5731
5732 *p = '\0';
5733 return p;
5734}
5735
5736static char *
5737decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5738{
5739 char *p;
5740
5741 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5742 p = g_stpcpy(p, " = ");
5743
5744 return p;
5745}
5746
5747/* Add a FT_FLOAT to a proto_tree */
5748proto_item *
5749proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5750 int length, float value)
5751{
5752 proto_item *pi;
5753 header_field_info *hfinfo;
5754
5755 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5756
5757 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", 5757
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5757, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5757, "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", 5757, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5758
5759 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",
5759, ((hfinfo))->abbrev))))
;
5760
5761 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5762 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5763
5764 return pi;
5765}
5766
5767proto_item *
5768proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5769 int start, int length, float value,
5770 const char *format, ...)
5771{
5772 proto_item *pi;
5773 va_list ap;
5774
5775 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5776 if (pi != tree) {
5777 va_start(ap, format)__builtin_va_start(ap, format);
5778 proto_tree_set_representation_value(pi, format, ap);
5779 va_end(ap)__builtin_va_end(ap);
5780 }
5781
5782 return pi;
5783}
5784
5785proto_item *
5786proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5787 int start, int length, float value,
5788 const char *format, ...)
5789{
5790 proto_item *pi;
5791 va_list ap;
5792
5793 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5794 if (pi != tree) {
5795 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5795, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5796
5797 va_start(ap, format)__builtin_va_start(ap, format);
5798 proto_tree_set_representation(pi, format, ap);
5799 va_end(ap)__builtin_va_end(ap);
5800 }
5801
5802 return pi;
5803}
5804
5805/* Set the FT_FLOAT value */
5806static void
5807proto_tree_set_float(field_info *fi, float value)
5808{
5809 fvalue_set_floating(fi->value, value);
5810}
5811
5812/* Add a FT_DOUBLE to a proto_tree */
5813proto_item *
5814proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5815 int length, double value)
5816{
5817 proto_item *pi;
5818 header_field_info *hfinfo;
5819
5820 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5821
5822 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", 5822
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5822, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5822, "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", 5822, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5823
5824 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"
, 5824, ((hfinfo))->abbrev))))
;
5825
5826 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5827 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5828
5829 return pi;
5830}
5831
5832proto_item *
5833proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5834 int start, int length, double value,
5835 const char *format, ...)
5836{
5837 proto_item *pi;
5838 va_list ap;
5839
5840 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5841 if (pi != tree) {
5842 va_start(ap, format)__builtin_va_start(ap, format);
5843 proto_tree_set_representation_value(pi, format, ap);
5844 va_end(ap)__builtin_va_end(ap);
5845 }
5846
5847 return pi;
5848}
5849
5850proto_item *
5851proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5852 int start, int length, double value,
5853 const char *format, ...)
5854{
5855 proto_item *pi;
5856 va_list ap;
5857
5858 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5859 if (pi != tree) {
5860 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5860, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5861
5862 va_start(ap, format)__builtin_va_start(ap, format);
5863 proto_tree_set_representation(pi, format, ap);
5864 va_end(ap)__builtin_va_end(ap);
5865 }
5866
5867 return pi;
5868}
5869
5870/* Set the FT_DOUBLE value */
5871static void
5872proto_tree_set_double(field_info *fi, double value)
5873{
5874 fvalue_set_floating(fi->value, value);
5875}
5876
5877/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5878proto_item *
5879proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5880 int length, uint32_t value)
5881{
5882 proto_item *pi = NULL((void*)0);
5883 header_field_info *hfinfo;
5884
5885 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5886
5887 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", 5887
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5887, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5887, "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", 5887, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5888
5889 switch (hfinfo->type) {
5890 case FT_CHAR:
5891 case FT_UINT8:
5892 case FT_UINT16:
5893 case FT_UINT24:
5894 case FT_UINT32:
5895 case FT_FRAMENUM:
5896 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5897 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5898 break;
5899
5900 default:
5901 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)
5902 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)
;
5903 }
5904
5905 return pi;
5906}
5907
5908proto_item *
5909proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5910 int start, int length, uint32_t value,
5911 const char *format, ...)
5912{
5913 proto_item *pi;
5914 va_list ap;
5915
5916 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5917 if (pi != tree) {
5918 va_start(ap, format)__builtin_va_start(ap, format);
5919 proto_tree_set_representation_value(pi, format, ap);
5920 va_end(ap)__builtin_va_end(ap);
5921 }
5922
5923 return pi;
5924}
5925
5926proto_item *
5927proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5928 int start, int length, uint32_t value,
5929 const char *format, ...)
5930{
5931 proto_item *pi;
5932 va_list ap;
5933
5934 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5935 if (pi != tree) {
5936 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5936, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5937
5938 va_start(ap, format)__builtin_va_start(ap, format);
5939 proto_tree_set_representation(pi, format, ap);
5940 va_end(ap)__builtin_va_end(ap);
5941 }
5942
5943 return pi;
5944}
5945
5946/* Set the FT_UINT{8,16,24,32} value */
5947static void
5948proto_tree_set_uint(field_info *fi, uint32_t value)
5949{
5950 const header_field_info *hfinfo;
5951 uint32_t integer;
5952
5953 hfinfo = fi->hfinfo;
5954 integer = value;
5955
5956 if (hfinfo->bitmask) {
5957 /* Mask out irrelevant portions */
5958 integer &= (uint32_t)(hfinfo->bitmask);
5959
5960 /* Shift bits */
5961 integer >>= hfinfo_bitshift(hfinfo);
5962
5963 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5964 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)
;
5965 }
5966
5967 fvalue_set_uinteger(fi->value, integer);
5968}
5969
5970/* Add FT_UINT{40,48,56,64} to a proto_tree */
5971proto_item *
5972proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5973 int length, uint64_t value)
5974{
5975 proto_item *pi = NULL((void*)0);
5976 header_field_info *hfinfo;
5977
5978 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5979
5980 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", 5980
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5980, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5980, "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", 5980, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5981
5982 switch (hfinfo->type) {
5983 case FT_UINT40:
5984 case FT_UINT48:
5985 case FT_UINT56:
5986 case FT_UINT64:
5987 case FT_FRAMENUM:
5988 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5989 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5990 break;
5991
5992 default:
5993 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)
5994 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)
;
5995 }
5996
5997 return pi;
5998}
5999
6000proto_item *
6001proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6002 int start, int length, uint64_t value,
6003 const char *format, ...)
6004{
6005 proto_item *pi;
6006 va_list ap;
6007
6008 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6009 if (pi != tree) {
6010 va_start(ap, format)__builtin_va_start(ap, format);
6011 proto_tree_set_representation_value(pi, format, ap);
6012 va_end(ap)__builtin_va_end(ap);
6013 }
6014
6015 return pi;
6016}
6017
6018proto_item *
6019proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6020 int start, int length, uint64_t value,
6021 const char *format, ...)
6022{
6023 proto_item *pi;
6024 va_list ap;
6025
6026 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6027 if (pi != tree) {
6028 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6028, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6029
6030 va_start(ap, format)__builtin_va_start(ap, format);
6031 proto_tree_set_representation(pi, format, ap);
6032 va_end(ap)__builtin_va_end(ap);
6033 }
6034
6035 return pi;
6036}
6037
6038/* Set the FT_UINT{40,48,56,64} value */
6039static void
6040proto_tree_set_uint64(field_info *fi, uint64_t value)
6041{
6042 const header_field_info *hfinfo;
6043 uint64_t integer;
6044
6045 hfinfo = fi->hfinfo;
6046 integer = value;
6047
6048 if (hfinfo->bitmask) {
6049 /* Mask out irrelevant portions */
6050 integer &= hfinfo->bitmask;
6051
6052 /* Shift bits */
6053 integer >>= hfinfo_bitshift(hfinfo);
6054
6055 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6056 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)
;
6057 }
6058
6059 fvalue_set_uinteger64(fi->value, integer);
6060}
6061
6062/* Add FT_INT{8,16,24,32} to a proto_tree */
6063proto_item *
6064proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6065 int length, int32_t value)
6066{
6067 proto_item *pi = NULL((void*)0);
6068 header_field_info *hfinfo;
6069
6070 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6071
6072 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", 6072
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6072, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6072, "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", 6072, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6073
6074 switch (hfinfo->type) {
6075 case FT_INT8:
6076 case FT_INT16:
6077 case FT_INT24:
6078 case FT_INT32:
6079 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6080 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6081 break;
6082
6083 default:
6084 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)
6085 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6086 }
6087
6088 return pi;
6089}
6090
6091proto_item *
6092proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6093 int start, int length, int32_t value,
6094 const char *format, ...)
6095{
6096 proto_item *pi;
6097 va_list ap;
6098
6099 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6100 if (pi != tree) {
6101 va_start(ap, format)__builtin_va_start(ap, format);
6102 proto_tree_set_representation_value(pi, format, ap);
6103 va_end(ap)__builtin_va_end(ap);
6104 }
6105
6106 return pi;
6107}
6108
6109proto_item *
6110proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6111 int start, int length, int32_t value,
6112 const char *format, ...)
6113{
6114 proto_item *pi;
6115 va_list ap;
6116
6117 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6118 if (pi != tree) {
6119 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6119, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6120
6121 va_start(ap, format)__builtin_va_start(ap, format);
6122 proto_tree_set_representation(pi, format, ap);
6123 va_end(ap)__builtin_va_end(ap);
6124 }
6125
6126 return pi;
6127}
6128
6129/* Set the FT_INT{8,16,24,32} value */
6130static void
6131proto_tree_set_int(field_info *fi, int32_t value)
6132{
6133 const header_field_info *hfinfo;
6134 uint32_t integer;
6135 int no_of_bits;
6136
6137 hfinfo = fi->hfinfo;
6138 integer = (uint32_t) value;
6139
6140 if (hfinfo->bitmask) {
6141 /* Mask out irrelevant portions */
6142 integer &= (uint32_t)(hfinfo->bitmask);
6143
6144 /* Shift bits */
6145 integer >>= hfinfo_bitshift(hfinfo);
6146
6147 no_of_bits = ws_count_ones(hfinfo->bitmask);
6148 integer = ws_sign_ext32(integer, no_of_bits);
6149
6150 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6151 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)
;
6152 }
6153
6154 fvalue_set_sinteger(fi->value, integer);
6155}
6156
6157/* Add FT_INT{40,48,56,64} to a proto_tree */
6158proto_item *
6159proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6160 int length, int64_t value)
6161{
6162 proto_item *pi = NULL((void*)0);
6163 header_field_info *hfinfo;
6164
6165 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6166
6167 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", 6167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6167, "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", 6167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6168
6169 switch (hfinfo->type) {
6170 case FT_INT40:
6171 case FT_INT48:
6172 case FT_INT56:
6173 case FT_INT64:
6174 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6175 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6176 break;
6177
6178 default:
6179 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)
6180 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6181 }
6182
6183 return pi;
6184}
6185
6186proto_item *
6187proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6188 int start, int length, int64_t value,
6189 const char *format, ...)
6190{
6191 proto_item *pi;
6192 va_list ap;
6193
6194 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6195 if (pi != tree) {
6196 va_start(ap, format)__builtin_va_start(ap, format);
6197 proto_tree_set_representation_value(pi, format, ap);
6198 va_end(ap)__builtin_va_end(ap);
6199 }
6200
6201 return pi;
6202}
6203
6204/* Set the FT_INT{40,48,56,64} value */
6205static void
6206proto_tree_set_int64(field_info *fi, int64_t value)
6207{
6208 const header_field_info *hfinfo;
6209 uint64_t integer;
6210 int no_of_bits;
6211
6212 hfinfo = fi->hfinfo;
6213 integer = value;
6214
6215 if (hfinfo->bitmask) {
6216 /* Mask out irrelevant portions */
6217 integer &= hfinfo->bitmask;
6218
6219 /* Shift bits */
6220 integer >>= hfinfo_bitshift(hfinfo);
6221
6222 no_of_bits = ws_count_ones(hfinfo->bitmask);
6223 integer = ws_sign_ext64(integer, no_of_bits);
6224
6225 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6226 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)
;
6227 }
6228
6229 fvalue_set_sinteger64(fi->value, integer);
6230}
6231
6232proto_item *
6233proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6234 int start, int length, int64_t value,
6235 const char *format, ...)
6236{
6237 proto_item *pi;
6238 va_list ap;
6239
6240 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6241 if (pi != tree) {
6242 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6242, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6243
6244 va_start(ap, format)__builtin_va_start(ap, format);
6245 proto_tree_set_representation(pi, format, ap);
6246 va_end(ap)__builtin_va_end(ap);
6247 }
6248
6249 return pi;
6250}
6251
6252/* Add a FT_EUI64 to a proto_tree */
6253proto_item *
6254proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6255 int length, const uint64_t value)
6256{
6257 proto_item *pi;
6258 header_field_info *hfinfo;
6259
6260 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6261
6262 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", 6262
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6262, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6262, "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", 6262, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6263
6264 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",
6264, ((hfinfo))->abbrev))))
;
6265
6266 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6267 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6268
6269 return pi;
6270}
6271
6272proto_item *
6273proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6274 int start, int length, const uint64_t value,
6275 const char *format, ...)
6276{
6277 proto_item *pi;
6278 va_list ap;
6279
6280 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6281 if (pi != tree) {
6282 va_start(ap, format)__builtin_va_start(ap, format);
6283 proto_tree_set_representation_value(pi, format, ap);
6284 va_end(ap)__builtin_va_end(ap);
6285 }
6286
6287 return pi;
6288}
6289
6290proto_item *
6291proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6292 int start, int length, const uint64_t value,
6293 const char *format, ...)
6294{
6295 proto_item *pi;
6296 va_list ap;
6297
6298 pi = proto_tree_add_eui64(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/* Set the FT_EUI64 value */
6311static void
6312proto_tree_set_eui64(field_info *fi, const uint64_t value)
6313{
6314 uint8_t v[FT_EUI64_LEN8];
6315 phtonu64(v, value);
6316 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6317}
6318
6319static void
6320proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6321{
6322 if (encoding)
6323 {
6324 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6325 } else {
6326 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6327 }
6328}
6329
6330proto_item *
6331proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6332 const mac_hf_list_t *list_generic,
6333 int idx, tvbuff_t *tvb,
6334 proto_tree *tree, int offset)
6335{
6336 uint8_t addr[6];
6337 const char *addr_name = NULL((void*)0);
6338 const char *oui_name = NULL((void*)0);
6339 proto_item *addr_item = NULL((void*)0);
6340 proto_tree *addr_tree = NULL((void*)0);
6341 proto_item *ret_val = NULL((void*)0);
6342
6343 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6344 return NULL((void*)0);
6345 }
6346
6347 /* Resolve what we can of the address */
6348 tvb_memcpy(tvb, addr, offset, sizeof addr);
6349 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6350 addr_name = get_ether_name(addr);
6351 }
6352 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6353 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6354 }
6355
6356 /* Add the item for the specific address type */
6357 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6358 if (idx >= 0) {
6359 addr_tree = proto_item_add_subtree(ret_val, idx);
6360 }
6361 else {
6362 addr_tree = tree;
6363 }
6364
6365 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6366 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6367 tvb, offset, 6, addr_name);
6368 proto_item_set_generated(addr_item);
6369 proto_item_set_hidden(addr_item);
6370 }
6371
6372 if (list_specific->hf_oui != NULL((void*)0)) {
6373 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6374 proto_item_set_generated(addr_item);
6375 proto_item_set_hidden(addr_item);
6376
6377 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6378 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6379 proto_item_set_generated(addr_item);
6380 proto_item_set_hidden(addr_item);
6381 }
6382 }
6383
6384 if (list_specific->hf_lg != NULL((void*)0)) {
6385 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6386 }
6387 if (list_specific->hf_ig != NULL((void*)0)) {
6388 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6389 }
6390
6391 /* Were we given a list for generic address fields? If not, stop here */
6392 if (list_generic == NULL((void*)0)) {
6393 return ret_val;
6394 }
6395
6396 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6397 proto_item_set_hidden(addr_item);
6398
6399 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6400 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6401 tvb, offset, 6, addr_name);
6402 proto_item_set_generated(addr_item);
6403 proto_item_set_hidden(addr_item);
6404 }
6405
6406 if (list_generic->hf_oui != NULL((void*)0)) {
6407 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6408 proto_item_set_generated(addr_item);
6409 proto_item_set_hidden(addr_item);
6410
6411 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6412 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6413 proto_item_set_generated(addr_item);
6414 proto_item_set_hidden(addr_item);
6415 }
6416 }
6417
6418 if (list_generic->hf_lg != NULL((void*)0)) {
6419 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6420 proto_item_set_hidden(addr_item);
6421 }
6422 if (list_generic->hf_ig != NULL((void*)0)) {
6423 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6424 proto_item_set_hidden(addr_item);
6425 }
6426 return ret_val;
6427}
6428
6429static proto_item *
6430proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6431{
6432 proto_node *pnode, *tnode, *sibling;
6433 field_info *tfi;
6434 unsigned depth = 1;
6435
6436 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6436, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6437
6438 /*
6439 * Restrict our depth. proto_tree_traverse_pre_order and
6440 * proto_tree_traverse_post_order (and possibly others) are recursive
6441 * so we need to be mindful of our stack size.
6442 */
6443 if (tree->first_child == NULL((void*)0)) {
6444 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6445 depth++;
6446 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6447 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__)), 6450)))
6448 "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__)), 6450)))
6449 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__)), 6450)))
6450 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__)), 6450)))
;
6451 }
6452 }
6453 }
6454
6455 /*
6456 * Make sure "tree" is ready to have subtrees under it, by
6457 * checking whether it's been given an ett_ value.
6458 *
6459 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6460 * node of the protocol tree. That node is not displayed,
6461 * so it doesn't need an ett_ value to remember whether it
6462 * was expanded.
6463 */
6464 tnode = tree;
6465 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6466 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6467 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"
, 6468)
6468 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"
, 6468)
;
6469 /* XXX - is it safe to continue here? */
6470 }
6471
6472 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6473 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6474 pnode->parent = tnode;
6475 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6476 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6477 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6478
6479 if (tnode->last_child != NULL((void*)0)) {
6480 sibling = tnode->last_child;
6481 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6481, "sibling->next == ((void*)0)"
))))
;
6482 sibling->next = pnode;
6483 } else
6484 tnode->first_child = pnode;
6485 tnode->last_child = pnode;
6486
6487 /* We should not be adding a fake node for an interesting field */
6488 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", 6488, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6489
6490 /* XXX - Should the proto_item have a header_field_info member, at least
6491 * for faked items, to know what hfi was faked? (Some dissectors look at
6492 * the tree items directly.)
6493 */
6494 return (proto_item *)pnode;
6495}
6496
6497/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6498static proto_item *
6499proto_tree_add_node(proto_tree *tree, field_info *fi)
6500{
6501 proto_node *pnode, *tnode, *sibling;
6502 field_info *tfi;
6503 unsigned depth = 1;
6504
6505 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6505, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6506
6507 /*
6508 * Restrict our depth. proto_tree_traverse_pre_order and
6509 * proto_tree_traverse_post_order (and possibly others) are recursive
6510 * so we need to be mindful of our stack size.
6511 */
6512 if (tree->first_child == NULL((void*)0)) {
6513 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6514 depth++;
6515 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6516 fvalue_free(fi->value);
6517 fi->value = NULL((void*)0);
6518 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__)), 6521)))
6519 "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__)), 6521)))
6520 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__)), 6521)))
6521 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__)), 6521)))
;
6522 }
6523 }
6524 }
6525
6526 /*
6527 * Make sure "tree" is ready to have subtrees under it, by
6528 * checking whether it's been given an ett_ value.
6529 *
6530 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6531 * node of the protocol tree. That node is not displayed,
6532 * so it doesn't need an ett_ value to remember whether it
6533 * was expanded.
6534 */
6535 tnode = tree;
6536 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6537 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6538 /* Since we are not adding fi to a node, its fvalue won't get
6539 * freed by proto_tree_free_node(), so free it now.
6540 */
6541 fvalue_free(fi->value);
6542 fi->value = NULL((void*)0);
6543 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", 6544)
6544 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", 6544)
;
6545 /* XXX - is it safe to continue here? */
6546 }
6547
6548 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6549 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6550 pnode->parent = tnode;
6551 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6552 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6553 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6554
6555 if (tnode->last_child != NULL((void*)0)) {
6556 sibling = tnode->last_child;
6557 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6557, "sibling->next == ((void*)0)"
))))
;
6558 sibling->next = pnode;
6559 } else
6560 tnode->first_child = pnode;
6561 tnode->last_child = pnode;
6562
6563 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6564
6565 return (proto_item *)pnode;
6566}
6567
6568
6569/* Generic way to allocate field_info and add to proto_tree.
6570 * Sets *pfi to address of newly-allocated field_info struct */
6571static proto_item *
6572proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6573 int *length)
6574{
6575 proto_item *pi;
6576 field_info *fi;
6577 int item_length;
6578
6579 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6580 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6581 pi = proto_tree_add_node(tree, fi);
6582
6583 return pi;
6584}
6585
6586
6587static void
6588get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6589 int *item_length, const unsigned encoding)
6590{
6591 int length_remaining;
6592
6593 /*
6594 * We only allow a null tvbuff if the item has a zero length,
6595 * i.e. if there's no data backing it.
6596 */
6597 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", 6597, "tvb != ((void*)0) || *length == 0"
))))
;
6598
6599 /*
6600 * XXX - in some protocols, there are 32-bit unsigned length
6601 * fields, so lengths in protocol tree and tvbuff routines
6602 * should really be unsigned. We should have, for those
6603 * field types for which "to the end of the tvbuff" makes sense,
6604 * additional routines that take no length argument and
6605 * add fields that run to the end of the tvbuff.
6606 */
6607 if (*length == -1) {
6608 /*
6609 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6610 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6611 * of -1 means "set the length to what remains in the
6612 * tvbuff".
6613 *
6614 * The assumption is either that
6615 *
6616 * 1) the length of the item can only be determined
6617 * by dissection (typically true of items with
6618 * subitems, which are probably FT_NONE or
6619 * FT_PROTOCOL)
6620 *
6621 * or
6622 *
6623 * 2) if the tvbuff is "short" (either due to a short
6624 * snapshot length or due to lack of reassembly of
6625 * fragments/segments/whatever), we want to display
6626 * what's available in the field (probably FT_BYTES
6627 * or FT_STRING) and then throw an exception later
6628 *
6629 * or
6630 *
6631 * 3) the field is defined to be "what's left in the
6632 * packet"
6633 *
6634 * so we set the length to what remains in the tvbuff so
6635 * that, if we throw an exception while dissecting, it
6636 * has what is probably the right value.
6637 *
6638 * For FT_STRINGZ, it means "the string is null-terminated,
6639 * not null-padded; set the length to the actual length
6640 * of the string", and if the tvbuff if short, we just
6641 * throw an exception.
6642 *
6643 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6644 * it means "find the end of the string",
6645 * and if the tvbuff if short, we just throw an exception.
6646 *
6647 * It's not valid for any other type of field. For those
6648 * fields, we treat -1 the same way we treat other
6649 * negative values - we assume the length is a Really
6650 * Big Positive Number, and throw a ReportedBoundsError
6651 * exception, under the assumption that the Really Big
6652 * Length would run past the end of the packet.
6653 */
6654 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
))
)) {
6655 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6656 /*
6657 * Leave the length as -1, so our caller knows
6658 * it was -1.
6659 */
6660 *item_length = *length;
6661 return;
6662 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6663 switch (tvb_get_uint8(tvb, start) >> 6)
6664 {
6665 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6666 *item_length = 1;
6667 break;
6668 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6669 *item_length = 2;
6670 break;
6671 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6672 *item_length = 4;
6673 break;
6674 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6675 *item_length = 8;
6676 break;
6677 }
6678 }
6679 }
6680
6681 switch (hfinfo->type) {
6682
6683 case FT_PROTOCOL:
6684 case FT_NONE:
6685 case FT_BYTES:
6686 case FT_STRING:
6687 case FT_STRINGZPAD:
6688 case FT_STRINGZTRUNC:
6689 /*
6690 * We allow FT_PROTOCOLs to be zero-length -
6691 * for example, an ONC RPC NULL procedure has
6692 * neither arguments nor reply, so the
6693 * payload for that protocol is empty.
6694 *
6695 * We also allow the others to be zero-length -
6696 * because that's the way the code has been for a
6697 * long, long time.
6698 *
6699 * However, we want to ensure that the start
6700 * offset is not *past* the byte past the end
6701 * of the tvbuff: we throw an exception in that
6702 * case.
6703 */
6704 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6705 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6705, "*length >= 0"
))))
;
6706 break;
6707
6708 case FT_STRINGZ:
6709 /*
6710 * Leave the length as -1, so our caller knows
6711 * it was -1.
6712 */
6713 break;
6714
6715 default:
6716 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6717 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6717))
;
6718 }
6719 *item_length = *length;
6720 } else {
6721 *item_length = *length;
6722 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6723 /*
6724 * These types are for interior nodes of the
6725 * tree, and don't have data associated with
6726 * them; if the length is negative (XXX - see
6727 * above) or goes past the end of the tvbuff,
6728 * cut it short at the end of the tvbuff.
6729 * That way, if this field is selected in
6730 * Wireshark, we don't highlight stuff past
6731 * the end of the data.
6732 */
6733 /* XXX - what to do, if we don't have a tvb? */
6734 if (tvb) {
6735 length_remaining = tvb_captured_length_remaining(tvb, start);
6736 if (*item_length < 0 ||
6737 (*item_length > 0 &&
6738 (length_remaining < *item_length)))
6739 *item_length = length_remaining;
6740 }
6741 }
6742 if (*item_length < 0) {
6743 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6744 }
6745 }
6746}
6747
6748static int
6749get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6750 int length, unsigned item_length, const int encoding)
6751{
6752 uint32_t n;
6753
6754 /*
6755 * We need to get the correct item length here.
6756 * That's normally done by proto_tree_new_item(),
6757 * but we won't be calling it.
6758 */
6759 switch (hfinfo->type) {
6760
6761 case FT_NONE:
6762 case FT_PROTOCOL:
6763 case FT_BYTES:
6764 /*
6765 * The length is the specified length.
6766 */
6767 break;
6768
6769 case FT_UINT_BYTES:
6770 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6771 item_length += n;
6772 if ((int)item_length < length) {
6773 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6774 }
6775 break;
6776
6777 /* XXX - make these just FT_UINT? */
6778 case FT_UINT8:
6779 case FT_UINT16:
6780 case FT_UINT24:
6781 case FT_UINT32:
6782 case FT_UINT40:
6783 case FT_UINT48:
6784 case FT_UINT56:
6785 case FT_UINT64:
6786 /* XXX - make these just FT_INT? */
6787 case FT_INT8:
6788 case FT_INT16:
6789 case FT_INT24:
6790 case FT_INT32:
6791 case FT_INT40:
6792 case FT_INT48:
6793 case FT_INT56:
6794 case FT_INT64:
6795 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6796 if (length < -1) {
6797 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6798 }
6799 if (length == -1) {
6800 uint64_t dummy;
6801 /* This can throw an exception */
6802 /* XXX - do this without fetching the varint? */
6803 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6804 if (length == 0) {
6805 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6806 }
6807 }
6808 item_length = length;
6809 break;
6810 }
6811
6812 /*
6813 * The length is the specified length.
6814 */
6815 break;
6816
6817 case FT_BOOLEAN:
6818 case FT_CHAR:
6819 case FT_IPv4:
6820 case FT_IPXNET:
6821 case FT_IPv6:
6822 case FT_FCWWN:
6823 case FT_AX25:
6824 case FT_VINES:
6825 case FT_ETHER:
6826 case FT_EUI64:
6827 case FT_GUID:
6828 case FT_OID:
6829 case FT_REL_OID:
6830 case FT_SYSTEM_ID:
6831 case FT_FLOAT:
6832 case FT_DOUBLE:
6833 case FT_STRING:
6834 /*
6835 * The length is the specified length.
6836 */
6837 break;
6838
6839 case FT_STRINGZ:
6840 if (length < -1) {
6841 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6842 }
6843 if (length == -1) {
6844 /* This can throw an exception */
6845 /* XXX - do this without fetching the string? */
6846 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6847 }
6848 item_length = length;
6849 break;
6850
6851 case FT_UINT_STRING:
6852 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6853 item_length += n;
6854 if ((int)item_length < length) {
6855 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6856 }
6857 break;
6858
6859 case FT_STRINGZPAD:
6860 case FT_STRINGZTRUNC:
6861 case FT_ABSOLUTE_TIME:
6862 case FT_RELATIVE_TIME:
6863 case FT_IEEE_11073_SFLOAT:
6864 case FT_IEEE_11073_FLOAT:
6865 /*
6866 * The length is the specified length.
6867 */
6868 break;
6869
6870 default:
6871 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
))
6872 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
))
6873 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
))
6874 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
))
;
6875 break;
6876 }
6877 return item_length;
6878}
6879
6880// This was arbitrarily chosen, but if you're adding 50K items to the tree
6881// without advancing the offset you should probably take a long, hard look
6882// at what you're doing.
6883// We *could* make this a configurable option, but I (Gerald) would like to
6884// avoid adding yet another nerd knob.
6885# define PROTO_TREE_MAX_IDLE50000 50000
6886static field_info *
6887new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6888 const int start, const int item_length)
6889{
6890 field_info *fi;
6891
6892 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6893
6894 fi->hfinfo = hfinfo;
6895 fi->start = start;
6896 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6897 /* add the data source tvbuff */
6898 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6899
6900 // If our start offset hasn't advanced after adding many items it probably
6901 // means we're in a large or infinite loop.
6902 if (fi->start > 0) {
6903 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6904 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6905 DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6905, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6906 } else {
6907 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6908 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6909 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6910 }
6911 }
6912 fi->length = item_length;
6913 fi->tree_type = -1;
6914 fi->flags = 0;
6915 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6916 /* If the tree is not visible, set the item hidden, unless we
6917 * need the representation or length and can't fake them.
6918 */
6919 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6920 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6921 }
6922 }
6923 fi->value = fvalue_new(fi->hfinfo->type);
6924 fi->rep = NULL((void*)0);
6925
6926 fi->appendix_start = 0;
6927 fi->appendix_length = 0;
6928
6929 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6930 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6931
6932 return fi;
6933}
6934
6935static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6936{
6937 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6938 return 0;
6939 }
6940
6941 /* Search for field name */
6942 char *ptr = strstr(representation, hfinfo->name);
6943 if (!ptr) {
6944 return 0;
6945 }
6946
6947 /* Check if field name ends with the ": " delimiter */
6948 ptr += strlen(hfinfo->name);
6949 if (strncmp(ptr, ": ", 2) == 0) {
6950 ptr += 2;
6951 }
6952
6953 /* Return offset to after field name */
6954 return ptr - representation;
6955}
6956
6957static size_t label_find_name_pos(const item_label_t *rep)
6958{
6959 size_t name_pos = 0;
6960
6961 /* If the value_pos is too small or too large, we can't find the expected format */
6962 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6963 return 0;
6964 }
6965
6966 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6967 if (rep->representation[rep->value_pos-2] == ':') {
6968 name_pos = rep->value_pos - 2;
6969 }
6970
6971 return name_pos;
6972}
6973
6974/* If the protocol tree is to be visible, set the representation of a
6975 proto_tree entry with the name of the field for the item and with
6976 the value formatted with the supplied printf-style format and
6977 argument list. */
6978static void
6979proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6980{
6981 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6981, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6982
6983 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6984 * items string representation */
6985 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6986 size_t name_pos, ret = 0;
6987 char *str;
6988 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6989 const header_field_info *hf;
6990
6991 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6991, "fi"))))
;
6992
6993 hf = fi->hfinfo;
6994
6995 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;
;
6996 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))
)) {
6997 uint64_t val;
6998 char *p;
6999
7000 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)
)
7001 val = fvalue_get_uinteger(fi->value);
7002 else
7003 val = fvalue_get_uinteger64(fi->value);
7004
7005 val <<= hfinfo_bitshift(hf);
7006
7007 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7008 ret = (p - fi->rep->representation);
7009 }
7010
7011 /* put in the hf name */
7012 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
7013
7014 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
7015 /* If possible, Put in the value of the string */
7016 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7017 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"
, 7017, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7018 fi->rep->value_pos = ret;
7019 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
7020 if (ret >= ITEM_LABEL_LENGTH240) {
7021 /* Uh oh, we don't have enough room. Tell the user
7022 * that the field is truncated.
7023 */
7024 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7025 }
7026 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7027 }
7028}
7029
7030/* If the protocol tree is to be visible, set the representation of a
7031 proto_tree entry with the representation formatted with the supplied
7032 printf-style format and argument list. */
7033static void
7034proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7035{
7036 size_t ret; /*tmp return value */
7037 char *str;
7038 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7039
7040 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7040, "fi"))))
;
7041
7042 if (!proto_item_is_hidden(pi)) {
7043 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;
;
7044
7045 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7046 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"
, 7046, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7047 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7048 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7049 if (ret >= ITEM_LABEL_LENGTH240) {
7050 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7051 size_t name_pos = label_find_name_pos(fi->rep);
7052 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7053 }
7054 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7055 }
7056}
7057
7058static int
7059proto_strlcpy(char *dest, const char *src, size_t dest_size)
7060{
7061 if (dest_size == 0) return 0;
7062
7063 size_t res = g_strlcpy(dest, src, dest_size);
7064
7065 /* At most dest_size - 1 characters will be copied
7066 * (unless dest_size is 0). */
7067 if (res >= dest_size)
7068 res = dest_size - 1;
7069 return (int) res;
7070}
7071
7072static header_field_info *
7073hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7074{
7075 header_field_info *dup_hfinfo;
7076
7077 if (hfinfo->same_name_prev_id == -1)
7078 return NULL((void*)0);
7079 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", 7079
, __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", 7079, "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", 7079,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7080 return dup_hfinfo;
7081}
7082
7083static void
7084hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7085{
7086 g_free(last_field_name);
7087 last_field_name = NULL((void*)0);
7088
7089 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7090 /* No hfinfo with the same name */
7091 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7092 return;
7093 }
7094
7095 if (hfinfo->same_name_next) {
7096 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7097 }
7098
7099 if (hfinfo->same_name_prev_id != -1) {
7100 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7101 same_name_prev->same_name_next = hfinfo->same_name_next;
7102 if (!hfinfo->same_name_next) {
7103 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7104 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7105 }
7106 }
7107}
7108
7109int
7110proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7111{
7112 const header_field_info *hfinfo = finfo->hfinfo;
7113 int label_len = 0;
7114 char *tmp_str;
7115 const char *str;
7116 const uint8_t *bytes;
7117 uint32_t number;
7118 uint64_t number64;
7119 const char *hf_str_val;
7120 char number_buf[NUMBER_LABEL_LENGTH80];
7121 const char *number_out;
7122 address addr;
7123 const ipv4_addr_and_mask *ipv4;
7124 const ipv6_addr_and_prefix *ipv6;
7125
7126 switch (hfinfo->type) {
7127
7128 case FT_NONE:
7129 case FT_PROTOCOL:
7130 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7131
7132 case FT_UINT_BYTES:
7133 case FT_BYTES:
7134 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7135 hfinfo,
7136 fvalue_get_bytes_data(finfo->value),
7137 (unsigned)fvalue_length2(finfo->value),
7138 label_str_size);
7139 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7140 wmem_free(NULL((void*)0), tmp_str);
7141 break;
7142
7143 case FT_ABSOLUTE_TIME:
7144 {
7145 const nstime_t *value = fvalue_get_time(finfo->value);
7146 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7147 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7148 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7149 }
7150 if (hfinfo->strings) {
7151 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7152 if (time_string != NULL((void*)0)) {
7153 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7154 break;
7155 }
7156 }
7157 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7158 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7159 wmem_free(NULL((void*)0), tmp_str);
7160 break;
7161 }
7162
7163 case FT_RELATIVE_TIME:
7164 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7165 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7166 wmem_free(NULL((void*)0), tmp_str);
7167 break;
7168
7169 case FT_BOOLEAN:
7170 number64 = fvalue_get_uinteger64(finfo->value);
7171 label_len = proto_strlcpy(display_label_str,
7172 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7173 break;
7174
7175 case FT_CHAR:
7176 number = fvalue_get_uinteger(finfo->value);
7177
7178 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7179 char tmp[ITEM_LABEL_LENGTH240];
7180 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7181
7182 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7182, "fmtfunc"))))
;
7183 fmtfunc(tmp, number);
7184
7185 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7186
7187 } else if (hfinfo->strings) {
7188 number_out = hf_try_val_to_str(number, hfinfo);
7189
7190 if (!number_out) {
7191 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7192 }
7193
7194 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7195
7196 } else {
7197 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7198
7199 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7200 }
7201
7202 break;
7203
7204 /* XXX - make these just FT_NUMBER? */
7205 case FT_INT8:
7206 case FT_INT16:
7207 case FT_INT24:
7208 case FT_INT32:
7209 case FT_UINT8:
7210 case FT_UINT16:
7211 case FT_UINT24:
7212 case FT_UINT32:
7213 case FT_FRAMENUM:
7214 hf_str_val = NULL((void*)0);
7215 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
))
?
7216 (uint32_t) fvalue_get_sinteger(finfo->value) :
7217 fvalue_get_uinteger(finfo->value);
7218
7219 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7220 char tmp[ITEM_LABEL_LENGTH240];
7221 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7222
7223 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7223, "fmtfunc"))))
;
7224 fmtfunc(tmp, number);
7225
7226 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7227
7228 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7229 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7230 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7231 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7232 hf_str_val = hf_try_val_to_str(number, hfinfo);
7233 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7234 } else {
7235 number_out = hf_try_val_to_str(number, hfinfo);
7236
7237 if (!number_out) {
7238 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7239 }
7240
7241 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7242 }
7243 } else {
7244 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7245
7246 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7247 }
7248
7249 break;
7250
7251 case FT_INT40:
7252 case FT_INT48:
7253 case FT_INT56:
7254 case FT_INT64:
7255 case FT_UINT40:
7256 case FT_UINT48:
7257 case FT_UINT56:
7258 case FT_UINT64:
7259 hf_str_val = NULL((void*)0);
7260 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
))
?
7261 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7262 fvalue_get_uinteger64(finfo->value);
7263
7264 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7265 char tmp[ITEM_LABEL_LENGTH240];
7266 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7267
7268 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7268, "fmtfunc64"
))))
;
7269 fmtfunc64(tmp, number64);
7270
7271 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7272 } else if (hfinfo->strings) {
7273 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7274 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7275 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7276 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7277 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7278 } else {
7279 number_out = hf_try_val64_to_str(number64, hfinfo);
7280
7281 if (!number_out)
7282 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7283
7284 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7285 }
7286 } else {
7287 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7288
7289 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7290 }
7291
7292 break;
7293
7294 case FT_EUI64:
7295 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7296 tmp_str = address_to_display(NULL((void*)0), &addr);
7297 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7298 wmem_free(NULL((void*)0), tmp_str);
7299 break;
7300
7301 case FT_IPv4:
7302 ipv4 = fvalue_get_ipv4(finfo->value);
7303 //XXX: Should we ignore the mask?
7304 set_address_ipv4(&addr, ipv4);
7305 tmp_str = address_to_display(NULL((void*)0), &addr);
7306 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7307 wmem_free(NULL((void*)0), tmp_str);
7308 free_address(&addr);
7309 break;
7310
7311 case FT_IPv6:
7312 ipv6 = fvalue_get_ipv6(finfo->value);
7313 set_address_ipv6(&addr, ipv6);
7314 tmp_str = address_to_display(NULL((void*)0), &addr);
7315 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7316 wmem_free(NULL((void*)0), tmp_str);
7317 free_address(&addr);
7318 break;
7319
7320 case FT_FCWWN:
7321 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7322 tmp_str = address_to_display(NULL((void*)0), &addr);
7323 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7324 wmem_free(NULL((void*)0), tmp_str);
7325 break;
7326
7327 case FT_ETHER:
7328 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7329 tmp_str = address_to_display(NULL((void*)0), &addr);
7330 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7331 wmem_free(NULL((void*)0), tmp_str);
7332 break;
7333
7334 case FT_GUID:
7335 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7336 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7337 wmem_free(NULL((void*)0), tmp_str);
7338 break;
7339
7340 case FT_REL_OID:
7341 bytes = fvalue_get_bytes_data(finfo->value);
7342 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7343 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7344 wmem_free(NULL((void*)0), tmp_str);
7345 break;
7346
7347 case FT_OID:
7348 bytes = fvalue_get_bytes_data(finfo->value);
7349 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7350 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7351 wmem_free(NULL((void*)0), tmp_str);
7352 break;
7353
7354 case FT_SYSTEM_ID:
7355 bytes = fvalue_get_bytes_data(finfo->value);
7356 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7357 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7358 wmem_free(NULL((void*)0), tmp_str);
7359 break;
7360
7361 case FT_FLOAT:
7362 case FT_DOUBLE:
7363 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7364 break;
7365
7366 case FT_IEEE_11073_SFLOAT:
7367 case FT_IEEE_11073_FLOAT:
7368 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7369 break;
7370
7371 case FT_STRING:
7372 case FT_STRINGZ:
7373 case FT_UINT_STRING:
7374 case FT_STRINGZPAD:
7375 case FT_STRINGZTRUNC:
7376 str = fvalue_get_string(finfo->value);
7377 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7378 if (label_len >= label_str_size) {
7379 /* Truncation occurred. Get the real length
7380 * copied (not including '\0') */
7381 label_len = label_str_size ? label_str_size - 1 : 0;
7382 }
7383 break;
7384
7385 default:
7386 /* First try ftype string representation */
7387 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7388 if (!tmp_str) {
7389 /* Default to show as bytes */
7390 bytes = fvalue_get_bytes_data(finfo->value);
7391 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7392 }
7393 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7394 wmem_free(NULL((void*)0), tmp_str);
7395 break;
7396 }
7397 return label_len;
7398}
7399
7400const char *
7401proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7402 char *result, char *expr, const int size)
7403{
7404 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7405 GPtrArray *finfos;
7406 field_info *finfo = NULL((void*)0);
7407 header_field_info* hfinfo;
7408 const char *abbrev = NULL((void*)0);
7409
7410 char *str;
7411 col_custom_t *field_idx;
7412 int field_id;
7413 int ii = 0;
7414
7415 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7415, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7416 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7417 field_id = field_idx->field_id;
7418 if (field_id == 0) {
7419 GPtrArray *fvals = NULL((void*)0);
7420 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7421 if (fvals != NULL((void*)0)) {
7422
7423 // XXX - Handling occurrences is unusual when more
7424 // than one field is involved, e.g. there's four
7425 // results for tcp.port + tcp.port. We may really
7426 // want to apply it to the operands, not the output.
7427 // Note that occurrences are not quite the same as
7428 // the layer operator (should the grammar support
7429 // both?)
7430 /* Calculate single index or set outer boundaries */
7431 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7432 if (occurrence < 0) {
7433 i = occurrence + len;
7434 last = i;
7435 } else if (occurrence > 0) {
7436 i = occurrence - 1;
7437 last = i;
7438 } else {
7439 i = 0;
7440 last = len - 1;
7441 }
7442 if (i < 0 || i >= len) {
7443 g_ptr_array_unref(fvals);
7444 continue;
7445 }
7446 for (; i <= last; i++) {
7447 /* XXX - We could have a "resolved" result
7448 * for types where the value depends only
7449 * on the type, e.g. FT_IPv4, and not on
7450 * hfinfo->strings. Supporting the latter
7451 * requires knowing which hfinfo matched
7452 * if there are multiple with the same
7453 * abbreviation. In any case, we need to
7454 * know the expected return type of the
7455 * field expression.
7456 */
7457 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7458 if (offset_r && (offset_r < (size - 1)))
7459 result[offset_r++] = ',';
7460 if (offset_e && (offset_e < (size - 1)))
7461 expr[offset_e++] = ',';
7462 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7463 // col_{add,append,set}_* calls ws_label_strcpy
7464 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7465
7466 g_free(str);
7467 }
7468 g_ptr_array_unref(fvals);
7469 } else if (passed) {
7470 // XXX - Occurrence doesn't make sense for a test
7471 // output, it should be applied to the operands.
7472 if (offset_r && (offset_r < (size - 1)))
7473 result[offset_r++] = ',';
7474 if (offset_e && (offset_e < (size - 1)))
7475 expr[offset_e++] = ',';
7476 /* Prevent multiple check marks */
7477 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7478 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7479 } else {
7480 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7481 }
7482 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7483 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7484 } else {
7485 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7486 }
7487 }
7488 continue;
7489 }
7490 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", 7490
, __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", 7490,
"(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", 7490,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7491
7492 /* do we need to rewind ? */
7493 if (!hfinfo)
7494 return "";
7495
7496 if (occurrence < 0) {
7497 /* Search other direction */
7498 while (hfinfo->same_name_prev_id != -1) {
7499 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", 7499
, __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", 7499, "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", 7499,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7500 }
7501 }
7502
7503 prev_len = 0; /* Reset handled occurrences */
7504
7505 while (hfinfo) {
7506 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7507
7508 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7509 if (occurrence < 0) {
7510 hfinfo = hfinfo->same_name_next;
7511 } else {
7512 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7513 }
7514 continue;
7515 }
7516
7517 /* Are there enough occurrences of the field? */
7518 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7519 if (occurrence < 0) {
7520 hfinfo = hfinfo->same_name_next;
7521 } else {
7522 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7523 }
7524 prev_len += len;
7525 continue;
7526 }
7527
7528 /* Calculate single index or set outer boundaries */
7529 if (occurrence < 0) {
7530 i = occurrence + len + prev_len;
7531 last = i;
7532 } else if (occurrence > 0) {
7533 i = occurrence - 1 - prev_len;
7534 last = i;
7535 } else {
7536 i = 0;
7537 last = len - 1;
7538 }
7539
7540 prev_len += len; /* Count handled occurrences */
7541
7542 while (i <= last) {
7543 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7544
7545 if (offset_r && (offset_r < (size - 1)))
7546 result[offset_r++] = ',';
7547
7548 if (display_details) {
7549 char representation[ITEM_LABEL_LENGTH240];
7550 size_t offset = 0;
7551
7552 if (finfo->rep && finfo->rep->value_len) {
7553 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7554 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7555 } else {
7556 proto_item_fill_label(finfo, representation, &offset);
7557 }
7558 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7559 } else {
7560 switch (hfinfo->type) {
7561
7562 case FT_NONE:
7563 case FT_PROTOCOL:
7564 /* Prevent multiple check marks */
7565 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7566 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7567 } else {
7568 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7569 }
7570 break;
7571
7572 default:
7573 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7574 break;
7575 }
7576 }
7577
7578 if (offset_e && (offset_e < (size - 1)))
7579 expr[offset_e++] = ',';
7580
7581 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
))
)) {
7582 const char *hf_str_val;
7583 /* Integer types with BASE_NONE never get the numeric value. */
7584 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7585 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7586 } 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
)
) {
7587 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7588 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7589 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7590 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7591 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7592 }
7593 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7594 offset_e = (int)strlen(expr);
7595 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7596 /* Prevent multiple check marks */
7597 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7598 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7599 } else {
7600 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7601 }
7602 } else {
7603 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7604 // col_{add,append,set}_* calls ws_label_strcpy
7605 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7606 wmem_free(NULL((void*)0), str);
7607 }
7608 i++;
7609 }
7610
7611 /* XXX: Why is only the first abbreviation returned for a multifield
7612 * custom column? */
7613 if (!abbrev) {
7614 /* Store abbrev for return value */
7615 abbrev = hfinfo->abbrev;
7616 }
7617
7618 if (occurrence == 0) {
7619 /* Fetch next hfinfo with same name (abbrev) */
7620 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7621 } else {
7622 hfinfo = NULL((void*)0);
7623 }
7624 }
7625 }
7626
7627 if (offset_r >= (size - 1)) {
7628 mark_truncated(result, 0, size, NULL((void*)0));
7629 }
7630 if (offset_e >= (size - 1)) {
7631 mark_truncated(expr, 0, size, NULL((void*)0));
7632 }
7633 return abbrev ? abbrev : "";
7634}
7635
7636char *
7637proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7638{
7639 int len, prev_len, last, i;
7640 GPtrArray *finfos;
7641 field_info *finfo = NULL((void*)0);
7642 header_field_info* hfinfo;
7643
7644 char *filter = NULL((void*)0);
7645 GPtrArray *filter_array;
7646
7647 col_custom_t *col_custom;
7648 int field_id;
7649
7650 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7650, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7651 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7652 for (GSList *iter = field_ids; iter; iter = iter->next) {
7653 col_custom = (col_custom_t*)iter->data;
7654 field_id = col_custom->field_id;
7655 if (field_id == 0) {
7656 GPtrArray *fvals = NULL((void*)0);
7657 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7658 if (fvals != NULL((void*)0)) {
7659 // XXX - Handling occurrences is unusual when more
7660 // than one field is involved, e.g. there's four
7661 // results for tcp.port + tcp.port. We really
7662 // want to apply it to the operands, not the output.
7663 /* Calculate single index or set outer boundaries */
7664 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7665 if (occurrence < 0) {
7666 i = occurrence + len;
7667 last = i;
7668 } else if (occurrence > 0) {
7669 i = occurrence - 1;
7670 last = i;
7671 } else {
7672 i = 0;
7673 last = len - 1;
7674 }
7675 if (i < 0 || i >= len) {
7676 g_ptr_array_unref(fvals);
7677 continue;
7678 }
7679 for (; i <= last; i++) {
7680 /* XXX - Should multiple values for one
7681 * field use set membership to reduce
7682 * verbosity, here and below? */
7683 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7684 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7685 wmem_free(NULL((void*)0), str);
7686 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7687 g_ptr_array_add(filter_array, filter);
7688 }
7689 }
7690 g_ptr_array_unref(fvals);
7691 } else if (passed) {
7692 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7693 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7694 g_ptr_array_add(filter_array, filter);
7695 }
7696 } else {
7697 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7698 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7699 g_ptr_array_add(filter_array, filter);
7700 }
7701 }
7702 continue;
7703 }
7704
7705 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", 7705
, __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", 7705,
"(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", 7705,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7706
7707 /* do we need to rewind ? */
7708 if (!hfinfo)
7709 return NULL((void*)0);
7710
7711 if (occurrence < 0) {
7712 /* Search other direction */
7713 while (hfinfo->same_name_prev_id != -1) {
7714 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", 7714
, __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", 7714, "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", 7714,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7715 }
7716 }
7717
7718 prev_len = 0; /* Reset handled occurrences */
7719
7720 while (hfinfo) {
7721 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7722
7723 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7724 if (occurrence < 0) {
7725 hfinfo = hfinfo->same_name_next;
7726 } else {
7727 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7728 }
7729 continue;
7730 }
7731
7732 /* Are there enough occurrences of the field? */
7733 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7734 if (occurrence < 0) {
7735 hfinfo = hfinfo->same_name_next;
7736 } else {
7737 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7738 }
7739 prev_len += len;
7740 continue;
7741 }
7742
7743 /* Calculate single index or set outer boundaries */
7744 if (occurrence < 0) {
7745 i = occurrence + len + prev_len;
7746 last = i;
7747 } else if (occurrence > 0) {
7748 i = occurrence - 1 - prev_len;
7749 last = i;
7750 } else {
7751 i = 0;
7752 last = len - 1;
7753 }
7754
7755 prev_len += len; /* Count handled occurrences */
7756
7757 while (i <= last) {
7758 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7759
7760 filter = proto_construct_match_selected_string(finfo, edt);
7761 if (filter) {
7762 /* Only add the same expression once (especially for FT_PROTOCOL).
7763 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7764 */
7765 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7766 g_ptr_array_add(filter_array, filter);
7767 }
7768 }
7769 i++;
7770 }
7771
7772 if (occurrence == 0) {
7773 /* Fetch next hfinfo with same name (abbrev) */
7774 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7775 } else {
7776 hfinfo = NULL((void*)0);
7777 }
7778 }
7779 }
7780
7781 g_ptr_array_add(filter_array, NULL((void*)0));
7782
7783 /* XXX: Should this be || or && ? */
7784 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7785
7786 g_ptr_array_free(filter_array, true1);
7787
7788 return output;
7789}
7790
7791/* Set text of proto_item after having already been created. */
7792void
7793proto_item_set_text(proto_item *pi, const char *format, ...)
7794{
7795 field_info *fi = NULL((void*)0);
7796 va_list ap;
7797
7798 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7799
7800 fi = PITEM_FINFO(pi)((pi)->finfo);
7801 if (fi == NULL((void*)0))
7802 return;
7803
7804 if (fi->rep) {
7805 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7806 fi->rep = NULL((void*)0);
7807 }
7808
7809 va_start(ap, format)__builtin_va_start(ap, format);
7810 proto_tree_set_representation(pi, format, ap);
7811 va_end(ap)__builtin_va_end(ap);
7812}
7813
7814/* Append to text of proto_item after having already been created. */
7815void
7816proto_item_append_text(proto_item *pi, const char *format, ...)
7817{
7818 field_info *fi = NULL((void*)0);
7819 size_t curlen;
7820 char *str;
7821 va_list ap;
7822
7823 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7824
7825 fi = PITEM_FINFO(pi)((pi)->finfo);
7826 if (fi == NULL((void*)0)) {
7827 return;
7828 }
7829
7830 if (!proto_item_is_hidden(pi)) {
7831 /*
7832 * If we don't already have a representation,
7833 * generate the default representation.
7834 */
7835 if (fi->rep == NULL((void*)0)) {
7836 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;
;
7837 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7838 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7839 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7840 (strncmp(format, ": ", 2) == 0)) {
7841 fi->rep->value_pos += 2;
7842 }
7843 }
7844 if (fi->rep) {
7845 curlen = strlen(fi->rep->representation);
7846 /* curlen doesn't include the \0 byte.
7847 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7848 * the representation has already been truncated (of an up
7849 * to 4 byte UTF-8 character) or is just at the maximum length
7850 * unless we search for " [truncated]" (which may not be
7851 * at the start.)
7852 * It's safer to do nothing.
7853 */
7854 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7855 va_start(ap, format)__builtin_va_start(ap, format);
7856 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7857 va_end(ap)__builtin_va_end(ap);
7858 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"
, 7858, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7859 /* Keep fi->rep->value_pos */
7860 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7861 if (curlen >= ITEM_LABEL_LENGTH240) {
7862 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7863 size_t name_pos = label_find_name_pos(fi->rep);
7864 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7865 }
7866 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7867 }
7868 }
7869 }
7870}
7871
7872/* Prepend to text of proto_item after having already been created. */
7873void
7874proto_item_prepend_text(proto_item *pi, const char *format, ...)
7875{
7876 field_info *fi = NULL((void*)0);
7877 size_t pos;
7878 char representation[ITEM_LABEL_LENGTH240];
7879 char *str;
7880 va_list ap;
7881
7882 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7883
7884 fi = PITEM_FINFO(pi)((pi)->finfo);
7885 if (fi == NULL((void*)0)) {
7886 return;
7887 }
7888
7889 if (!proto_item_is_hidden(pi)) {
7890 /*
7891 * If we don't already have a representation,
7892 * generate the default representation.
7893 */
7894 if (fi->rep == NULL((void*)0)) {
7895 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;
;
7896 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7897 } else
7898 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7899
7900 va_start(ap, format)__builtin_va_start(ap, format);
7901 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7902 va_end(ap)__builtin_va_end(ap);
7903 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"
, 7903, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7904 fi->rep->value_pos += strlen(str);
7905 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7906 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7907 /* XXX: As above, if the old representation is close to the label
7908 * length, it might already be marked as truncated. */
7909 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7910 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7911 size_t name_pos = label_find_name_pos(fi->rep);
7912 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7913 }
7914 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7915 }
7916}
7917
7918static void
7919finfo_set_len(field_info *fi, const int length)
7920{
7921 int length_remaining;
7922
7923 DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7923,
"length >= 0", fi->hfinfo->abbrev))))
;
7924 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7925 if (length > length_remaining)
7926 fi->length = length_remaining;
7927 else
7928 fi->length = length;
7929
7930 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7931 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7932 fvalue_set_protocol_length(fi->value, fi->length);
7933 }
7934
7935 /*
7936 * You cannot just make the "len" field of a GByteArray
7937 * larger, if there's no data to back that length;
7938 * you can only make it smaller.
7939 */
7940 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7941 GBytes *bytes = fvalue_get_bytes(fi->value);
7942 size_t size;
7943 const void *data = g_bytes_get_data(bytes, &size);
7944 if ((size_t)fi->length <= size) {
7945 fvalue_set_bytes_data(fi->value, data, fi->length);
7946 }
7947 g_bytes_unref(bytes);
7948 }
7949}
7950
7951void
7952proto_item_set_len(proto_item *pi, const int length)
7953{
7954 field_info *fi;
7955
7956 if (pi == NULL((void*)0))
7957 return;
7958
7959 fi = PITEM_FINFO(pi)((pi)->finfo);
7960 if (fi == NULL((void*)0))
7961 return;
7962
7963 finfo_set_len(fi, length);
7964}
7965
7966/*
7967 * Sets the length of the item based on its start and on the specified
7968 * offset, which is the offset past the end of the item; as the start
7969 * in the item is relative to the beginning of the data source tvbuff,
7970 * we need to pass in a tvbuff - the end offset is relative to the beginning
7971 * of that tvbuff.
7972 */
7973void
7974proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7975{
7976 field_info *fi;
7977 int length;
7978
7979 if (pi == NULL((void*)0))
7980 return;
7981
7982 fi = PITEM_FINFO(pi)((pi)->finfo);
7983 if (fi == NULL((void*)0))
7984 return;
7985
7986 end += tvb_raw_offset(tvb);
7987 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7987, "end >= fi->start"
))))
;
7988 length = end - fi->start;
7989
7990 finfo_set_len(fi, length);
7991}
7992
7993int
7994proto_item_get_len(const proto_item *pi)
7995{
7996 field_info *fi;
7997
7998 if (!pi)
7999 return -1;
8000 fi = PITEM_FINFO(pi)((pi)->finfo);
8001 return fi ? fi->length : -1;
8002}
8003
8004void
8005proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8006 if (!ti) {
8007 return;
8008 }
8009 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)
;
8010 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)
;
8011}
8012
8013char *
8014proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8015{
8016 field_info *fi;
8017
8018 if (!pi)
8019 return wmem_strdup(scope, "");
8020 fi = PITEM_FINFO(pi)((pi)->finfo);
8021 if (!fi)
8022 return wmem_strdup(scope, "");
8023 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8023, "fi->hfinfo != ((void*)0)"
))))
;
8024 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8025}
8026
8027proto_tree *
8028proto_tree_create_root(packet_info *pinfo)
8029{
8030 proto_node *pnode;
8031
8032 /* Initialize the proto_node */
8033 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8034 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8035 pnode->parent = NULL((void*)0);
8036 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8037 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8038
8039 /* Make sure we can access pinfo everywhere */
8040 pnode->tree_data->pinfo = pinfo;
8041
8042 /* Don't initialize the tree_data_t. Wait until we know we need it */
8043 pnode->tree_data->interesting_hfids = NULL((void*)0);
8044
8045 /* Set the default to false so it's easier to
8046 * find errors; if we expect to see the protocol tree
8047 * but for some reason the default 'visible' is not
8048 * changed, then we'll find out very quickly. */
8049 pnode->tree_data->visible = false0;
8050
8051 /* Make sure that we fake protocols (if possible) */
8052 pnode->tree_data->fake_protocols = true1;
8053
8054 /* Keep track of the number of children */
8055 pnode->tree_data->count = 0;
8056
8057 /* Initialize our loop checks */
8058 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8059 pnode->tree_data->max_start = 0;
8060 pnode->tree_data->start_idle_count = 0;
8061
8062 return (proto_tree *)pnode;
8063}
8064
8065
8066/* "prime" a proto_tree with a single hfid that a dfilter
8067 * is interested in. */
8068void
8069proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8070{
8071 header_field_info *hfinfo;
8072
8073 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", 8073, __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", 8073, "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", 8073, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8074 /* this field is referenced by a filter so increase the refcount.
8075 also increase the refcount for the parent, i.e the protocol.
8076 Don't increase the refcount if we're already printing the
8077 type, as that is a superset of direct reference.
8078 */
8079 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8080 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8081 }
8082 /* only increase the refcount if there is a parent.
8083 if this is a protocol and not a field then parent will be -1
8084 and there is no parent to add any refcounting for.
8085 */
8086 if (hfinfo->parent != -1) {
8087 header_field_info *parent_hfinfo;
8088 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", 8088
, __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", 8088,
"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", 8088,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8089
8090 /* Mark parent as indirectly referenced unless it is already directly
8091 * referenced, i.e. the user has specified the parent in a filter.
8092 */
8093 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8094 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8095 }
8096}
8097
8098/* "prime" a proto_tree with a single hfid that a dfilter
8099 * is interested in. */
8100void
8101proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8102{
8103 header_field_info *hfinfo;
8104
8105 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", 8105, __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", 8105, "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", 8105, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8106 /* this field is referenced by an (output) filter so increase the refcount.
8107 also increase the refcount for the parent, i.e the protocol.
8108 */
8109 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8110 /* only increase the refcount if there is a parent.
8111 if this is a protocol and not a field then parent will be -1
8112 and there is no parent to add any refcounting for.
8113 */
8114 if (hfinfo->parent != -1) {
8115 header_field_info *parent_hfinfo;
8116 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", 8116
, __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", 8116,
"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", 8116,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8117
8118 /* Mark parent as indirectly referenced unless it is already directly
8119 * referenced, i.e. the user has specified the parent in a filter.
8120 */
8121 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8122 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8123 }
8124}
8125
8126proto_tree *
8127proto_item_add_subtree(proto_item *pi, const int idx) {
8128 field_info *fi;
8129
8130 if (!pi)
8131 return NULL((void*)0);
8132
8133 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", 8133, "idx >= 0 && idx < num_tree_types"
))))
;
8134
8135 fi = PITEM_FINFO(pi)((pi)->finfo);
8136 if (!fi)
8137 return (proto_tree *)pi;
8138
8139 fi->tree_type = idx;
8140
8141 return (proto_tree *)pi;
8142}
8143
8144proto_tree *
8145proto_item_get_subtree(proto_item *pi) {
8146 field_info *fi;
8147
8148 if (!pi)
8149 return NULL((void*)0);
8150 fi = PITEM_FINFO(pi)((pi)->finfo);
8151 if ( (fi) && (fi->tree_type == -1) )
8152 return NULL((void*)0);
8153 return (proto_tree *)pi;
8154}
8155
8156proto_item *
8157proto_item_get_parent(const proto_item *ti) {
8158 if (!ti)
8159 return NULL((void*)0);
8160 return ti->parent;
8161}
8162
8163proto_item *
8164proto_item_get_parent_nth(proto_item *ti, int gen) {
8165 if (!ti)
8166 return NULL((void*)0);
8167 while (gen--) {
8168 ti = ti->parent;
8169 if (!ti)
8170 return NULL((void*)0);
8171 }
8172 return ti;
8173}
8174
8175
8176proto_item *
8177proto_tree_get_parent(proto_tree *tree) {
8178 if (!tree)
8179 return NULL((void*)0);
8180 return (proto_item *)tree;
8181}
8182
8183proto_tree *
8184proto_tree_get_parent_tree(proto_tree *tree) {
8185 if (!tree)
8186 return NULL((void*)0);
8187
8188 /* we're the root tree, there's no parent
8189 return ourselves so the caller has at least a tree to attach to */
8190 if (!tree->parent)
8191 return tree;
8192
8193 return (proto_tree *)tree->parent;
8194}
8195
8196proto_tree *
8197proto_tree_get_root(proto_tree *tree) {
8198 if (!tree)
8199 return NULL((void*)0);
8200 while (tree->parent) {
8201 tree = tree->parent;
8202 }
8203 return tree;
8204}
8205
8206void
8207proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8208 proto_item *item_to_move)
8209{
8210 /* This function doesn't generate any values. It only reorganizes the protocol tree
8211 * so we can bail out immediately if it isn't visible. */
8212 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8213 return;
8214
8215 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", 8215, "item_to_move->parent == tree"
))))
;
8216 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", 8216, "fixed_item->parent == tree"
))))
;
8217
8218 /*** cut item_to_move out ***/
8219
8220 /* is item_to_move the first? */
8221 if (tree->first_child == item_to_move) {
8222 /* simply change first child to next */
8223 tree->first_child = item_to_move->next;
8224
8225 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", 8225, "tree->last_child != item_to_move"
))))
;
8226 } else {
8227 proto_item *curr_item;
8228 /* find previous and change it's next */
8229 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8230 if (curr_item->next == item_to_move) {
8231 break;
8232 }
8233 }
8234
8235 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8235, "curr_item"
))))
;
8236
8237 curr_item->next = item_to_move->next;
8238
8239 /* fix last_child if required */
8240 if (tree->last_child == item_to_move) {
8241 tree->last_child = curr_item;
8242 }
8243 }
8244
8245 /*** insert to_move after fixed ***/
8246 item_to_move->next = fixed_item->next;
8247 fixed_item->next = item_to_move;
8248 if (tree->last_child == fixed_item) {
8249 tree->last_child = item_to_move;
8250 }
8251}
8252
8253void
8254proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8255 const int length)
8256{
8257 field_info *fi;
8258
8259 if (tree == NULL((void*)0))
8260 return;
8261
8262 fi = PTREE_FINFO(tree)((tree)->finfo);
8263 if (fi == NULL((void*)0))
8264 return;
8265
8266 start += tvb_raw_offset(tvb);
8267 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8267, "start >= 0"
))))
;
8268 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8268, "length >= 0"
))))
;
8269
8270 fi->appendix_start = start;
8271 fi->appendix_length = length;
8272}
8273
8274static void
8275check_protocol_filter_name_or_fail(const char *filter_name)
8276{
8277 /* Require at least two characters. */
8278 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8279 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)
;
8280 }
8281
8282 if (proto_check_field_name(filter_name) != '\0') {
8283 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)
8284 " 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)
8285 " 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)
;
8286 }
8287
8288 /* Check that it doesn't match some very common numeric forms. */
8289 if (filter_name[0] == '0' &&
8290 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8291 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8292 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])
8293 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])
;
8294 }
8295
8296 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8297
8298 /* Check that it contains at least one letter. */
8299 bool_Bool have_letter = false0;
8300 for (const char *s = filter_name; *s != '\0'; s++) {
8301 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8302 have_letter = true1;
8303 break;
8304 }
8305 }
8306 if (!have_letter) {
8307 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)
8308 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8309 }
8310
8311 /* Check for reserved keywords. */
8312 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8313 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)
8314 " 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)
;
8315 }
8316}
8317
8318int
8319proto_register_protocol(const char *name, const char *short_name,
8320 const char *filter_name)
8321{
8322 protocol_t *protocol;
8323 header_field_info *hfinfo;
8324
8325 check_protocol_filter_name_or_fail(filter_name);
8326
8327 /*
8328 * Add this protocol to the list of known protocols;
8329 * the list is sorted by protocol short name.
8330 */
8331 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8332 protocol->name = name;
8333 protocol->short_name = short_name;
8334 protocol->filter_name = filter_name;
8335 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8336 protocol->is_enabled = true1; /* protocol is enabled by default */
8337 protocol->enabled_by_default = true1; /* see previous comment */
8338 protocol->can_toggle = true1;
8339 protocol->parent_proto_id = -1;
8340 protocol->heur_list = NULL((void*)0);
8341
8342 /* List will be sorted later by name, when all protocols completed registering */
8343 protocols = g_list_prepend(protocols, protocol);
8344 /*
8345 * Make sure there's not already a protocol with any of those
8346 * names. Crash if there is, as that's an error in the code
8347 * or an inappropriate plugin.
8348 * This situation has to be fixed to not register more than one
8349 * protocol with the same name.
8350 */
8351 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8352 /* ws_error will terminate the program */
8353 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)
8354 " 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)
;
8355 }
8356 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8357 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)
8358 " 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)
;
8359 }
8360 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8361 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)
8362 " 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)
;
8363 }
8364
8365 /* Here we allocate a new header_field_info struct */
8366 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8367 hfinfo->name = name;
8368 hfinfo->abbrev = filter_name;
8369 hfinfo->type = FT_PROTOCOL;
8370 hfinfo->display = BASE_NONE;
8371 hfinfo->strings = protocol;
8372 hfinfo->bitmask = 0;
8373 hfinfo->ref_type = HF_REF_TYPE_NONE;
8374 hfinfo->blurb = NULL((void*)0);
8375 hfinfo->parent = -1; /* This field differentiates protos and fields */
8376
8377 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8378 return protocol->proto_id;
8379}
8380
8381int
8382proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8383{
8384 protocol_t *protocol;
8385 header_field_info *hfinfo;
8386
8387 /*
8388 * Helper protocols don't need the strict rules as a "regular" protocol
8389 * Just register it in a list and make a hf_ field from it
8390 */
8391 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8392 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)
;
8393 }
8394
8395 if (parent_proto <= 0) {
8396 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)
8397 " 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)
;
8398 }
8399
8400 check_protocol_filter_name_or_fail(filter_name);
8401
8402 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8403 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8404 protocol->name = name;
8405 protocol->short_name = short_name;
8406 protocol->filter_name = filter_name;
8407 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8408
8409 /* Enabling and toggling is really determined by parent protocol,
8410 but provide default values here */
8411 protocol->is_enabled = true1;
8412 protocol->enabled_by_default = true1;
8413 protocol->can_toggle = true1;
8414
8415 protocol->parent_proto_id = parent_proto;
8416 protocol->heur_list = NULL((void*)0);
8417
8418 /* List will be sorted later by name, when all protocols completed registering */
8419 protocols = g_list_prepend(protocols, protocol);
8420
8421 /* Here we allocate a new header_field_info struct */
8422 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8423 hfinfo->name = name;
8424 hfinfo->abbrev = filter_name;
8425 hfinfo->type = field_type;
8426 hfinfo->display = BASE_NONE;
8427 if (field_type == FT_BYTES) {
8428 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8429 }
8430 hfinfo->strings = protocol;
8431 hfinfo->bitmask = 0;
8432 hfinfo->ref_type = HF_REF_TYPE_NONE;
8433 hfinfo->blurb = NULL((void*)0);
8434 hfinfo->parent = -1; /* This field differentiates protos and fields */
8435
8436 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8437 return protocol->proto_id;
8438}
8439
8440bool_Bool
8441proto_deregister_protocol(const char *short_name)
8442{
8443 protocol_t *protocol;
8444 header_field_info *hfinfo;
8445 int proto_id;
8446 unsigned i;
8447
8448 proto_id = proto_get_id_by_short_name(short_name);
8449 protocol = find_protocol_by_id(proto_id);
8450 if (protocol == NULL((void*)0))
8451 return false0;
8452
8453 g_hash_table_remove(proto_names, protocol->name);
8454 g_hash_table_remove(proto_short_names, (void *)short_name);
8455 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8456
8457 if (protocol->fields) {
8458 for (i = 0; i < protocol->fields->len; i++) {
8459 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8460 hfinfo_remove_from_gpa_name_map(hfinfo);
8461 expert_deregister_expertinfo(hfinfo->abbrev);
8462 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8463 }
8464 g_ptr_array_free(protocol->fields, true1);
8465 protocol->fields = NULL((void*)0);
8466 }
8467
8468 g_list_free(protocol->heur_list);
8469
8470 /* Remove this protocol from the list of known protocols */
8471 protocols = g_list_remove(protocols, protocol);
8472
8473 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8474 wmem_map_remove(gpa_name_map, protocol->filter_name);
8475
8476 g_free(last_field_name);
8477 last_field_name = NULL((void*)0);
8478
8479 return true1;
8480}
8481
8482void
8483proto_register_alias(const int proto_id, const char *alias_name)
8484{
8485 protocol_t *protocol;
8486
8487 protocol = find_protocol_by_id(proto_id);
8488 if (alias_name && protocol) {
8489 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8490 }
8491}
8492
8493/*
8494 * Routines to use to iterate over the protocols.
8495 * The argument passed to the iterator routines is an opaque cookie to
8496 * their callers; it's the GList pointer for the current element in
8497 * the list.
8498 * The ID of the protocol is returned, or -1 if there is no protocol.
8499 */
8500int
8501proto_get_first_protocol(void **cookie)
8502{
8503 protocol_t *protocol;
8504
8505 if (protocols == NULL((void*)0))
8506 return -1;
8507 *cookie = protocols;
8508 protocol = (protocol_t *)protocols->data;
8509 return protocol->proto_id;
8510}
8511
8512int
8513proto_get_data_protocol(void *cookie)
8514{
8515 GList *list_item = (GList *)cookie;
8516
8517 protocol_t *protocol = (protocol_t *)list_item->data;
8518 return protocol->proto_id;
8519}
8520
8521int
8522proto_get_next_protocol(void **cookie)
8523{
8524 GList *list_item = (GList *)*cookie;
8525 protocol_t *protocol;
8526
8527 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8528 if (list_item == NULL((void*)0))
8529 return -1;
8530 *cookie = list_item;
8531 protocol = (protocol_t *)list_item->data;
8532 return protocol->proto_id;
8533}
8534
8535header_field_info *
8536proto_get_first_protocol_field(const int proto_id, void **cookie)
8537{
8538 protocol_t *protocol = find_protocol_by_id(proto_id);
8539
8540 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8541 return NULL((void*)0);
8542
8543 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8544 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8545}
8546
8547header_field_info *
8548proto_get_next_protocol_field(const int proto_id, void **cookie)
8549{
8550 protocol_t *protocol = find_protocol_by_id(proto_id);
8551 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8552
8553 i++;
8554
8555 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8556 return NULL((void*)0);
8557
8558 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8559 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8560}
8561
8562protocol_t *
8563find_protocol_by_id(const int proto_id)
8564{
8565 header_field_info *hfinfo;
8566
8567 if (proto_id <= 0)
8568 return NULL((void*)0);
8569
8570 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", 8570, __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", 8570,
"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", 8570, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8571 if (hfinfo->type != FT_PROTOCOL) {
8572 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", 8572, "hfinfo->display & 0x00004000"
))))
;
8573 }
8574 return (protocol_t *)hfinfo->strings;
8575}
8576
8577int
8578proto_get_id(const protocol_t *protocol)
8579{
8580 return protocol->proto_id;
8581}
8582
8583bool_Bool
8584proto_name_already_registered(const char *name)
8585{
8586 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8586, "name", "No name present"))))
;
8587
8588 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8589 return true1;
8590 return false0;
8591}
8592
8593int
8594proto_get_id_by_filter_name(const char *filter_name)
8595{
8596 const protocol_t *protocol = NULL((void*)0);
8597
8598 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", 8598,
"filter_name", "No filter name present"))))
;
8599
8600 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8601
8602 if (protocol == NULL((void*)0))
8603 return -1;
8604 return protocol->proto_id;
8605}
8606
8607int
8608proto_get_id_by_short_name(const char *short_name)
8609{
8610 const protocol_t *protocol = NULL((void*)0);
8611
8612 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", 8612,
"short_name", "No short name present"))))
;
8613
8614 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8615
8616 if (protocol == NULL((void*)0))
8617 return -1;
8618 return protocol->proto_id;
8619}
8620
8621const char *
8622proto_get_protocol_name(const int proto_id)
8623{
8624 protocol_t *protocol;
8625
8626 protocol = find_protocol_by_id(proto_id);
8627
8628 if (protocol == NULL((void*)0))
8629 return NULL((void*)0);
8630 return protocol->name;
8631}
8632
8633const char *
8634proto_get_protocol_short_name(const protocol_t *protocol)
8635{
8636 if (protocol == NULL((void*)0))
8637 return "(none)";
8638 return protocol->short_name;
8639}
8640
8641const char *
8642proto_get_protocol_long_name(const protocol_t *protocol)
8643{
8644 if (protocol == NULL((void*)0))
8645 return "(none)";
8646 return protocol->name;
8647}
8648
8649const char *
8650proto_get_protocol_filter_name(const int proto_id)
8651{
8652 protocol_t *protocol;
8653
8654 protocol = find_protocol_by_id(proto_id);
8655 if (protocol == NULL((void*)0))
8656 return "(none)";
8657 return protocol->filter_name;
8658}
8659
8660void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8661{
8662 heur_dtbl_entry_t* heuristic_dissector;
8663
8664 if (protocol == NULL((void*)0))
8665 return;
8666
8667 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8668 if (heuristic_dissector != NULL((void*)0))
8669 {
8670 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8671 }
8672}
8673
8674void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8675{
8676 if (protocol == NULL((void*)0))
8677 return;
8678
8679 g_list_foreach(protocol->heur_list, func, user_data);
8680}
8681
8682void
8683proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8684 bool_Bool *is_tcp, bool_Bool *is_udp,
8685 bool_Bool *is_sctp, bool_Bool *is_tls,
8686 bool_Bool *is_rtp,
8687 bool_Bool *is_lte_rlc)
8688{
8689 wmem_list_frame_t *protos = wmem_list_head(layers);
8690 int proto_id;
8691 const char *proto_name;
8692
8693 /* Walk the list of a available protocols in the packet and
8694 attempt to find "major" ones. */
8695 /* It might make more sense to assemble and return a bitfield. */
8696 while (protos != NULL((void*)0))
8697 {
8698 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8699 proto_name = proto_get_protocol_filter_name(proto_id);
8700
8701 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8702 (!strcmp(proto_name, "ipv6")))) {
8703 *is_ip = true1;
8704 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8705 *is_tcp = true1;
8706 } else if (is_udp && !strcmp(proto_name, "udp")) {
8707 *is_udp = true1;
8708 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8709 *is_sctp = true1;
8710 } else if (is_tls && !strcmp(proto_name, "tls")) {
8711 *is_tls = true1;
8712 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8713 *is_rtp = true1;
8714 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8715 *is_lte_rlc = true1;
8716 }
8717
8718 protos = wmem_list_frame_next(protos);
8719 }
8720}
8721
8722bool_Bool
8723proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8724{
8725 wmem_list_frame_t *protos = wmem_list_head(layers);
8726 int proto_id;
8727 const char *name;
8728
8729 /* Walk the list of a available protocols in the packet and
8730 attempt to find the specified protocol. */
8731 while (protos != NULL((void*)0))
8732 {
8733 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8734 name = proto_get_protocol_filter_name(proto_id);
8735
8736 if (!strcmp(name, proto_name))
8737 {
8738 return true1;
8739 }
8740
8741 protos = wmem_list_frame_next(protos);
8742 }
8743
8744 return false0;
8745}
8746
8747char *
8748proto_list_layers(const packet_info *pinfo)
8749{
8750 wmem_strbuf_t *buf;
8751 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8752
8753 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8754
8755 /* Walk the list of layers in the packet and
8756 return a string of all entries. */
8757 while (layers != NULL((void*)0))
8758 {
8759 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8760
8761 layers = wmem_list_frame_next(layers);
8762 if (layers != NULL((void*)0)) {
8763 wmem_strbuf_append_c(buf, ':');
8764 }
8765 }
8766
8767 return wmem_strbuf_finalize(buf);
8768}
8769
8770uint8_t
8771proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8772{
8773 int *proto_layer_num_ptr;
8774
8775 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8776 if (proto_layer_num_ptr == NULL((void*)0)) {
8777 return 0;
8778 }
8779
8780 return (uint8_t)*proto_layer_num_ptr;
8781}
8782
8783bool_Bool
8784proto_is_pino(const protocol_t *protocol)
8785{
8786 return (protocol->parent_proto_id != -1);
8787}
8788
8789bool_Bool
8790// NOLINTNEXTLINE(misc-no-recursion)
8791proto_is_protocol_enabled(const protocol_t *protocol)
8792{
8793 if (protocol == NULL((void*)0))
8794 return false0;
8795
8796 //parent protocol determines enable/disable for helper dissectors
8797 if (proto_is_pino(protocol))
8798 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8799
8800 return protocol->is_enabled;
8801}
8802
8803bool_Bool
8804// NOLINTNEXTLINE(misc-no-recursion)
8805proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8806{
8807 //parent protocol determines enable/disable for helper dissectors
8808 if (proto_is_pino(protocol))
8809 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8810
8811 return protocol->enabled_by_default;
8812}
8813
8814bool_Bool
8815// NOLINTNEXTLINE(misc-no-recursion)
8816proto_can_toggle_protocol(const int proto_id)
8817{
8818 protocol_t *protocol;
8819
8820 protocol = find_protocol_by_id(proto_id);
8821 //parent protocol determines toggling for helper dissectors
8822 if (proto_is_pino(protocol))
8823 return proto_can_toggle_protocol(protocol->parent_proto_id);
8824
8825 return protocol->can_toggle;
8826}
8827
8828void
8829proto_disable_by_default(const int proto_id)
8830{
8831 protocol_t *protocol;
8832
8833 protocol = find_protocol_by_id(proto_id);
8834 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8834, "protocol->can_toggle"
))))
;
8835 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", 8835, "proto_is_pino(protocol) == 0"
))))
;
8836 protocol->is_enabled = false0;
8837 protocol->enabled_by_default = false0;
8838}
8839
8840void
8841proto_set_decoding(const int proto_id, const bool_Bool enabled)
8842{
8843 protocol_t *protocol;
8844
8845 protocol = find_protocol_by_id(proto_id);
8846 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8846, "protocol->can_toggle"
))))
;
8847 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", 8847, "proto_is_pino(protocol) == 0"
))))
;
8848 protocol->is_enabled = enabled;
8849}
8850
8851void
8852proto_disable_all(void)
8853{
8854 /* This doesn't explicitly disable heuristic protocols,
8855 * but the heuristic doesn't get called if the parent
8856 * protocol isn't enabled.
8857 */
8858 protocol_t *protocol;
8859 GList *list_item = protocols;
8860
8861 if (protocols == NULL((void*)0))
8862 return;
8863
8864 while (list_item) {
8865 protocol = (protocol_t *)list_item->data;
8866 if (protocol->can_toggle) {
8867 protocol->is_enabled = false0;
8868 }
8869 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8870 }
8871}
8872
8873static void
8874heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8875{
8876 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8877
8878 heur->enabled = heur->enabled_by_default;
8879}
8880
8881void
8882proto_reenable_all(void)
8883{
8884 protocol_t *protocol;
8885 GList *list_item = protocols;
8886
8887 if (protocols == NULL((void*)0))
8888 return;
8889
8890 while (list_item) {
8891 protocol = (protocol_t *)list_item->data;
8892 if (protocol->can_toggle)
8893 protocol->is_enabled = protocol->enabled_by_default;
8894 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8895 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8896 }
8897}
8898
8899void
8900proto_set_cant_toggle(const int proto_id)
8901{
8902 protocol_t *protocol;
8903
8904 protocol = find_protocol_by_id(proto_id);
8905 protocol->can_toggle = false0;
8906}
8907
8908static int
8909proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8910{
8911 g_ptr_array_add(proto->fields, hfi);
8912
8913 return proto_register_field_init(hfi, parent);
8914}
8915
8916/* for use with static arrays only, since we don't allocate our own copies
8917of the header_field_info struct contained within the hf_register_info struct */
8918void
8919proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8920{
8921 hf_register_info *ptr = hf;
8922 protocol_t *proto;
8923 int i;
8924
8925 proto = find_protocol_by_id(parent);
8926
8927 /* if (proto == NULL) - error or return? */
8928
8929 if (proto->fields == NULL((void*)0)) {
8930 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8931 * GLib introduced g_ptr_array_new_from_array, which might have
8932 * given a reason to actually use it. (#17774)
8933 */
8934 proto->fields = g_ptr_array_sized_new(num_records);
8935 }
8936
8937 for (i = 0; i < num_records; i++, ptr++) {
8938 /*
8939 * Make sure we haven't registered this yet.
8940 * Most fields have variables associated with them that
8941 * are initialized to 0; some are initialized to -1 (which
8942 * was the standard before 4.4).
8943 *
8944 * XXX - Since this is called almost 300000 times at startup,
8945 * it might be nice to compare to only 0 and require
8946 * dissectors to pass in zero for unregistered fields.
8947 */
8948 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8949 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8950 "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)
8951 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8952 return;
8953 }
8954
8955 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8956 }
8957}
8958
8959/* deregister already registered fields */
8960void
8961proto_deregister_field (const int parent, int hf_id)
8962{
8963 header_field_info *hfi;
8964 protocol_t *proto;
8965 unsigned i;
8966
8967 g_free(last_field_name);
8968 last_field_name = NULL((void*)0);
8969
8970 if (hf_id == -1 || hf_id == 0)
8971 return;
8972
8973 proto = find_protocol_by_id (parent);
8974 if (!proto || proto->fields == NULL((void*)0)) {
8975 return;
8976 }
8977
8978 for (i = 0; i < proto->fields->len; i++) {
8979 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8980 if (hfi->id == hf_id) {
8981 /* Found the hf_id in this protocol */
8982 wmem_map_remove(gpa_name_map, hfi->abbrev);
8983 g_ptr_array_remove_index_fast(proto->fields, i);
8984 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8985 return;
8986 }
8987 }
8988}
8989
8990/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8991void
8992proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8993{
8994 header_field_info *hfinfo;
8995 protocol_t *proto;
8996
8997 g_free(last_field_name);
8998 last_field_name = NULL((void*)0);
8999
9000 proto = find_protocol_by_id(parent);
9001 if (proto && proto->fields && proto->fields->len > 0) {
9002 guint i = proto->fields->len;
9003 do {
9004 i--;
9005
9006 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9007 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) )
) {
9008 hfinfo_remove_from_gpa_name_map(hfinfo);
9009 expert_deregister_expertinfo(hfinfo->abbrev);
9010 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9011 g_ptr_array_remove_index_fast(proto->fields, i);
9012 }
9013 } while (i > 0);
9014 }
9015}
9016
9017void
9018proto_add_deregistered_data (void *data)
9019{
9020 g_ptr_array_add(deregistered_data, data);
9021}
9022
9023void
9024proto_add_deregistered_slice (size_t block_size, void *mem_block)
9025{
9026 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
)))
;
9027
9028 slice_data->block_size = block_size;
9029 slice_data->mem_block = mem_block;
9030
9031 g_ptr_array_add(deregistered_slice, slice_data);
9032}
9033
9034void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9035{
9036 if (field_strings == NULL((void*)0)) {
9037 return;
9038 }
9039
9040 switch (field_type) {
9041 case FT_FRAMENUM:
9042 /* This is just an integer represented as a pointer */
9043 break;
9044 case FT_PROTOCOL: {
9045 protocol_t *protocol = (protocol_t *)field_strings;
9046 g_free((char *)protocol->short_name);
9047 break;
9048 }
9049 case FT_BOOLEAN: {
9050 true_false_string *tf = (true_false_string *)field_strings;
9051 g_free((char *)tf->true_string);
9052 g_free((char *)tf->false_string);
9053 break;
9054 }
9055 case FT_UINT40:
9056 case FT_INT40:
9057 case FT_UINT48:
9058 case FT_INT48:
9059 case FT_UINT56:
9060 case FT_INT56:
9061 case FT_UINT64:
9062 case FT_INT64: {
9063 if (field_display & BASE_UNIT_STRING0x00001000) {
9064 unit_name_string *unit = (unit_name_string *)field_strings;
9065 g_free((char *)unit->singular);
9066 g_free((char *)unit->plural);
9067 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9068 range_string *rs = (range_string *)field_strings;
9069 while (rs->strptr) {
9070 g_free((char *)rs->strptr);
9071 rs++;
9072 }
9073 } else if (field_display & BASE_EXT_STRING0x00000200) {
9074 val64_string_ext *vse = (val64_string_ext *)field_strings;
9075 val64_string *vs = (val64_string *)vse->_vs_p;
9076 while (vs->strptr) {
9077 g_free((char *)vs->strptr);
9078 vs++;
9079 }
9080 val64_string_ext_free(vse);
9081 field_strings = NULL((void*)0);
9082 } else if (field_display == BASE_CUSTOM) {
9083 /* this will be a pointer to a function, don't free that */
9084 field_strings = NULL((void*)0);
9085 } else {
9086 val64_string *vs64 = (val64_string *)field_strings;
9087 while (vs64->strptr) {
9088 g_free((char *)vs64->strptr);
9089 vs64++;
9090 }
9091 }
9092 break;
9093 }
9094 case FT_CHAR:
9095 case FT_UINT8:
9096 case FT_INT8:
9097 case FT_UINT16:
9098 case FT_INT16:
9099 case FT_UINT24:
9100 case FT_INT24:
9101 case FT_UINT32:
9102 case FT_INT32:
9103 case FT_FLOAT:
9104 case FT_DOUBLE: {
9105 if (field_display & BASE_UNIT_STRING0x00001000) {
9106 unit_name_string *unit = (unit_name_string *)field_strings;
9107 g_free((char *)unit->singular);
9108 g_free((char *)unit->plural);
9109 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9110 range_string *rs = (range_string *)field_strings;
9111 while (rs->strptr) {
9112 g_free((char *)rs->strptr);
9113 rs++;
9114 }
9115 } else if (field_display & BASE_EXT_STRING0x00000200) {
9116 value_string_ext *vse = (value_string_ext *)field_strings;
9117 value_string *vs = (value_string *)vse->_vs_p;
9118 while (vs->strptr) {
9119 g_free((char *)vs->strptr);
9120 vs++;
9121 }
9122 value_string_ext_free(vse);
9123 field_strings = NULL((void*)0);
9124 } else if (field_display == BASE_CUSTOM) {
9125 /* this will be a pointer to a function, don't free that */
9126 field_strings = NULL((void*)0);
9127 } else {
9128 value_string *vs = (value_string *)field_strings;
9129 while (vs->strptr) {
9130 g_free((char *)vs->strptr);
9131 vs++;
9132 }
9133 }
9134 break;
9135 default:
9136 break;
9137 }
9138 }
9139
9140 if (field_type != FT_FRAMENUM) {
9141 g_free((void *)field_strings);
9142 }
9143}
9144
9145static void
9146free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9147{
9148 header_field_info *hfi = (header_field_info *) data;
9149 int hf_id = hfi->id;
9150
9151 g_free((char *)hfi->name);
9152 g_free((char *)hfi->abbrev);
9153 g_free((char *)hfi->blurb);
9154
9155 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9156
9157 if (hfi->parent == -1)
9158 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)
;
9159
9160 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9161}
9162
9163static void
9164free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9165{
9166 g_free (data);
9167}
9168
9169static void
9170free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9171{
9172 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9173
9174 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9175 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)
;
9176}
9177
9178/* free deregistered fields and data */
9179void
9180proto_free_deregistered_fields (void)
9181{
9182 expert_free_deregistered_expertinfos();
9183
9184 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9185 g_ptr_array_free(deregistered_fields, true1);
9186 deregistered_fields = g_ptr_array_new();
9187
9188 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9189 g_ptr_array_free(deregistered_data, true1);
9190 deregistered_data = g_ptr_array_new();
9191
9192 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9193 g_ptr_array_free(deregistered_slice, true1);
9194 deregistered_slice = g_ptr_array_new();
9195}
9196
9197static const value_string hf_display[] = {
9198 { BASE_NONE, "BASE_NONE" },
9199 { BASE_DEC, "BASE_DEC" },
9200 { BASE_HEX, "BASE_HEX" },
9201 { BASE_OCT, "BASE_OCT" },
9202 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9203 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9204 { BASE_CUSTOM, "BASE_CUSTOM" },
9205 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9206 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9207 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9208 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9209 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9210 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9211 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9212 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9213 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9214 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9215 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9216 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9217 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9218 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9219 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9220 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9221 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9222 { BASE_PT_UDP, "BASE_PT_UDP" },
9223 { BASE_PT_TCP, "BASE_PT_TCP" },
9224 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9225 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9226 { BASE_OUI, "BASE_OUI" },
9227 { 0, NULL((void*)0) } };
9228
9229const char* proto_field_display_to_string(int field_display)
9230{
9231 return val_to_str_const(field_display, hf_display, "Unknown");
9232}
9233
9234static inline port_type
9235display_to_port_type(field_display_e e)
9236{
9237 switch (e) {
9238 case BASE_PT_UDP:
9239 return PT_UDP;
9240 case BASE_PT_TCP:
9241 return PT_TCP;
9242 case BASE_PT_DCCP:
9243 return PT_DCCP;
9244 case BASE_PT_SCTP:
9245 return PT_SCTP;
9246 default:
9247 break;
9248 }
9249 return PT_NONE;
9250}
9251
9252/* temporary function containing assert part for easier profiling */
9253static void
9254tmp_fld_check_assert(header_field_info *hfinfo)
9255{
9256 char* tmp_str;
9257
9258 /* The field must have a name (with length > 0) */
9259 if (!hfinfo->name || !hfinfo->name[0]) {
9260 if (hfinfo->abbrev)
9261 /* Try to identify the field */
9262 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)
9263 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9264 else
9265 /* Hum, no luck */
9266 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)"
)
;
9267 }
9268
9269 /* fields with an empty string for an abbreviation aren't filterable */
9270 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9271 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)
;
9272
9273 /* TODO: This check is a significant percentage of startup time (~10%),
9274 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9275 It might be nice to have a way to disable this check when, e.g.,
9276 running TShark many times with the same configuration. */
9277 /* Check that the filter name (abbreviation) is legal;
9278 * it must contain only alphanumerics, '-', "_", and ".". */
9279 unsigned char c;
9280 c = module_check_valid_name(hfinfo->abbrev, false0);
9281 if (c) {
9282 if (c == '.') {
9283 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)
;
9284 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9285 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)
;
9286 } else {
9287 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)
;
9288 }
9289 }
9290
9291 /* These types of fields are allowed to have value_strings,
9292 * true_false_strings or a protocol_t struct
9293 */
9294 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9295 switch (hfinfo->type) {
9296
9297 /*
9298 * These types are allowed to support display value_strings,
9299 * value64_strings, the extended versions of the previous
9300 * two, range strings, or unit strings.
9301 */
9302 case FT_CHAR:
9303 case FT_UINT8:
9304 case FT_UINT16:
9305 case FT_UINT24:
9306 case FT_UINT32:
9307 case FT_UINT40:
9308 case FT_UINT48:
9309 case FT_UINT56:
9310 case FT_UINT64:
9311 case FT_INT8:
9312 case FT_INT16:
9313 case FT_INT24:
9314 case FT_INT32:
9315 case FT_INT40:
9316 case FT_INT48:
9317 case FT_INT56:
9318 case FT_INT64:
9319 case FT_BOOLEAN:
9320 case FT_PROTOCOL:
9321 break;
9322
9323 /*
9324 * This is allowed to have a value of type
9325 * enum ft_framenum_type to indicate what relationship
9326 * the frame in question has to the frame in which
9327 * the field is put.
9328 */
9329 case FT_FRAMENUM:
9330 break;
9331
9332 /*
9333 * These types are allowed to support only unit strings.
9334 */
9335 case FT_FLOAT:
9336 case FT_DOUBLE:
9337 case FT_IEEE_11073_SFLOAT:
9338 case FT_IEEE_11073_FLOAT:
9339 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9340 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))
9341 " (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))
9342 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))
;
9343 }
9344 break;
9345
9346 /*
9347 * These types are allowed to support display
9348 * time_value_strings.
9349 */
9350 case FT_ABSOLUTE_TIME:
9351 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9352 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9353 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9354 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9355 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))
9356 " (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))
9357 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))
;
9358 }
9359 break;
9360
9361 /*
9362 * This type is only allowed to support a string if it's
9363 * a protocol (for pinos).
9364 */
9365 case FT_BYTES:
9366 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9367 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))
9368 " (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))
9369 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))
;
9370 }
9371 break;
9372
9373 default:
9374 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))
9375 " (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))
9376 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))
;
9377 }
9378 }
9379
9380 /* TODO: This check may slow down startup, and output quite a few warnings.
9381 It would be good to be able to enable this (and possibly other checks?)
9382 in non-release builds. */
9383#ifdef ENABLE_CHECK_FILTER
9384 /* Check for duplicate value_string values.
9385 There are lots that have the same value *and* string, so for now only
9386 report those that have same value but different string. */
9387 if ((hfinfo->strings != NULL((void*)0)) &&
9388 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9389 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9390 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9391 (
9392 (hfinfo->type == FT_CHAR) ||
9393 (hfinfo->type == FT_UINT8) ||
9394 (hfinfo->type == FT_UINT16) ||
9395 (hfinfo->type == FT_UINT24) ||
9396 (hfinfo->type == FT_UINT32) ||
9397 (hfinfo->type == FT_INT8) ||
9398 (hfinfo->type == FT_INT16) ||
9399 (hfinfo->type == FT_INT24) ||
9400 (hfinfo->type == FT_INT32) )) {
9401
9402 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9403 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9404 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9405 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9406 } else {
9407 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9408 CHECK_HF_VALUE(value_string, "u", start_values);
9409 }
9410 } else {
9411 const value_string *start_values = (const value_string*)hfinfo->strings;
9412 CHECK_HF_VALUE(value_string, "u", start_values);
9413 }
9414 }
9415
9416 if (hfinfo->type == FT_BOOLEAN) {
9417 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9418 if (tfs) {
9419 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9420 ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9422, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9421 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9422, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9422 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9422, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9423 }
9424 }
9425 }
9426
9427 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9428 const range_string *rs = (const range_string*)(hfinfo->strings);
9429 if (rs) {
9430 const range_string *this_it = rs;
9431
9432 do {
9433 if (this_it->value_max < this_it->value_min) {
9434 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"
, 9438, __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)
9435 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9438, __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)
9436 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9438, __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)
9437 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9438, __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)
9438 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9438, __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)
;
9439 ++this_it;
9440 continue;
9441 }
9442
9443 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9444 /* Not OK if this one is completely hidden by an earlier one! */
9445 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9446 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"
, 9452, __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)
9447 "(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"
, 9452, __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)
9448 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9452, __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)
9449 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9452, __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)
9450 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9452, __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)
9451 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9452, __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)
9452 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9452, __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)
;
9453 }
9454 }
9455 ++this_it;
9456 } while (this_it->strptr);
9457 }
9458 }
9459#endif
9460
9461 switch (hfinfo->type) {
9462
9463 case FT_CHAR:
9464 /* Require the char type to have BASE_HEX, BASE_OCT,
9465 * BASE_CUSTOM, or BASE_NONE as its base.
9466 *
9467 * If the display value is BASE_NONE and there is a
9468 * strings conversion then the dissector writer is
9469 * telling us that the field's numerical value is
9470 * meaningless; we'll avoid showing the value to the
9471 * user.
9472 */
9473 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9474 case BASE_HEX:
9475 case BASE_OCT:
9476 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9477 break;
9478 case BASE_NONE:
9479 if (hfinfo->strings == NULL((void*)0))
9480 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
))
9481 " 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
))
9482 " 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
))
9483 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
))
9484 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
))
;
9485 break;
9486 default:
9487 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9488 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)
9489 " 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)
9490 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)
9491 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)
;
9492 //wmem_free(NULL, tmp_str);
9493 }
9494 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9495 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
))
9496 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
))
9497 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
))
;
9498 }
9499 break;
9500 case FT_INT8:
9501 case FT_INT16:
9502 case FT_INT24:
9503 case FT_INT32:
9504 case FT_INT40:
9505 case FT_INT48:
9506 case FT_INT56:
9507 case FT_INT64:
9508 /* Hexadecimal and octal are, in printf() and everywhere
9509 * else, unsigned so don't allow dissectors to register a
9510 * signed field to be displayed unsigned. (Else how would
9511 * we display negative values?)
9512 */
9513 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9514 case BASE_HEX:
9515 case BASE_OCT:
9516 case BASE_DEC_HEX:
9517 case BASE_HEX_DEC:
9518 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9519 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)
9520 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)
9521 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)
;
9522 //wmem_free(NULL, tmp_str);
9523 }
9524 /* FALL THROUGH */
9525 case FT_UINT8:
9526 case FT_UINT16:
9527 case FT_UINT24:
9528 case FT_UINT32:
9529 case FT_UINT40:
9530 case FT_UINT48:
9531 case FT_UINT56:
9532 case FT_UINT64:
9533 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
))
) {
9534 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9535 if (hfinfo->type != FT_UINT16) {
9536 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))
9537 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))
9538 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))
;
9539 }
9540 if (hfinfo->strings != NULL((void*)0)) {
9541 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)
9542 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)
9543 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)
;
9544 }
9545 if (hfinfo->bitmask != 0) {
9546 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)
9547 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)
9548 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)
;
9549 }
9550 wmem_free(NULL((void*)0), tmp_str);
9551 break;
9552 }
9553
9554 if (hfinfo->display == BASE_OUI) {
9555 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9556 if (hfinfo->type != FT_UINT24) {
9557 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))
9558 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))
9559 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))
;
9560 }
9561 if (hfinfo->strings != NULL((void*)0)) {
9562 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)
9563 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)
9564 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)
;
9565 }
9566 if (hfinfo->bitmask != 0) {
9567 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)
9568 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)
9569 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)
;
9570 }
9571 wmem_free(NULL((void*)0), tmp_str);
9572 break;
9573 }
9574
9575 /* Require integral types (other than frame number,
9576 * which is always displayed in decimal) to have a
9577 * number base.
9578 *
9579 * If the display value is BASE_NONE and there is a
9580 * strings conversion then the dissector writer is
9581 * telling us that the field's numerical value is
9582 * meaningless; we'll avoid showing the value to the
9583 * user.
9584 */
9585 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9586 case BASE_DEC:
9587 case BASE_HEX:
9588 case BASE_OCT:
9589 case BASE_DEC_HEX:
9590 case BASE_HEX_DEC:
9591 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9592 break;
9593 case BASE_NONE:
9594 if (hfinfo->strings == NULL((void*)0)) {
9595 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
))
9596 " 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
))
9597 " 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
))
9598 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
))
9599 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
))
;
9600 }
9601 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9602 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
))
9603 " 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
))
9604 " 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
))
9605 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
))
9606 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
))
;
9607 }
9608 break;
9609
9610 default:
9611 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9612 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)
9613 " 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)
9614 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)
9615 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)
;
9616 //wmem_free(NULL, tmp_str);
9617 }
9618 break;
9619 case FT_BYTES:
9620 case FT_UINT_BYTES:
9621 /* Require bytes to have a "display type" that could
9622 * add a character between displayed bytes.
9623 */
9624 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9625 case BASE_NONE:
9626 case SEP_DOT:
9627 case SEP_DASH:
9628 case SEP_COLON:
9629 case SEP_SPACE:
9630 break;
9631 default:
9632 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9633 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)
9634 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)
;
9635 //wmem_free(NULL, tmp_str);
9636 }
9637 if (hfinfo->bitmask != 0)
9638 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
))
9639 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
))
9640 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
))
;
9641 //allowed to support string if its a protocol (for pinos)
9642 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9643 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
))
9644 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
))
9645 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
))
;
9646 break;
9647
9648 case FT_PROTOCOL:
9649 case FT_FRAMENUM:
9650 if (hfinfo->display != BASE_NONE) {
9651 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9652 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)
9653 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)
9654 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)
;
9655 //wmem_free(NULL, tmp_str);
9656 }
9657 if (hfinfo->bitmask != 0)
9658 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
))
9659 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
))
9660 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
))
;
9661 break;
9662
9663 case FT_BOOLEAN:
9664 break;
9665
9666 case FT_ABSOLUTE_TIME:
9667 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9668 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9669 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)
9670 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)
;
9671 //wmem_free(NULL, tmp_str);
9672 }
9673 if (hfinfo->bitmask != 0)
9674 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
))
9675 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
))
9676 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
))
;
9677 break;
9678
9679 case FT_STRING:
9680 case FT_STRINGZ:
9681 case FT_UINT_STRING:
9682 case FT_STRINGZPAD:
9683 case FT_STRINGZTRUNC:
9684 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9685 case BASE_NONE:
9686 case BASE_STR_WSP:
9687 break;
9688
9689 default:
9690 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9691 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)
9692 " 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)
9693 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)
9694 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)
;
9695 //wmem_free(NULL, tmp_str);
9696 }
9697
9698 if (hfinfo->bitmask != 0)
9699 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
))
9700 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
))
9701 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
))
;
9702 if (hfinfo->strings != NULL((void*)0))
9703 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
))
9704 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
))
9705 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
))
;
9706 break;
9707
9708 case FT_IPv4:
9709 switch (hfinfo->display) {
9710 case BASE_NONE:
9711 case BASE_NETMASK:
9712 break;
9713
9714 default:
9715 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9716 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)
9717 " 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)
9718 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)
9719 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)
;
9720 //wmem_free(NULL, tmp_str);
9721 break;
9722 }
9723 break;
9724 case FT_FLOAT:
9725 case FT_DOUBLE:
9726 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9727 case BASE_NONE:
9728 case BASE_DEC:
9729 case BASE_HEX:
9730 case BASE_EXP:
9731 case BASE_CUSTOM:
9732 break;
9733 default:
9734 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9735 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)
9736 " 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)
9737 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)
9738 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)
;
9739 //wmem_free(NULL, tmp_str);
9740 }
9741 if (hfinfo->bitmask != 0)
9742 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
))
9743 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
))
9744 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
))
;
9745 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9746 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
))
9747 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
))
9748 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
))
;
9749 break;
9750 case FT_IEEE_11073_SFLOAT:
9751 case FT_IEEE_11073_FLOAT:
9752 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9753 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9754 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)
9755 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)
9756 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)
9757 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)
;
9758 //wmem_free(NULL, tmp_str);
9759 }
9760 if (hfinfo->bitmask != 0)
9761 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9762 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9763 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9764 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9765 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
))
9766 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
))
9767 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
))
;
9768 break;
9769 default:
9770 if (hfinfo->display != BASE_NONE) {
9771 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9772 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)
9773 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)
9774 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)
9775 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)
;
9776 //wmem_free(NULL, tmp_str);
9777 }
9778 if (hfinfo->bitmask != 0)
9779 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
))
9780 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
))
9781 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
))
;
9782 if (hfinfo->strings != NULL((void*)0))
9783 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
))
9784 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
))
9785 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
))
;
9786 break;
9787 }
9788}
9789
9790static void
9791register_type_length_mismatch(void)
9792{
9793 static ei_register_info ei[] = {
9794 { &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)}}
}},
9795 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", 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)}}
}},
9796 };
9797
9798 expert_module_t* expert_type_length_mismatch;
9799
9800 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9801
9802 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9803 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9804
9805 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9806 disabling them makes no sense. */
9807 proto_set_cant_toggle(proto_type_length_mismatch);
9808}
9809
9810static void
9811register_byte_array_string_decodinws_error(void)
9812{
9813 static ei_register_info ei[] = {
9814 { &ei_byte_array_string_decoding_failed_error,
9815 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9816 "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)}}
9817 }
9818 },
9819 };
9820
9821 expert_module_t* expert_byte_array_string_decoding_error;
9822
9823 proto_byte_array_string_decoding_error =
9824 proto_register_protocol("Byte Array-String Decoding Error",
9825 "Byte Array-string decoding error",
9826 "_ws.byte_array_string.decoding_error");
9827
9828 expert_byte_array_string_decoding_error =
9829 expert_register_protocol(proto_byte_array_string_decoding_error);
9830 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9831
9832 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9833 disabling them makes no sense. */
9834 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9835}
9836
9837static void
9838register_date_time_string_decodinws_error(void)
9839{
9840 static ei_register_info ei[] = {
9841 { &ei_date_time_string_decoding_failed_error,
9842 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9843 "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)}}
9844 }
9845 },
9846 };
9847
9848 expert_module_t* expert_date_time_string_decoding_error;
9849
9850 proto_date_time_string_decoding_error =
9851 proto_register_protocol("Date and Time-String Decoding Error",
9852 "Date and Time-string decoding error",
9853 "_ws.date_time_string.decoding_error");
9854
9855 expert_date_time_string_decoding_error =
9856 expert_register_protocol(proto_date_time_string_decoding_error);
9857 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9858
9859 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9860 disabling them makes no sense. */
9861 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9862}
9863
9864static void
9865register_string_errors(void)
9866{
9867 static ei_register_info ei[] = {
9868 { &ei_string_trailing_characters,
9869 { "_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)}}
}
9870 },
9871 };
9872
9873 expert_module_t* expert_string_errors;
9874
9875 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9876
9877 expert_string_errors = expert_register_protocol(proto_string_errors);
9878 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9879
9880 /* "String Errors" isn't really a protocol, it's an error indication;
9881 disabling them makes no sense. */
9882 proto_set_cant_toggle(proto_string_errors);
9883}
9884
9885static int
9886proto_register_field_init(header_field_info *hfinfo, const int parent)
9887{
9888
9889 tmp_fld_check_assert(hfinfo);
9890
9891 hfinfo->parent = parent;
9892 hfinfo->same_name_next = NULL((void*)0);
9893 hfinfo->same_name_prev_id = -1;
9894
9895 /* if we always add and never delete, then id == len - 1 is correct */
9896 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9897 if (!gpa_hfinfo.hfi) {
9898 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9899 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9900 /* The entry with index 0 is not used. */
9901 gpa_hfinfo.hfi[0] = NULL((void*)0);
9902 gpa_hfinfo.len = 1;
9903 } else {
9904 gpa_hfinfo.allocated_len += 1000;
9905 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9906 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9907 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9908 }
9909 }
9910 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9911 gpa_hfinfo.len++;
9912 hfinfo->id = gpa_hfinfo.len - 1;
9913
9914 /* if we have real names, enter this field in the name tree */
9915 /* Already checked in tmp_fld_check_assert */
9916 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9917 {
9918
9919 header_field_info *same_name_next_hfinfo;
9920
9921 /* We allow multiple hfinfo's to be registered under the same
9922 * abbreviation. This was done for X.25, as, depending
9923 * on whether it's modulo-8 or modulo-128 operation,
9924 * some bitfield fields may be in different bits of
9925 * a byte, and we want to be able to refer to that field
9926 * with one name regardless of whether the packets
9927 * are modulo-8 or modulo-128 packets. */
9928
9929 /* wmem_map_insert - if key is already present the previous
9930 * hfinfo with the same key/name is returned, otherwise NULL */
9931 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9932 if (same_name_hfinfo) {
9933 /* There's already a field with this name.
9934 * Put the current field *before* that field
9935 * in the list of fields with this name, Thus,
9936 * we end up with an effectively
9937 * doubly-linked-list of same-named hfinfo's,
9938 * with the head of the list (stored in the
9939 * hash) being the last seen hfinfo.
9940 */
9941 same_name_next_hfinfo =
9942 same_name_hfinfo->same_name_next;
9943
9944 hfinfo->same_name_next = same_name_next_hfinfo;
9945 if (same_name_next_hfinfo)
9946 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9947
9948 same_name_hfinfo->same_name_next = hfinfo;
9949 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9950#ifdef ENABLE_CHECK_FILTER
9951 while (same_name_hfinfo) {
9952 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9953 ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9953, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type)); } } while (0)
;
9954 same_name_hfinfo = same_name_hfinfo->same_name_next;
9955 }
9956#endif
9957 }
9958 }
9959
9960 return hfinfo->id;
9961}
9962
9963void
9964proto_register_subtree_array(int * const *indices, const int num_indices)
9965{
9966 int i;
9967 int *const *ptr = indices;
9968
9969 /*
9970 * If we've already allocated the array of tree types, expand
9971 * it; this lets plugins such as mate add tree types after
9972 * the initial startup. (If we haven't already allocated it,
9973 * we don't allocate it; on the first pass, we just assign
9974 * ett values and keep track of how many we've assigned, and
9975 * when we're finished registering all dissectors we allocate
9976 * the array, so that we do only one allocation rather than
9977 * wasting CPU time and memory by growing the array for each
9978 * dissector that registers ett values.)
9979 */
9980 if (tree_is_expanded != NULL((void*)0)) {
9981 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9982
9983 /* set new items to 0 */
9984 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9985 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9986 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9987 }
9988
9989 /*
9990 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9991 * returning the indices through the pointers in the array whose
9992 * first element is pointed to by "indices", and update
9993 * "num_tree_types" appropriately.
9994 */
9995 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9996 if (**ptr != -1 && **ptr != 0) {
9997 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.")
9998 " 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.")
9999 " 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.")
10000 " 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.")
;
10001 }
10002 **ptr = num_tree_types;
10003 }
10004}
10005
10006static void
10007mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10008{
10009 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10010 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10011 char *last_char;
10012
10013 /* ..... field_name: dataaaaaaaaaaaaa
10014 * |
10015 * ^^^^^ name_pos
10016 *
10017 * ..... field_name […]: dataaaaaaaaaaaaa
10018 *
10019 * name_pos==0 means that we have only data or only a field_name
10020 */
10021
10022 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10022, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10023
10024 if (name_pos >= size - trunc_len) {
10025 /* No room for trunc_str after the field_name, put it first. */
10026 name_pos = 0;
10027 }
10028
10029 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10030 if (name_pos == 0) {
10031 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10032 memcpy(label_str, trunc_str + 1, trunc_len);
10033 } else {
10034 memcpy(label_str + name_pos, trunc_str, trunc_len);
10035 }
10036 /* in general, label_str is UTF-8
10037 we can truncate it only at the beginning of a new character
10038 we go backwards from the byte right after our buffer and
10039 find the next starting byte of a UTF-8 character, this is
10040 where we cut
10041 there's no need to use g_utf8_find_prev_char(), the search
10042 will always succeed since we copied trunc_str into the
10043 buffer */
10044 /* g_utf8_prev_char does not deference the memory address
10045 * passed in (until after decrementing it, so it is perfectly
10046 * legal to pass in a pointer one past the last element.
10047 */
10048 last_char = g_utf8_prev_char(label_str + size);
10049 *last_char = '\0';
10050
10051 if (value_pos && *value_pos > 0) {
10052 if (name_pos == 0) {
10053 *value_pos += trunc_len;
10054 } else {
10055 /* Move one back to include trunc_str in the value. */
10056 *value_pos -= 1;
10057 }
10058 }
10059
10060 /* Check if value_pos is past label_str. */
10061 if (value_pos && *value_pos >= size) {
10062 *value_pos = size - 1;
10063 }
10064}
10065
10066static void
10067label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10068{
10069 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10070}
10071
10072static size_t
10073label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10074{
10075 size_t name_pos;
10076
10077 /* "%s: %s", hfinfo->name, text */
10078 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10079 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10080 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10081 if (value_pos) {
10082 *value_pos = pos;
10083 }
10084 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10085 }
10086
10087 if (pos >= ITEM_LABEL_LENGTH240) {
10088 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10089 label_mark_truncated(label_str, name_pos, value_pos);
10090 }
10091
10092 return pos;
10093}
10094
10095static size_t
10096label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10097{
10098 size_t name_pos;
10099
10100 /* "%s: %s (%s)", hfinfo->name, text, descr */
10101 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10102 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10103 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10104 if (value_pos) {
10105 *value_pos = pos;
10106 }
10107 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10108 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10109 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10110 } else {
10111 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10112 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10113 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10114 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10115 }
10116 }
10117
10118 if (pos >= ITEM_LABEL_LENGTH240) {
10119 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10120 label_mark_truncated(label_str, name_pos, value_pos);
10121 }
10122
10123 return pos;
10124}
10125
10126void
10127proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10128{
10129 const header_field_info *hfinfo;
10130 const char *str;
10131 const uint8_t *bytes;
10132 uint32_t integer;
10133 const ipv4_addr_and_mask *ipv4;
10134 const ipv6_addr_and_prefix *ipv6;
10135 const e_guid_t *guid;
10136 char *name;
10137 address addr;
10138 char *addr_str;
10139 char *tmp;
10140
10141 if (!label_str) {
10142 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10142, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10143 return;
10144 }
10145
10146 label_str[0]= '\0';
10147
10148 if (!fi) {
10149 return;
10150 }
10151
10152 hfinfo = fi->hfinfo;
10153
10154 switch (hfinfo->type) {
10155 case FT_NONE:
10156 case FT_PROTOCOL:
10157 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10158 if (value_pos) {
10159 *value_pos = strlen(hfinfo->name);
10160 }
10161 break;
10162
10163 case FT_BOOLEAN:
10164 fill_label_boolean(fi, label_str, value_pos);
10165 break;
10166
10167 case FT_BYTES:
10168 case FT_UINT_BYTES:
10169 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10170 fvalue_get_bytes_data(fi->value),
10171 (unsigned)fvalue_length2(fi->value));
10172 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10173 wmem_free(NULL((void*)0), tmp);
10174 break;
10175
10176 case FT_CHAR:
10177 if (hfinfo->bitmask) {
10178 fill_label_bitfield_char(fi, label_str, value_pos);
10179 } else {
10180 fill_label_char(fi, label_str, value_pos);
10181 }
10182 break;
10183
10184 /* Four types of integers to take care of:
10185 * Bitfield, with val_string
10186 * Bitfield, w/o val_string
10187 * Non-bitfield, with val_string
10188 * Non-bitfield, w/o val_string
10189 */
10190 case FT_UINT8:
10191 case FT_UINT16:
10192 case FT_UINT24:
10193 case FT_UINT32:
10194 if (hfinfo->bitmask) {
10195 fill_label_bitfield(fi, label_str, value_pos, false0);
10196 } else {
10197 fill_label_number(fi, label_str, value_pos, false0);
10198 }
10199 break;
10200
10201 case FT_FRAMENUM:
10202 fill_label_number(fi, label_str, value_pos, false0);
10203 break;
10204
10205 case FT_UINT40:
10206 case FT_UINT48:
10207 case FT_UINT56:
10208 case FT_UINT64:
10209 if (hfinfo->bitmask) {
10210 fill_label_bitfield64(fi, label_str, value_pos, false0);
10211 } else {
10212 fill_label_number64(fi, label_str, value_pos, false0);
10213 }
10214 break;
10215
10216 case FT_INT8:
10217 case FT_INT16:
10218 case FT_INT24:
10219 case FT_INT32:
10220 if (hfinfo->bitmask) {
10221 fill_label_bitfield(fi, label_str, value_pos, true1);
10222 } else {
10223 fill_label_number(fi, label_str, value_pos, true1);
10224 }
10225 break;
10226
10227 case FT_INT40:
10228 case FT_INT48:
10229 case FT_INT56:
10230 case FT_INT64:
10231 if (hfinfo->bitmask) {
10232 fill_label_bitfield64(fi, label_str, value_pos, true1);
10233 } else {
10234 fill_label_number64(fi, label_str, value_pos, true1);
10235 }
10236 break;
10237
10238 case FT_FLOAT:
10239 case FT_DOUBLE:
10240 fill_label_float(fi, label_str, value_pos);
10241 break;
10242
10243 case FT_ABSOLUTE_TIME:
10244 {
10245 const nstime_t *value = fvalue_get_time(fi->value);
10246 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10247 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10248 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10249 }
10250 if (hfinfo->strings) {
10251 /*
10252 * Table of time valus to be displayed
10253 * specially.
10254 */
10255 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10256 if (time_string != NULL((void*)0)) {
10257 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10258 break;
10259 }
10260 }
10261 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10262 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10263 wmem_free(NULL((void*)0), tmp);
10264 break;
10265 }
10266 case FT_RELATIVE_TIME:
10267 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10268 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10269 wmem_free(NULL((void*)0), tmp);
10270 break;
10271
10272 case FT_IPXNET:
10273 integer = fvalue_get_uinteger(fi->value);
10274 tmp = get_ipxnet_name(NULL((void*)0), integer);
10275 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10276 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10277 wmem_free(NULL((void*)0), tmp);
10278 wmem_free(NULL((void*)0), addr_str);
10279 break;
10280
10281 case FT_VINES:
10282 addr.type = AT_VINES;
10283 addr.len = VINES_ADDR_LEN6;
10284 addr.data = fvalue_get_bytes_data(fi->value);
10285
10286 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10287 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10288 wmem_free(NULL((void*)0), addr_str);
10289 break;
10290
10291 case FT_ETHER:
10292 bytes = fvalue_get_bytes_data(fi->value);
10293
10294 addr.type = AT_ETHER;
10295 addr.len = 6;
10296 addr.data = bytes;
10297
10298 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10299 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10300 wmem_free(NULL((void*)0), addr_str);
10301 break;
10302
10303 case FT_IPv4:
10304 ipv4 = fvalue_get_ipv4(fi->value);
10305 set_address_ipv4(&addr, ipv4);
10306
10307 if (hfinfo->display == BASE_NETMASK) {
10308 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10309 } else {
10310 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10311 }
10312 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10313 wmem_free(NULL((void*)0), addr_str);
10314 free_address(&addr);
10315 break;
10316
10317 case FT_IPv6:
10318 ipv6 = fvalue_get_ipv6(fi->value);
10319 set_address_ipv6(&addr, ipv6);
10320
10321 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10322 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10323 wmem_free(NULL((void*)0), addr_str);
10324 free_address(&addr);
10325 break;
10326
10327 case FT_FCWWN:
10328 bytes = fvalue_get_bytes_data(fi->value);
10329 addr.type = AT_FCWWN;
10330 addr.len = FCWWN_ADDR_LEN8;
10331 addr.data = bytes;
10332
10333 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10334 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10335 wmem_free(NULL((void*)0), addr_str);
10336 break;
10337
10338 case FT_GUID:
10339 guid = fvalue_get_guid(fi->value);
10340 tmp = guid_to_str(NULL((void*)0), guid);
10341 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10342 wmem_free(NULL((void*)0), tmp);
10343 break;
10344
10345 case FT_OID:
10346 bytes = fvalue_get_bytes_data(fi->value);
10347 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10348 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10349 if (name) {
10350 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10351 wmem_free(NULL((void*)0), name);
10352 } else {
10353 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10354 }
10355 wmem_free(NULL((void*)0), tmp);
10356 break;
10357
10358 case FT_REL_OID:
10359 bytes = fvalue_get_bytes_data(fi->value);
10360 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10361 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10362 if (name) {
10363 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10364 wmem_free(NULL((void*)0), name);
10365 } else {
10366 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10367 }
10368 wmem_free(NULL((void*)0), tmp);
10369 break;
10370
10371 case FT_SYSTEM_ID:
10372 bytes = fvalue_get_bytes_data(fi->value);
10373 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10374 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10375 wmem_free(NULL((void*)0), tmp);
10376 break;
10377
10378 case FT_EUI64:
10379 bytes = fvalue_get_bytes_data(fi->value);
10380 addr.type = AT_EUI64;
10381 addr.len = EUI64_ADDR_LEN8;
10382 addr.data = bytes;
10383
10384 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10385 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10386 wmem_free(NULL((void*)0), addr_str);
10387 break;
10388 case FT_STRING:
10389 case FT_STRINGZ:
10390 case FT_UINT_STRING:
10391 case FT_STRINGZPAD:
10392 case FT_STRINGZTRUNC:
10393 case FT_AX25:
10394 str = fvalue_get_string(fi->value);
10395 label_fill(label_str, 0, hfinfo, str, value_pos);
10396 break;
10397
10398 case FT_IEEE_11073_SFLOAT:
10399 case FT_IEEE_11073_FLOAT:
10400 fill_label_ieee_11073_float(fi, label_str, value_pos);
10401 break;
10402
10403 default:
10404 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
))
10405 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
))
10406 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
))
10407 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
))
;
10408 break;
10409 }
10410}
10411
10412static void
10413fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10414{
10415 char *p;
10416 int bitfield_byte_length = 0, bitwidth;
10417 uint64_t unshifted_value;
10418 uint64_t value;
10419
10420 const header_field_info *hfinfo = fi->hfinfo;
10421
10422 value = fvalue_get_uinteger64(fi->value);
10423 if (hfinfo->bitmask) {
10424 /* Figure out the bit width */
10425 bitwidth = hfinfo_container_bitwidth(hfinfo);
10426
10427 /* Un-shift bits */
10428 unshifted_value = value;
10429 unshifted_value <<= hfinfo_bitshift(hfinfo);
10430
10431 /* Create the bitfield first */
10432 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10433 bitfield_byte_length = (int) (p - label_str);
10434 }
10435
10436 /* Fill in the textual info */
10437 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10438}
10439
10440static const char *
10441hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10442{
10443 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10444 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10445
10446 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10447 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10448 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10449 else
10450 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10451 }
10452
10453 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10454 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10455
10456 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10457 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10458
10459 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10460}
10461
10462static const char *
10463hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10464{
10465 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10466 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10467 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10468 else
10469 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10470 }
10471
10472 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10473 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10474
10475 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10476 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10477
10478 /* If this is reached somebody registered a 64-bit field with a 32-bit
10479 * value-string, which isn't right. */
10480 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)
10481 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10482
10483 /* This is necessary to squelch MSVC errors; is there
10484 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10485 never returns? */
10486 return NULL((void*)0);
10487}
10488
10489static const char *
10490hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10491{
10492 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10493 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10494
10495 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)
;
10496
10497 /* This is necessary to squelch MSVC errors; is there
10498 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10499 never returns? */
10500 return NULL((void*)0);
10501}
10502
10503static const char *
10504hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10505{
10506 const char *str = hf_try_val_to_str(value, hfinfo);
10507
10508 return (str) ? str : unknown_str;
10509}
10510
10511static const char *
10512hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10513{
10514 const char *str = hf_try_val64_to_str(value, hfinfo);
10515
10516 return (str) ? str : unknown_str;
10517}
10518
10519/* Fills data for bitfield chars with val_strings */
10520static void
10521fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10522{
10523 char *p;
10524 int bitfield_byte_length, bitwidth;
10525 uint32_t unshifted_value;
10526 uint32_t value;
10527
10528 char buf[32];
10529 const char *out;
10530
10531 const header_field_info *hfinfo = fi->hfinfo;
10532
10533 /* Figure out the bit width */
10534 bitwidth = hfinfo_container_bitwidth(hfinfo);
10535
10536 /* Un-shift bits */
10537 value = fvalue_get_uinteger(fi->value);
10538
10539 unshifted_value = value;
10540 if (hfinfo->bitmask) {
10541 unshifted_value <<= hfinfo_bitshift(hfinfo);
10542 }
10543
10544 /* Create the bitfield first */
10545 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10546 bitfield_byte_length = (int) (p - label_str);
10547
10548 /* Fill in the textual info using stored (shifted) value */
10549 if (hfinfo->display == BASE_CUSTOM) {
10550 char tmp[ITEM_LABEL_LENGTH240];
10551 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10552
10553 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10553, "fmtfunc"))))
;
10554 fmtfunc(tmp, value);
10555 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10556 }
10557 else if (hfinfo->strings) {
10558 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10559
10560 out = hfinfo_char_vals_format(hfinfo, buf, value);
10561 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10562 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10563 else
10564 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10565 }
10566 else {
10567 out = hfinfo_char_value_format(hfinfo, buf, value);
10568
10569 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10570 }
10571}
10572
10573/* Fills data for bitfield ints with val_strings */
10574static void
10575fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10576{
10577 char *p;
10578 int bitfield_byte_length, bitwidth;
10579 uint32_t value, unshifted_value;
10580 char buf[NUMBER_LABEL_LENGTH80];
10581 const char *out;
10582
10583 const header_field_info *hfinfo = fi->hfinfo;
10584
10585 /* Figure out the bit width */
10586 if (fi->flags & FI_VARINT0x00040000)
10587 bitwidth = fi->length*8;
10588 else
10589 bitwidth = hfinfo_container_bitwidth(hfinfo);
10590
10591 /* Un-shift bits */
10592 if (is_signed)
10593 value = fvalue_get_sinteger(fi->value);
10594 else
10595 value = fvalue_get_uinteger(fi->value);
10596
10597 unshifted_value = value;
10598 if (hfinfo->bitmask) {
10599 unshifted_value <<= hfinfo_bitshift(hfinfo);
10600 }
10601
10602 /* Create the bitfield first */
10603 if (fi->flags & FI_VARINT0x00040000)
10604 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10605 else
10606 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10607 bitfield_byte_length = (int) (p - label_str);
10608
10609 /* Fill in the textual info using stored (shifted) value */
10610 if (hfinfo->display == BASE_CUSTOM) {
10611 char tmp[ITEM_LABEL_LENGTH240];
10612 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10613
10614 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10614, "fmtfunc"))))
;
10615 fmtfunc(tmp, value);
10616 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10617 }
10618 else if (hfinfo->strings) {
10619 const char *val_str = hf_try_val_to_str(value, hfinfo);
10620
10621 out = hfinfo_number_vals_format(hfinfo, buf, value);
10622 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10623 /*
10624 * Unique values only display value_string string
10625 * if there is a match. Otherwise it's just a number
10626 */
10627 if (val_str) {
10628 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10629 } else {
10630 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10631 }
10632 } else {
10633 if (val_str == NULL((void*)0))
10634 val_str = "Unknown";
10635
10636 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10637 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10638 else
10639 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10640 }
10641 }
10642 else {
10643 out = hfinfo_number_value_format(hfinfo, buf, value);
10644
10645 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10646 }
10647}
10648
10649static void
10650fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10651{
10652 char *p;
10653 int bitfield_byte_length, bitwidth;
10654 uint64_t value, unshifted_value;
10655 char buf[NUMBER_LABEL_LENGTH80];
10656 const char *out;
10657
10658 const header_field_info *hfinfo = fi->hfinfo;
10659
10660 /* Figure out the bit width */
10661 if (fi->flags & FI_VARINT0x00040000)
10662 bitwidth = fi->length*8;
10663 else
10664 bitwidth = hfinfo_container_bitwidth(hfinfo);
10665
10666 /* Un-shift bits */
10667 if (is_signed)
10668 value = fvalue_get_sinteger64(fi->value);
10669 else
10670 value = fvalue_get_uinteger64(fi->value);
10671
10672 unshifted_value = value;
10673 if (hfinfo->bitmask) {
10674 unshifted_value <<= hfinfo_bitshift(hfinfo);
10675 }
10676
10677 /* Create the bitfield first */
10678 if (fi->flags & FI_VARINT0x00040000)
10679 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10680 else
10681 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10682 bitfield_byte_length = (int) (p - label_str);
10683
10684 /* Fill in the textual info using stored (shifted) value */
10685 if (hfinfo->display == BASE_CUSTOM) {
10686 char tmp[ITEM_LABEL_LENGTH240];
10687 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10688
10689 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10689, "fmtfunc64"
))))
;
10690 fmtfunc64(tmp, value);
10691 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10692 }
10693 else if (hfinfo->strings) {
10694 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10695
10696 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10697 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10698 /*
10699 * Unique values only display value_string string
10700 * if there is a match. Otherwise it's just a number
10701 */
10702 if (val_str) {
10703 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10704 } else {
10705 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10706 }
10707 } else {
10708 if (val_str == NULL((void*)0))
10709 val_str = "Unknown";
10710
10711 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10712 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10713 else
10714 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10715 }
10716 }
10717 else {
10718 out = hfinfo_number_value_format64(hfinfo, buf, value);
10719
10720 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10721 }
10722}
10723
10724static void
10725fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10726{
10727 const header_field_info *hfinfo = fi->hfinfo;
10728 uint32_t value;
10729
10730 char buf[32];
10731 const char *out;
10732
10733 value = fvalue_get_uinteger(fi->value);
10734
10735 /* Fill in the textual info */
10736 if (hfinfo->display == BASE_CUSTOM) {
10737 char tmp[ITEM_LABEL_LENGTH240];
10738 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10739
10740 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10740, "fmtfunc"))))
;
10741 fmtfunc(tmp, value);
10742 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10743 }
10744 else if (hfinfo->strings) {
10745 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10746
10747 out = hfinfo_char_vals_format(hfinfo, buf, value);
10748 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10749 }
10750 else {
10751 out = hfinfo_char_value_format(hfinfo, buf, value);
10752
10753 label_fill(label_str, 0, hfinfo, out, value_pos);
10754 }
10755}
10756
10757static void
10758fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10759{
10760 const header_field_info *hfinfo = fi->hfinfo;
10761 uint32_t value;
10762
10763 char buf[NUMBER_LABEL_LENGTH80];
10764 const char *out;
10765
10766 if (is_signed)
10767 value = fvalue_get_sinteger(fi->value);
10768 else
10769 value = fvalue_get_uinteger(fi->value);
10770
10771 /* Fill in the textual info */
10772 if (hfinfo->display == BASE_CUSTOM) {
10773 char tmp[ITEM_LABEL_LENGTH240];
10774 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10775
10776 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10776, "fmtfunc"))))
;
10777 fmtfunc(tmp, value);
10778 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10779 }
10780 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10781 /*
10782 * It makes no sense to have a value-string table for a
10783 * frame-number field - they're just integers giving
10784 * the ordinal frame number.
10785 */
10786 const char *val_str = hf_try_val_to_str(value, hfinfo);
10787
10788 out = hfinfo_number_vals_format(hfinfo, buf, value);
10789 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10790 /*
10791 * Unique values only display value_string string
10792 * if there is a match. Otherwise it's just a number
10793 */
10794 if (val_str) {
10795 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10796 } else {
10797 label_fill(label_str, 0, hfinfo, out, value_pos);
10798 }
10799 } else {
10800 if (val_str == NULL((void*)0))
10801 val_str = "Unknown";
10802
10803 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10804 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10805 else
10806 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10807 }
10808 }
10809 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
))
) {
10810 char tmp[ITEM_LABEL_LENGTH240];
10811
10812 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10813 display_to_port_type((field_display_e)hfinfo->display), value);
10814 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10815 }
10816 else {
10817 out = hfinfo_number_value_format(hfinfo, buf, value);
10818
10819 label_fill(label_str, 0, hfinfo, out, value_pos);
10820 }
10821}
10822
10823static void
10824fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10825{
10826 const header_field_info *hfinfo = fi->hfinfo;
10827 uint64_t value;
10828
10829 char buf[NUMBER_LABEL_LENGTH80];
10830 const char *out;
10831
10832 if (is_signed)
10833 value = fvalue_get_sinteger64(fi->value);
10834 else
10835 value = fvalue_get_uinteger64(fi->value);
10836
10837 /* Fill in the textual info */
10838 if (hfinfo->display == BASE_CUSTOM) {
10839 char tmp[ITEM_LABEL_LENGTH240];
10840 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10841
10842 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10842, "fmtfunc64"
))))
;
10843 fmtfunc64(tmp, value);
10844 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10845 }
10846 else if (hfinfo->strings) {
10847 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10848
10849 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10850 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10851 /*
10852 * Unique values only display value_string string
10853 * if there is a match. Otherwise it's just a number
10854 */
10855 if (val_str) {
10856 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10857 } else {
10858 label_fill(label_str, 0, hfinfo, out, value_pos);
10859 }
10860 } else {
10861 if (val_str == NULL((void*)0))
10862 val_str = "Unknown";
10863
10864 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10865 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10866 else
10867 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10868 }
10869 }
10870 else {
10871 out = hfinfo_number_value_format64(hfinfo, buf, value);
10872
10873 label_fill(label_str, 0, hfinfo, out, value_pos);
10874 }
10875}
10876
10877static size_t
10878fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10879{
10880 int display;
10881 int n;
10882 double value;
10883
10884 if (label_str_size < 12) {
10885 /* Not enough room to write an entire floating point value. */
10886 return 0;
10887 }
10888
10889 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10890 value = fvalue_get_floating(fi->value);
10891
10892 if (display == BASE_CUSTOM) {
10893 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10894 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10894, "fmtfunc"))))
;
10895 fmtfunc(label_str, value);
10896 return strlen(label_str);
10897 }
10898
10899 switch (display) {
10900 case BASE_NONE:
10901 if (fi->hfinfo->type == FT_FLOAT) {
10902 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10903 } else {
10904 n = (int)strlen(dtoa_g_fmt(label_str, value));
10905 }
10906 break;
10907 case BASE_DEC:
10908 n = snprintf(label_str, label_str_size, "%f", value);
10909 break;
10910 case BASE_HEX:
10911 n = snprintf(label_str, label_str_size, "%a", value);
10912 break;
10913 case BASE_EXP:
10914 n = snprintf(label_str, label_str_size, "%e", value);
10915 break;
10916 default:
10917 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10917
, __func__, "assertion \"not reached\" failed")
;
10918 }
10919 if (n < 0) {
10920 return 0; /* error */
10921 }
10922 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10923 const char *hf_str_val;
10924 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10925 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10926 }
10927 if (n > label_str_size) {
10928 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10928, __func__, "label length too small"); } } while (0)
;
10929 return strlen(label_str);
10930 }
10931
10932 return n;
10933}
10934
10935void
10936fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10937{
10938 char tmp[ITEM_LABEL_LENGTH240];
10939
10940 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10941 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10942}
10943
10944static size_t
10945fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10946{
10947 int display;
10948 size_t pos = 0;
10949 double value;
10950 char* tmp_str;
10951
10952 if (label_str_size < 12) {
10953 /* Not enough room to write an entire floating point value. */
10954 return 0;
10955 }
10956
10957 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10958 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10959 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10960 wmem_free(NULL((void*)0), tmp_str);
10961
10962 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10963 const char *hf_str_val;
10964 fvalue_to_double(fi->value, &value);
10965 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10966 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10967 }
10968 if ((int)pos > label_str_size) {
10969 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10969, __func__, "label length too small"); } } while (0)
;
10970 return strlen(label_str);
10971 }
10972
10973 return pos;
10974}
10975
10976void
10977fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10978{
10979 char tmp[ITEM_LABEL_LENGTH240];
10980
10981 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10982 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10983}
10984
10985int
10986hfinfo_bitshift(const header_field_info *hfinfo)
10987{
10988 return ws_ctz(hfinfo->bitmask);
10989}
10990
10991
10992static int
10993hfinfo_bitoffset(const header_field_info *hfinfo)
10994{
10995 if (!hfinfo->bitmask) {
10996 return 0;
10997 }
10998
10999 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11000 * as the first bit */
11001 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11002}
11003
11004static int
11005hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11006{
11007 if (!hfinfo->bitmask) {
11008 return 0;
11009 }
11010
11011 /* ilog2 = first set bit, ctz = last set bit */
11012 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11013}
11014
11015static int
11016hfinfo_type_bitwidth(enum ftenum type)
11017{
11018 int bitwidth = 0;
11019
11020 switch (type) {
11021 case FT_CHAR:
11022 case FT_UINT8:
11023 case FT_INT8:
11024 bitwidth = 8;
11025 break;
11026 case FT_UINT16:
11027 case FT_INT16:
11028 bitwidth = 16;
11029 break;
11030 case FT_UINT24:
11031 case FT_INT24:
11032 bitwidth = 24;
11033 break;
11034 case FT_UINT32:
11035 case FT_INT32:
11036 bitwidth = 32;
11037 break;
11038 case FT_UINT40:
11039 case FT_INT40:
11040 bitwidth = 40;
11041 break;
11042 case FT_UINT48:
11043 case FT_INT48:
11044 bitwidth = 48;
11045 break;
11046 case FT_UINT56:
11047 case FT_INT56:
11048 bitwidth = 56;
11049 break;
11050 case FT_UINT64:
11051 case FT_INT64:
11052 bitwidth = 64;
11053 break;
11054 default:
11055 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11055))
;
11056 ;
11057 }
11058 return bitwidth;
11059}
11060
11061
11062static int
11063hfinfo_container_bitwidth(const header_field_info *hfinfo)
11064{
11065 if (!hfinfo->bitmask) {
11066 return 0;
11067 }
11068
11069 if (hfinfo->type == FT_BOOLEAN) {
11070 return hfinfo->display; /* hacky? :) */
11071 }
11072
11073 return hfinfo_type_bitwidth(hfinfo->type);
11074}
11075
11076static int
11077hfinfo_hex_digits(const header_field_info *hfinfo)
11078{
11079 int bitwidth;
11080
11081 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11082 * appropriate to determine the number of hex digits for the field.
11083 * So instead, we compute it from the bitmask.
11084 */
11085 if (hfinfo->bitmask != 0) {
11086 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11087 } else {
11088 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11089 }
11090
11091 /* Divide by 4, rounding up, to get number of hex digits. */
11092 return (bitwidth + 3) / 4;
11093}
11094
11095const char *
11096hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11097{
11098 char *ptr = &buf[6];
11099 static const char hex_digits[16] =
11100 { '0', '1', '2', '3', '4', '5', '6', '7',
11101 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11102
11103 *ptr = '\0';
11104 *(--ptr) = '\'';
11105 /* Properly format value */
11106 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11107 /*
11108 * Printable, so just show the character, and, if it needs
11109 * to be escaped, escape it.
11110 */
11111 *(--ptr) = value;
11112 if (value == '\\' || value == '\'')
11113 *(--ptr) = '\\';
11114 } else {
11115 /*
11116 * Non-printable; show it as an escape sequence.
11117 */
11118 switch (value) {
11119
11120 case '\0':
11121 /*
11122 * Show a NUL with only one digit.
11123 */
11124 *(--ptr) = '0';
11125 break;
11126
11127 case '\a':
11128 case '\b':
11129 case '\f':
11130 case '\n':
11131 case '\r':
11132 case '\t':
11133 case '\v':
11134 *(--ptr) = value - '\a' + 'a';
11135 break;
11136
11137 default:
11138 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11139
11140 case BASE_OCT:
11141 *(--ptr) = (value & 0x7) + '0';
11142 value >>= 3;
11143 *(--ptr) = (value & 0x7) + '0';
11144 value >>= 3;
11145 *(--ptr) = (value & 0x7) + '0';
11146 break;
11147
11148 case BASE_HEX:
11149 *(--ptr) = hex_digits[value & 0x0F];
11150 value >>= 4;
11151 *(--ptr) = hex_digits[value & 0x0F];
11152 *(--ptr) = 'x';
11153 break;
11154
11155 default:
11156 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11157 }
11158 }
11159 *(--ptr) = '\\';
11160 }
11161 *(--ptr) = '\'';
11162 return ptr;
11163}
11164
11165static const char *
11166hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11167{
11168 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11169 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
))
;
11170
11171 *ptr = '\0';
11172 /* Properly format value */
11173 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11174 case BASE_DEC:
11175 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11176
11177 case BASE_DEC_HEX:
11178 *(--ptr) = ')';
11179 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11180 *(--ptr) = '(';
11181 *(--ptr) = ' ';
11182 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11183 return ptr;
11184
11185 case BASE_OCT:
11186 return oct_to_str_back(ptr, value);
11187
11188 case BASE_HEX:
11189 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11190
11191 case BASE_HEX_DEC:
11192 *(--ptr) = ')';
11193 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11194 *(--ptr) = '(';
11195 *(--ptr) = ' ';
11196 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11197 return ptr;
11198
11199 case BASE_PT_UDP:
11200 case BASE_PT_TCP:
11201 case BASE_PT_DCCP:
11202 case BASE_PT_SCTP:
11203 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11204 display_to_port_type((field_display_e)display), value);
11205 return buf;
11206 case BASE_OUI:
11207 {
11208 uint8_t p_oui[3];
11209 const char *manuf_name;
11210
11211 p_oui[0] = value >> 16 & 0xFF;
11212 p_oui[1] = value >> 8 & 0xFF;
11213 p_oui[2] = value & 0xFF;
11214
11215 /* Attempt an OUI lookup. */
11216 manuf_name = uint_get_manuf_name_if_known(value);
11217 if (manuf_name == NULL((void*)0)) {
11218 /* Could not find an OUI. */
11219 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11220 }
11221 else {
11222 /* Found an address string. */
11223 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11224 }
11225 return buf;
11226 }
11227
11228 default:
11229 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11230 }
11231 return ptr;
11232}
11233
11234static const char *
11235hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11236{
11237 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11238 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
))
;
11239
11240 *ptr = '\0';
11241 /* Properly format value */
11242 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11243 case BASE_DEC:
11244 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11245
11246 case BASE_DEC_HEX:
11247 *(--ptr) = ')';
11248 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11249 *(--ptr) = '(';
11250 *(--ptr) = ' ';
11251 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11252 return ptr;
11253
11254 case BASE_OCT:
11255 return oct64_to_str_back(ptr, value);
11256
11257 case BASE_HEX:
11258 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11259
11260 case BASE_HEX_DEC:
11261 *(--ptr) = ')';
11262 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11263 *(--ptr) = '(';
11264 *(--ptr) = ' ';
11265 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11266 return ptr;
11267
11268 default:
11269 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11270 }
11271
11272 return ptr;
11273}
11274
11275static const char *
11276hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11277{
11278 int display = hfinfo->display;
11279
11280 if (hfinfo->type == FT_FRAMENUM) {
11281 /*
11282 * Frame numbers are always displayed in decimal.
11283 */
11284 display = BASE_DEC;
11285 }
11286
11287 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11288}
11289
11290static const char *
11291hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11292{
11293 int display = hfinfo->display;
11294
11295 if (hfinfo->type == FT_FRAMENUM) {
11296 /*
11297 * Frame numbers are always displayed in decimal.
11298 */
11299 display = BASE_DEC;
11300 }
11301
11302 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11303}
11304
11305static const char *
11306hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11307{
11308 /* Get the underlying BASE_ value */
11309 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11310
11311 return hfinfo_char_value_format_display(display, buf, value);
11312}
11313
11314static const char *
11315hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11316{
11317 /* Get the underlying BASE_ value */
11318 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11319
11320 if (hfinfo->type == FT_FRAMENUM) {
11321 /*
11322 * Frame numbers are always displayed in decimal.
11323 */
11324 display = BASE_DEC;
11325 }
11326
11327 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11328 display = BASE_DEC;
11329 } else if (display == BASE_OUI) {
11330 display = BASE_HEX;
11331 }
11332
11333 switch (display) {
11334 case BASE_NONE:
11335 /* case BASE_DEC: */
11336 case BASE_DEC_HEX:
11337 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11338 case BASE_CUSTOM:
11339 display = BASE_DEC;
11340 break;
11341
11342 /* case BASE_HEX: */
11343 case BASE_HEX_DEC:
11344 display = BASE_HEX;
11345 break;
11346 }
11347
11348 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11349}
11350
11351static const char *
11352hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11353{
11354 /* Get the underlying BASE_ value */
11355 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11356
11357 if (hfinfo->type == FT_FRAMENUM) {
11358 /*
11359 * Frame numbers are always displayed in decimal.
11360 */
11361 display = BASE_DEC;
11362 }
11363
11364 switch (display) {
11365 case BASE_NONE:
11366 /* case BASE_DEC: */
11367 case BASE_DEC_HEX:
11368 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11369 case BASE_CUSTOM:
11370 display = BASE_DEC;
11371 break;
11372
11373 /* case BASE_HEX: */
11374 case BASE_HEX_DEC:
11375 display = BASE_HEX;
11376 break;
11377 }
11378
11379 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11380}
11381
11382static const char *
11383hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11384{
11385 /* Get the underlying BASE_ value */
11386 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11387
11388 return hfinfo_char_value_format_display(display, buf, value);
11389}
11390
11391static const char *
11392hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11393{
11394 /* Get the underlying BASE_ value */
11395 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11396
11397 if (display == BASE_NONE)
11398 return NULL((void*)0);
11399
11400 if (display == BASE_DEC_HEX)
11401 display = BASE_DEC;
11402 if (display == BASE_HEX_DEC)
11403 display = BASE_HEX;
11404
11405 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11406}
11407
11408static const char *
11409hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11410{
11411 /* Get the underlying BASE_ value */
11412 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11413
11414 if (display == BASE_NONE)
11415 return NULL((void*)0);
11416
11417 if (display == BASE_DEC_HEX)
11418 display = BASE_DEC;
11419 if (display == BASE_HEX_DEC)
11420 display = BASE_HEX;
11421
11422 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11423}
11424
11425const char *
11426proto_registrar_get_name(const int n)
11427{
11428 header_field_info *hfinfo;
11429
11430 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", 11430
, __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", 11430
, "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", 11430, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11431 return hfinfo->name;
11432}
11433
11434const char *
11435proto_registrar_get_abbrev(const int n)
11436{
11437 header_field_info *hfinfo;
11438
11439 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", 11439
, __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", 11439
, "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", 11439, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11440 return hfinfo->abbrev;
11441}
11442
11443enum ftenum
11444proto_registrar_get_ftype(const int n)
11445{
11446 header_field_info *hfinfo;
11447
11448 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", 11448
, __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", 11448
, "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", 11448, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11449 return hfinfo->type;
11450}
11451
11452int
11453proto_registrar_get_parent(const int n)
11454{
11455 header_field_info *hfinfo;
11456
11457 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", 11457
, __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", 11457
, "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", 11457, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11458 return hfinfo->parent;
11459}
11460
11461bool_Bool
11462proto_registrar_is_protocol(const int n)
11463{
11464 header_field_info *hfinfo;
11465
11466 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", 11466
, __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", 11466
, "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", 11466, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11467 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11468}
11469
11470/* Returns length of field in packet (not necessarily the length
11471 * in our internal representation, as in the case of IPv4).
11472 * 0 means undeterminable at time of registration
11473 * -1 means the field is not registered. */
11474int
11475proto_registrar_get_length(const int n)
11476{
11477 header_field_info *hfinfo;
11478
11479 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", 11479
, __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", 11479
, "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", 11479, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11480 return ftype_wire_size(hfinfo->type);
11481}
11482
11483/* Looks for a protocol or a field in a proto_tree. Returns true if
11484 * it exists anywhere, or false if it exists nowhere. */
11485bool_Bool
11486proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11487{
11488 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11489
11490 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11491 return true1;
11492 }
11493 else {
11494 return false0;
11495 }
11496}
11497
11498/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11499 * This only works if the hfindex was "primed" before the dissection
11500 * took place, as we just pass back the already-created GPtrArray*.
11501 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11502 * handles that. */
11503GPtrArray *
11504proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11505{
11506 if (!tree)
11507 return NULL((void*)0);
11508
11509 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11510 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11511 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11512 else
11513 return NULL((void*)0);
11514}
11515
11516bool_Bool
11517proto_tracking_interesting_fields(const proto_tree *tree)
11518{
11519 GHashTable *interesting_hfids;
11520
11521 if (!tree)
11522 return false0;
11523
11524 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11525
11526 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11527}
11528
11529/* Helper struct for proto_find_info() and proto_all_finfos() */
11530typedef struct {
11531 GPtrArray *array;
11532 int id;
11533} ffdata_t;
11534
11535/* Helper function for proto_find_info() */
11536static bool_Bool
11537find_finfo(proto_node *node, void * data)
11538{
11539 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11540 if (fi && fi->hfinfo) {
11541 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11542 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11543 }
11544 }
11545
11546 /* Don't stop traversing. */
11547 return false0;
11548}
11549
11550/* Helper function for proto_find_first_info() */
11551static bool_Bool
11552find_first_finfo(proto_node *node, void *data)
11553{
11554 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11555 if (fi && fi->hfinfo) {
11556 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11557 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11558
11559 /* Stop traversing. */
11560 return true1;
11561 }
11562 }
11563
11564 /* Continue traversing. */
11565 return false0;
11566}
11567
11568/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11569* This works on any proto_tree, primed or unprimed, but actually searches
11570* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11571* The caller does need to free the returned GPtrArray with
11572* g_ptr_array_free(<array>, true).
11573*/
11574GPtrArray *
11575proto_find_finfo(proto_tree *tree, const int id)
11576{
11577 ffdata_t ffdata;
11578
11579 ffdata.array = g_ptr_array_new();
11580 ffdata.id = id;
11581
11582 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11583
11584 return ffdata.array;
11585}
11586
11587/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11588* This works on any proto_tree, primed or unprimed, but actually searches
11589* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11590* The caller does need to free the returned GPtrArray with
11591* g_ptr_array_free(<array>, true).
11592*/
11593GPtrArray *
11594proto_find_first_finfo(proto_tree *tree, const int id)
11595{
11596 ffdata_t ffdata;
11597
11598 ffdata.array = g_ptr_array_new();
11599 ffdata.id = id;
11600
11601 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11602
11603 return ffdata.array;
11604}
11605
11606/* Helper function for proto_all_finfos() */
11607static bool_Bool
11608every_finfo(proto_node *node, void * data)
11609{
11610 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11611 if (fi && fi->hfinfo) {
11612 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11613 }
11614
11615 /* Don't stop traversing. */
11616 return false0;
11617}
11618
11619/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11620 * The caller does need to free the returned GPtrArray with
11621 * g_ptr_array_free(<array>, true).
11622 */
11623GPtrArray *
11624proto_all_finfos(proto_tree *tree)
11625{
11626 ffdata_t ffdata;
11627
11628 /* Pre allocate enough space to hold all fields in most cases */
11629 ffdata.array = g_ptr_array_sized_new(512);
11630 ffdata.id = 0;
11631
11632 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11633
11634 return ffdata.array;
11635}
11636
11637
11638typedef struct {
11639 unsigned offset;
11640 field_info *finfo;
11641 tvbuff_t *tvb;
11642} offset_search_t;
11643
11644static bool_Bool
11645check_for_offset(proto_node *node, void * data)
11646{
11647 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11648 offset_search_t *offsearch = (offset_search_t *)data;
11649
11650 /* !fi == the top most container node which holds nothing */
11651 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11652 if (offsearch->offset >= (unsigned) fi->start &&
11653 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11654
11655 offsearch->finfo = fi;
11656 return false0; /* keep traversing */
11657 }
11658 }
11659 return false0; /* keep traversing */
11660}
11661
11662/* Search a proto_tree backwards (from leaves to root) looking for the field
11663 * whose start/length occupies 'offset' */
11664/* XXX - I couldn't find an easy way to search backwards, so I search
11665 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11666 * the one I want to return to the user. This algorithm is inefficient
11667 * and could be re-done, but I'd have to handle all the children and
11668 * siblings of each node myself. When I have more time I'll do that.
11669 * (yeah right) */
11670field_info *
11671proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11672{
11673 offset_search_t offsearch;
11674
11675 offsearch.offset = offset;
11676 offsearch.finfo = NULL((void*)0);
11677 offsearch.tvb = tvb;
11678
11679 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11680
11681 return offsearch.finfo;
11682}
11683
11684typedef struct {
11685 int length;
11686 char *buf;
11687} decoded_data_t;
11688
11689static bool_Bool
11690check_for_undecoded(proto_node *node, void * data)
11691{
11692 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11693 decoded_data_t* decoded = (decoded_data_t*)data;
11694 int i;
11695 unsigned byte;
11696 unsigned bit;
11697
11698 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11699 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11700 byte = i / 8;
11701 bit = i % 8;
11702 decoded->buf[byte] |= (1 << bit);
11703 }
11704 }
11705
11706 return false0;
11707}
11708
11709char*
11710proto_find_undecoded_data(proto_tree *tree, unsigned length)
11711{
11712 decoded_data_t decoded;
11713 decoded.length = length;
11714 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11715
11716 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11717 return decoded.buf;
11718}
11719
11720/* Dumps the protocols in the registration database to stdout. An independent
11721 * program can take this output and format it into nice tables or HTML or
11722 * whatever.
11723 *
11724 * There is one record per line. The fields are tab-delimited.
11725 *
11726 * Field 1 = protocol name
11727 * Field 2 = protocol short name
11728 * Field 3 = protocol filter name
11729 * Field 4 = protocol enabled
11730 * Field 5 = protocol enabled by default
11731 * Field 6 = protocol can toggle
11732 */
11733void
11734proto_registrar_dump_protocols(void)
11735{
11736 protocol_t *protocol;
11737 int i;
11738 void *cookie = NULL((void*)0);
11739
11740
11741 i = proto_get_first_protocol(&cookie);
11742 while (i != -1) {
11743 protocol = find_protocol_by_id(i);
11744 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11745 protocol->name,
11746 protocol->short_name,
11747 protocol->filter_name,
11748 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11749 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11750 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11751 i = proto_get_next_protocol(&cookie);
11752 }
11753}
11754
11755/* Dumps the value_strings, extended value string headers, range_strings
11756 * or true/false strings for fields that have them.
11757 * There is one record per line. Fields are tab-delimited.
11758 * There are four types of records: Value String, Extended Value String Header,
11759 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11760 * the type of record.
11761 *
11762 * Note that a record will be generated only if the value_string,... is referenced
11763 * in a registered hfinfo entry.
11764 *
11765 *
11766 * Value Strings
11767 * -------------
11768 * Field 1 = 'V'
11769 * Field 2 = Field abbreviation to which this value string corresponds
11770 * Field 3 = Integer value
11771 * Field 4 = String
11772 *
11773 * Extended Value String Headers
11774 * -----------------------------
11775 * Field 1 = 'E'
11776 * Field 2 = Field abbreviation to which this extended value string header corresponds
11777 * Field 3 = Extended Value String "Name"
11778 * Field 4 = Number of entries in the associated value_string array
11779 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11780 *
11781 * Range Strings
11782 * -------------
11783 * Field 1 = 'R'
11784 * Field 2 = Field abbreviation to which this range string corresponds
11785 * Field 3 = Integer value: lower bound
11786 * Field 4 = Integer value: upper bound
11787 * Field 5 = String
11788 *
11789 * True/False Strings
11790 * ------------------
11791 * Field 1 = 'T'
11792 * Field 2 = Field abbreviation to which this true/false string corresponds
11793 * Field 3 = True String
11794 * Field 4 = False String
11795 */
11796void
11797proto_registrar_dump_values(void)
11798{
11799 header_field_info *hfinfo;
11800 int i, len, vi;
11801 const value_string *vals;
11802 const val64_string *vals64;
11803 const range_string *range;
11804 const true_false_string *tfs;
11805 const unit_name_string *units;
11806
11807 len = gpa_hfinfo.len;
11808 for (i = 0; i < len ; i++) {
11809 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11810 continue; /* This is a deregistered protocol or field */
11811
11812 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", 11812
, __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", 11812
, "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", 11812, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11813
11814 if (hfinfo->id == hf_text_only) {
11815 continue;
11816 }
11817
11818 /* ignore protocols */
11819 if (proto_registrar_is_protocol(i)) {
11820 continue;
11821 }
11822 /* process header fields */
11823#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11824 /*
11825 * If this field isn't at the head of the list of
11826 * fields with this name, skip this field - all
11827 * fields with the same name are really just versions
11828 * of the same field stored in different bits, and
11829 * should have the same type/radix/value list, and
11830 * just differ in their bit masks. (If a field isn't
11831 * a bitfield, but can be, say, 1 or 2 bytes long,
11832 * it can just be made FT_UINT16, meaning the
11833 * *maximum* length is 2 bytes, and be used
11834 * for all lengths.)
11835 */
11836 if (hfinfo->same_name_prev_id != -1)
11837 continue;
11838#endif
11839 vals = NULL((void*)0);
11840 vals64 = NULL((void*)0);
11841 range = NULL((void*)0);
11842 tfs = NULL((void*)0);
11843 units = NULL((void*)0);
11844
11845 if (hfinfo->strings != NULL((void*)0)) {
11846 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11847 (hfinfo->type == FT_CHAR ||
11848 hfinfo->type == FT_UINT8 ||
11849 hfinfo->type == FT_UINT16 ||
11850 hfinfo->type == FT_UINT24 ||
11851 hfinfo->type == FT_UINT32 ||
11852 hfinfo->type == FT_UINT40 ||
11853 hfinfo->type == FT_UINT48 ||
11854 hfinfo->type == FT_UINT56 ||
11855 hfinfo->type == FT_UINT64 ||
11856 hfinfo->type == FT_INT8 ||
11857 hfinfo->type == FT_INT16 ||
11858 hfinfo->type == FT_INT24 ||
11859 hfinfo->type == FT_INT32 ||
11860 hfinfo->type == FT_INT40 ||
11861 hfinfo->type == FT_INT48 ||
11862 hfinfo->type == FT_INT56 ||
11863 hfinfo->type == FT_INT64 ||
11864 hfinfo->type == FT_FLOAT ||
11865 hfinfo->type == FT_DOUBLE)) {
11866
11867 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11868 range = (const range_string *)hfinfo->strings;
11869 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11870 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11871 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11872 } else {
11873 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11874 }
11875 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11876 vals64 = (const val64_string *)hfinfo->strings;
11877 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11878 units = (const unit_name_string *)hfinfo->strings;
11879 } else {
11880 vals = (const value_string *)hfinfo->strings;
11881 }
11882 }
11883 else if (hfinfo->type == FT_BOOLEAN) {
11884 tfs = (const struct true_false_string *)hfinfo->strings;
11885 }
11886 }
11887
11888 /* Print value strings? */
11889 if (vals) {
11890 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11891 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11892 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11893 if (!val64_string_ext_validate(vse_p)) {
11894 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11894, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11895 continue;
11896 }
11897 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11898 printf("E\t%s\t%u\t%s\t%s\n",
11899 hfinfo->abbrev,
11900 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11901 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11902 val64_string_ext_match_type_str(vse_p));
11903 } else {
11904 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11905 if (!value_string_ext_validate(vse_p)) {
11906 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11906, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11907 continue;
11908 }
11909 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11910 printf("E\t%s\t%u\t%s\t%s\n",
11911 hfinfo->abbrev,
11912 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11913 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11914 value_string_ext_match_type_str(vse_p));
11915 }
11916 }
11917 vi = 0;
11918 while (vals[vi].strptr) {
11919 /* Print in the proper base */
11920 if (hfinfo->type == FT_CHAR) {
11921 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11922 printf("V\t%s\t'%c'\t%s\n",
11923 hfinfo->abbrev,
11924 vals[vi].value,
11925 vals[vi].strptr);
11926 } else {
11927 if (hfinfo->display == BASE_HEX) {
11928 printf("V\t%s\t'\\x%02x'\t%s\n",
11929 hfinfo->abbrev,
11930 vals[vi].value,
11931 vals[vi].strptr);
11932 }
11933 else {
11934 printf("V\t%s\t'\\%03o'\t%s\n",
11935 hfinfo->abbrev,
11936 vals[vi].value,
11937 vals[vi].strptr);
11938 }
11939 }
11940 } else {
11941 if (hfinfo->display == BASE_HEX) {
11942 printf("V\t%s\t0x%x\t%s\n",
11943 hfinfo->abbrev,
11944 vals[vi].value,
11945 vals[vi].strptr);
11946 }
11947 else {
11948 printf("V\t%s\t%u\t%s\n",
11949 hfinfo->abbrev,
11950 vals[vi].value,
11951 vals[vi].strptr);
11952 }
11953 }
11954 vi++;
11955 }
11956 }
11957 else if (vals64) {
11958 vi = 0;
11959 while (vals64[vi].strptr) {
11960 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11961 hfinfo->abbrev,
11962 vals64[vi].value,
11963 vals64[vi].strptr);
11964 vi++;
11965 }
11966 }
11967
11968 /* print range strings? */
11969 else if (range) {
11970 vi = 0;
11971 while (range[vi].strptr) {
11972 /* Print in the proper base */
11973 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11974 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11975 hfinfo->abbrev,
11976 range[vi].value_min,
11977 range[vi].value_max,
11978 range[vi].strptr);
11979 }
11980 else {
11981 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11982 hfinfo->abbrev,
11983 range[vi].value_min,
11984 range[vi].value_max,
11985 range[vi].strptr);
11986 }
11987 vi++;
11988 }
11989 }
11990
11991 /* Print true/false strings? */
11992 else if (tfs) {
11993 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11994 tfs->true_string, tfs->false_string);
11995 }
11996 /* Print unit strings? */
11997 else if (units) {
11998 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11999 units->singular, units->plural ? units->plural : "(no plural)");
12000 }
12001 }
12002}
12003
12004/* Prints the number of registered fields.
12005 * Useful for determining an appropriate value for
12006 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12007 *
12008 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12009 * the number of fields, true otherwise.
12010 */
12011bool_Bool
12012proto_registrar_dump_fieldcount(void)
12013{
12014 uint32_t i;
12015 header_field_info *hfinfo;
12016 uint32_t deregistered_count = 0;
12017 uint32_t same_name_count = 0;
12018 uint32_t protocol_count = 0;
12019
12020 for (i = 0; i < gpa_hfinfo.len; i++) {
12021 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12022 deregistered_count++;
12023 continue; /* This is a deregistered protocol or header field */
12024 }
12025
12026 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", 12026
, __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", 12026
, "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", 12026, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12027
12028 if (proto_registrar_is_protocol(i))
12029 protocol_count++;
12030
12031 if (hfinfo->same_name_prev_id != -1)
12032 same_name_count++;
12033 }
12034
12035 printf("There are %u header fields registered, of which:\n"
12036 "\t%u are deregistered\n"
12037 "\t%u are protocols\n"
12038 "\t%u have the same name as another field\n\n",
12039 gpa_hfinfo.len, deregistered_count, protocol_count,
12040 same_name_count);
12041
12042 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12043 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12044 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12045 "\n");
12046
12047 printf("The header field table consumes %u KiB of memory.\n",
12048 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12049 printf("The fields themselves consume %u KiB of memory.\n",
12050 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12051
12052 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12053}
12054
12055static void
12056elastic_add_base_mapping(json_dumper *dumper)
12057{
12058 json_dumper_set_member_name(dumper, "index_patterns");
12059 json_dumper_begin_array(dumper);
12060 // The index names from write_json_index() in print.c
12061 json_dumper_value_string(dumper, "packets-*");
12062 json_dumper_end_array(dumper);
12063
12064 json_dumper_set_member_name(dumper, "settings");
12065 json_dumper_begin_object(dumper);
12066 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12067 json_dumper_value_anyf(dumper, "%d", 1000000);
12068 json_dumper_end_object(dumper);
12069}
12070
12071static char*
12072ws_type_to_elastic(unsigned type)
12073{
12074 switch(type) {
12075 case FT_INT8:
12076 return "byte";
12077 case FT_UINT8:
12078 case FT_INT16:
12079 return "short";
12080 case FT_UINT16:
12081 case FT_INT32:
12082 case FT_UINT24:
12083 case FT_INT24:
12084 return "integer";
12085 case FT_FRAMENUM:
12086 case FT_UINT32:
12087 case FT_UINT40:
12088 case FT_UINT48:
12089 case FT_UINT56:
12090 case FT_INT40:
12091 case FT_INT48:
12092 case FT_INT56:
12093 case FT_INT64:
12094 return "long";
12095 case FT_UINT64:
12096 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12097 case FT_FLOAT:
12098 return "float";
12099 case FT_DOUBLE:
12100 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12101 return "double";
12102 case FT_IPv6:
12103 case FT_IPv4:
12104 return "ip";
12105 case FT_ABSOLUTE_TIME:
12106 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12107 case FT_BOOLEAN:
12108 return "boolean";
12109 default:
12110 return NULL((void*)0);
12111 }
12112}
12113
12114static char*
12115dot_to_underscore(char* str)
12116{
12117 unsigned i;
12118 for (i = 0; i < strlen(str); i++) {
12119 if (str[i] == '.')
12120 str[i] = '_';
12121 }
12122 return str;
12123}
12124
12125/* Dumps a mapping file for ElasticSearch
12126 * This is the v1 (legacy) _template API.
12127 * At some point it may need to be updated with the composable templates
12128 * introduced in Elasticsearch 7.8 (_index_template)
12129 */
12130void
12131proto_registrar_dump_elastic(const char* filter)
12132{
12133 header_field_info *hfinfo;
12134 header_field_info *parent_hfinfo;
12135 unsigned i;
12136 bool_Bool open_object = true1;
12137 const char* prev_proto = NULL((void*)0);
12138 char* str;
12139 char** protos = NULL((void*)0);
12140 char* proto;
12141 bool_Bool found;
12142 unsigned j;
12143 char* type;
12144 char* prev_item = NULL((void*)0);
12145
12146 /* We have filtering protocols. Extract them. */
12147 if (filter) {
12148 protos = g_strsplit(filter, ",", -1);
12149 }
12150
12151 /*
12152 * To help tracking down the json tree, objects have been appended with a comment:
12153 * n.label -> where n is the indentation level and label the name of the object
12154 */
12155
12156 json_dumper dumper = {
12157 .output_file = stdoutstdout,
12158 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12159 };
12160 json_dumper_begin_object(&dumper); // 1.root
12161 elastic_add_base_mapping(&dumper);
12162
12163 json_dumper_set_member_name(&dumper, "mappings");
12164 json_dumper_begin_object(&dumper); // 2.mappings
12165
12166 json_dumper_set_member_name(&dumper, "properties");
12167 json_dumper_begin_object(&dumper); // 3.properties
12168 json_dumper_set_member_name(&dumper, "timestamp");
12169 json_dumper_begin_object(&dumper); // 4.timestamp
12170 json_dumper_set_member_name(&dumper, "type");
12171 json_dumper_value_string(&dumper, "date");
12172 json_dumper_end_object(&dumper); // 4.timestamp
12173
12174 json_dumper_set_member_name(&dumper, "layers");
12175 json_dumper_begin_object(&dumper); // 4.layers
12176 json_dumper_set_member_name(&dumper, "properties");
12177 json_dumper_begin_object(&dumper); // 5.properties
12178
12179 for (i = 0; i < gpa_hfinfo.len; i++) {
12180 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12181 continue; /* This is a deregistered protocol or header field */
12182
12183 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", 12183
, __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", 12183
, "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", 12183, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12184
12185 /*
12186 * Skip the pseudo-field for "proto_tree_add_text()" since
12187 * we don't want it in the list of filterable protocols.
12188 */
12189 if (hfinfo->id == hf_text_only)
12190 continue;
12191
12192 if (!proto_registrar_is_protocol(i)) {
12193 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", 12193
, __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", 12193
, "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", 12193
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12194
12195 /*
12196 * Skip the field if filter protocols have been set and this one's
12197 * parent is not listed.
12198 */
12199 if (protos) {
12200 found = false0;
12201 j = 0;
12202 proto = protos[0];
12203 while(proto) {
12204 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12205 found = true1;
12206 break;
12207 }
12208 j++;
12209 proto = protos[j];
12210 }
12211 if (!found)
12212 continue;
12213 }
12214
12215 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12216 json_dumper_end_object(&dumper); // 7.properties
12217 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12218 open_object = true1;
12219 }
12220
12221 prev_proto = parent_hfinfo->abbrev;
12222
12223 if (open_object) {
12224 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12225 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12226 json_dumper_set_member_name(&dumper, "properties");
12227 json_dumper_begin_object(&dumper); // 7.properties
12228 open_object = false0;
12229 }
12230 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12231 type = ws_type_to_elastic(hfinfo->type);
12232 /* when type is NULL, we have the default mapping: string */
12233 if (type) {
12234 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12235 dot_to_underscore(str);
12236 if (g_strcmp0(prev_item, str)) {
12237 json_dumper_set_member_name(&dumper, str);
12238 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12239 json_dumper_set_member_name(&dumper, "type");
12240 json_dumper_value_string(&dumper, type);
12241 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12242 }
12243 g_free(prev_item);
12244 prev_item = str;
12245 }
12246 }
12247 }
12248 g_free(prev_item);
12249
12250 if (prev_proto) {
12251 json_dumper_end_object(&dumper); // 7.properties
12252 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12253 }
12254
12255 json_dumper_end_object(&dumper); // 5.properties
12256 json_dumper_end_object(&dumper); // 4.layers
12257 json_dumper_end_object(&dumper); // 3.properties
12258 json_dumper_end_object(&dumper); // 2.mappings
12259 json_dumper_end_object(&dumper); // 1.root
12260 bool_Bool ret = json_dumper_finish(&dumper);
12261 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12261, "ret"))))
;
12262
12263 g_strfreev(protos);
12264}
12265
12266/* Dumps the contents of the registration database to stdout. An independent
12267 * program can take this output and format it into nice tables or HTML or
12268 * whatever.
12269 *
12270 * There is one record per line. Each record is either a protocol or a header
12271 * field, differentiated by the first field. The fields are tab-delimited.
12272 *
12273 * Protocols
12274 * ---------
12275 * Field 1 = 'P'
12276 * Field 2 = descriptive protocol name
12277 * Field 3 = protocol abbreviation
12278 *
12279 * Header Fields
12280 * -------------
12281 * Field 1 = 'F'
12282 * Field 2 = descriptive field name
12283 * Field 3 = field abbreviation
12284 * Field 4 = type ( textual representation of the ftenum type )
12285 * Field 5 = parent protocol abbreviation
12286 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12287 * Field 7 = bitmask: format: hex: 0x....
12288 * Field 8 = blurb describing field
12289 */
12290void
12291proto_registrar_dump_fields(void)
12292{
12293 header_field_info *hfinfo, *parent_hfinfo;
12294 int i, len;
12295 const char *enum_name;
12296 const char *base_name;
12297 const char *blurb;
12298 char width[5];
12299
12300 len = gpa_hfinfo.len;
12301 for (i = 0; i < len ; i++) {
12302 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12303 continue; /* This is a deregistered protocol or header field */
12304
12305 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", 12305
, __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", 12305
, "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", 12305, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12306
12307 /*
12308 * Skip the pseudo-field for "proto_tree_add_text()" since
12309 * we don't want it in the list of filterable fields.
12310 */
12311 if (hfinfo->id == hf_text_only)
12312 continue;
12313
12314 /* format for protocols */
12315 if (proto_registrar_is_protocol(i)) {
12316 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12317 }
12318 /* format for header fields */
12319 else {
12320 /*
12321 * If this field isn't at the head of the list of
12322 * fields with this name, skip this field - all
12323 * fields with the same name are really just versions
12324 * of the same field stored in different bits, and
12325 * should have the same type/radix/value list, and
12326 * just differ in their bit masks. (If a field isn't
12327 * a bitfield, but can be, say, 1 or 2 bytes long,
12328 * it can just be made FT_UINT16, meaning the
12329 * *maximum* length is 2 bytes, and be used
12330 * for all lengths.)
12331 */
12332 if (hfinfo->same_name_prev_id != -1)
12333 continue;
12334
12335 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", 12335
, __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", 12335
, "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", 12335
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12336
12337 enum_name = ftype_name(hfinfo->type);
12338 base_name = "";
12339
12340 if (hfinfo->type == FT_CHAR ||
12341 hfinfo->type == FT_UINT8 ||
12342 hfinfo->type == FT_UINT16 ||
12343 hfinfo->type == FT_UINT24 ||
12344 hfinfo->type == FT_UINT32 ||
12345 hfinfo->type == FT_UINT40 ||
12346 hfinfo->type == FT_UINT48 ||
12347 hfinfo->type == FT_UINT56 ||
12348 hfinfo->type == FT_UINT64 ||
12349 hfinfo->type == FT_INT8 ||
12350 hfinfo->type == FT_INT16 ||
12351 hfinfo->type == FT_INT24 ||
12352 hfinfo->type == FT_INT32 ||
12353 hfinfo->type == FT_INT40 ||
12354 hfinfo->type == FT_INT48 ||
12355 hfinfo->type == FT_INT56 ||
12356 hfinfo->type == FT_INT64) {
12357
12358 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12359 case BASE_NONE:
12360 case BASE_DEC:
12361 case BASE_HEX:
12362 case BASE_OCT:
12363 case BASE_DEC_HEX:
12364 case BASE_HEX_DEC:
12365 case BASE_CUSTOM:
12366 case BASE_PT_UDP:
12367 case BASE_PT_TCP:
12368 case BASE_PT_DCCP:
12369 case BASE_PT_SCTP:
12370 case BASE_OUI:
12371 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12372 break;
12373 default:
12374 base_name = "????";
12375 break;
12376 }
12377 } else if (hfinfo->type == FT_BOOLEAN) {
12378 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12379 snprintf(width, sizeof(width), "%d", hfinfo->display);
12380 base_name = width;
12381 }
12382
12383 blurb = hfinfo->blurb;
12384 if (blurb == NULL((void*)0))
12385 blurb = "";
12386 else if (strlen(blurb) == 0)
12387 blurb = "\"\"";
12388
12389 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12390 hfinfo->name, hfinfo->abbrev, enum_name,
12391 parent_hfinfo->abbrev, base_name,
12392 hfinfo->bitmask, blurb);
12393 }
12394 }
12395}
12396
12397/* Dumps all abbreviated field and protocol completions of the given string to
12398 * stdout. An independent program may use this for command-line tab completion
12399 * of fields.
12400 */
12401bool_Bool
12402proto_registrar_dump_field_completions(const char *prefix)
12403{
12404 header_field_info *hfinfo;
12405 int i, len;
12406 size_t prefix_len;
12407 bool_Bool matched = false0;
12408
12409 prefix_len = strlen(prefix);
12410 len = gpa_hfinfo.len;
12411 for (i = 0; i < len ; i++) {
12412 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12413 continue; /* This is a deregistered protocol or header field */
12414
12415 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", 12415
, __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", 12415
, "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", 12415, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12416
12417 /*
12418 * Skip the pseudo-field for "proto_tree_add_text()" since
12419 * we don't want it in the list of filterable fields.
12420 */
12421 if (hfinfo->id == hf_text_only)
12422 continue;
12423
12424 /* format for protocols */
12425 if (proto_registrar_is_protocol(i)) {
12426 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12427 matched = true1;
12428 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12429 }
12430 }
12431 /* format for header fields */
12432 else {
12433 /*
12434 * If this field isn't at the head of the list of
12435 * fields with this name, skip this field - all
12436 * fields with the same name are really just versions
12437 * of the same field stored in different bits, and
12438 * should have the same type/radix/value list, and
12439 * just differ in their bit masks. (If a field isn't
12440 * a bitfield, but can be, say, 1 or 2 bytes long,
12441 * it can just be made FT_UINT16, meaning the
12442 * *maximum* length is 2 bytes, and be used
12443 * for all lengths.)
12444 */
12445 if (hfinfo->same_name_prev_id != -1)
12446 continue;
12447
12448 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12449 matched = true1;
12450 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12451 }
12452 }
12453 }
12454 return matched;
12455}
12456
12457/* Dumps field types and descriptive names to stdout. An independent
12458 * program can take this output and format it into nice tables or HTML or
12459 * whatever.
12460 *
12461 * There is one record per line. The fields are tab-delimited.
12462 *
12463 * Field 1 = field type name, e.g. FT_UINT8
12464 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12465 */
12466void
12467proto_registrar_dump_ftypes(void)
12468{
12469 int fte;
12470
12471 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12472 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12473 }
12474}
12475
12476/* This function indicates whether it's possible to construct a
12477 * "match selected" display filter string for the specified field,
12478 * returns an indication of whether it's possible, and, if it's
12479 * possible and "filter" is non-null, constructs the filter and
12480 * sets "*filter" to point to it.
12481 * You do not need to [g_]free() this string since it will be automatically
12482 * freed once the next packet is dissected.
12483 */
12484static bool_Bool
12485construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12486 char **filter)
12487{
12488 const header_field_info *hfinfo;
12489 int start, length, length_remaining;
12490
12491 if (!finfo)
12492 return false0;
12493
12494 hfinfo = finfo->hfinfo;
12495 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12495, "hfinfo"))))
;
12496
12497 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12498 * then "the numeric value ... is not used when preparing
12499 * filters for the field in question." If it's any other
12500 * base, we'll generate the filter normally (which will
12501 * be numeric, even though the human-readable string does
12502 * work for filtering.)
12503 *
12504 * XXX - It might be nice to use fvalue_to_string_repr() in
12505 * "proto_item_fill_label()" as well, although, there, you'd
12506 * have to deal with the base *and* with resolved values for
12507 * addresses.
12508 *
12509 * Perhaps in addition to taking the repr type (DISPLAY
12510 * or DFILTER) and the display (base), fvalue_to_string_repr()
12511 * should have the the "strings" values in the header_field_info
12512 * structure for the field as a parameter, so it can have
12513 * if the field is Boolean or an enumerated integer type,
12514 * the tables used to generate human-readable values.
12515 */
12516 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12517 const char *str = NULL((void*)0);
12518
12519 switch (hfinfo->type) {
12520
12521 case FT_INT8:
12522 case FT_INT16:
12523 case FT_INT24:
12524 case FT_INT32:
12525 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12526 break;
12527
12528 case FT_CHAR:
12529 case FT_UINT8:
12530 case FT_UINT16:
12531 case FT_UINT24:
12532 case FT_UINT32:
12533 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12534 break;
12535
12536 default:
12537 break;
12538 }
12539
12540 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12541 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12542 return true1;
12543 }
12544 }
12545
12546 switch (hfinfo->type) {
12547
12548 case FT_PROTOCOL:
12549 if (filter != NULL((void*)0))
12550 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12551 break;
12552
12553 case FT_NONE:
12554 /*
12555 * If the length is 0, just match the name of the
12556 * field.
12557 *
12558 * (Also check for negative values, just in case,
12559 * as we'll cast it to an unsigned value later.)
12560 */
12561 length = finfo->length;
12562 if (length == 0) {
12563 if (filter != NULL((void*)0))
12564 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12565 break;
12566 }
12567 if (length < 0)
12568 return false0;
12569
12570 /*
12571 * This doesn't have a value, so we'd match
12572 * on the raw bytes at this address.
12573 *
12574 * Should we be allowed to access to the raw bytes?
12575 * If "edt" is NULL, the answer is "no".
12576 */
12577 if (edt == NULL((void*)0))
12578 return false0;
12579
12580 /*
12581 * Is this field part of the raw frame tvbuff?
12582 * If not, we can't use "frame[N:M]" to match
12583 * it.
12584 *
12585 * XXX - should this be frame-relative, or
12586 * protocol-relative?
12587 *
12588 * XXX - does this fallback for non-registered
12589 * fields even make sense?
12590 */
12591 if (finfo->ds_tvb != edt->tvb)
12592 return false0; /* you lose */
12593
12594 /*
12595 * Don't go past the end of that tvbuff.
12596 */
12597 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12598 if (length > length_remaining)
12599 length = length_remaining;
12600 if (length <= 0)
12601 return false0;
12602
12603 if (filter != NULL((void*)0)) {
12604 start = finfo->start;
12605 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12606 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12607 wmem_free(NULL((void*)0), str);
12608 }
12609 break;
12610
12611 /* By default, use the fvalue's "to_string_repr" method. */
12612 default:
12613 if (filter != NULL((void*)0)) {
12614 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12615 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12616 wmem_free(NULL((void*)0), str);
12617 }
12618 break;
12619 }
12620
12621 return true1;
12622}
12623
12624/*
12625 * Returns true if we can do a "match selected" on the field, false
12626 * otherwise.
12627 */
12628bool_Bool
12629proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12630{
12631 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12632}
12633
12634/* This function attempts to construct a "match selected" display filter
12635 * string for the specified field; if it can do so, it returns a pointer
12636 * to the string, otherwise it returns NULL.
12637 *
12638 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12639 */
12640char *
12641proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12642{
12643 char *filter = NULL((void*)0);
12644
12645 if (!construct_match_selected_string(finfo, edt, &filter))
12646 {
12647 wmem_free(NULL((void*)0), filter);
12648 return NULL((void*)0);
12649 }
12650 return filter;
12651}
12652
12653/* This function is common code for all proto_tree_add_bitmask... functions.
12654 */
12655
12656static bool_Bool
12657proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12658 const int len, const int ett, int * const *fields,
12659 const int flags, bool_Bool first,
12660 bool_Bool use_parent_tree,
12661 proto_tree* tree, uint64_t value)
12662{
12663 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12664 uint64_t bitmask = 0;
12665 uint64_t tmpval;
12666 header_field_info *hf;
12667 uint32_t integer32;
12668 int bit_offset;
12669 int no_of_bits;
12670
12671 if (!*fields)
12672 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"
)
;
12673
12674 if (len < 0 || len > 8)
12675 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12676 /**
12677 * packet-frame.c uses len=0 since the value is taken from the packet
12678 * metadata, not the packet bytes. In that case, assume that all bits
12679 * in the provided value are valid.
12680 */
12681 if (len > 0) {
12682 available_bits >>= (8 - (unsigned)len)*8;
12683 }
12684
12685 if (use_parent_tree == false0)
12686 tree = proto_item_add_subtree(item, ett);
12687
12688 while (*fields) {
12689 uint64_t present_bits;
12690 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", 12690, __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", 12690
, "**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", 12690, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12691 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", 12691
, "hf->bitmask != 0", hf->abbrev))))
;
12692
12693 bitmask |= hf->bitmask;
12694
12695 /* Skip fields that aren't fully present */
12696 present_bits = available_bits & hf->bitmask;
12697 if (present_bits != hf->bitmask) {
12698 fields++;
12699 continue;
12700 }
12701
12702 switch (hf->type) {
12703 case FT_CHAR:
12704 case FT_UINT8:
12705 case FT_UINT16:
12706 case FT_UINT24:
12707 case FT_UINT32:
12708 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12709 break;
12710
12711 case FT_INT8:
12712 case FT_INT16:
12713 case FT_INT24:
12714 case FT_INT32:
12715 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12716 break;
12717
12718 case FT_UINT40:
12719 case FT_UINT48:
12720 case FT_UINT56:
12721 case FT_UINT64:
12722 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12723 break;
12724
12725 case FT_INT40:
12726 case FT_INT48:
12727 case FT_INT56:
12728 case FT_INT64:
12729 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12730 break;
12731
12732 case FT_BOOLEAN:
12733 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12734 break;
12735
12736 default:
12737 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))
12738 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))
12739 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))
12740 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))
;
12741 break;
12742 }
12743 if (flags & BMT_NO_APPEND0x01) {
12744 fields++;
12745 continue;
12746 }
12747 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12748
12749 /* XXX: README.developer and the comments have always defined
12750 * BMT_NO_INT as "only boolean flags are added to the title /
12751 * don't add non-boolean (integral) fields", but the
12752 * implementation has always added BASE_CUSTOM and fields with
12753 * value_strings, though not fields with unit_strings.
12754 * Possibly this is because some dissectors use a FT_UINT8
12755 * with a value_string for fields that should be a FT_BOOLEAN.
12756 */
12757 switch (hf->type) {
12758 case FT_CHAR:
12759 if (hf->display == BASE_CUSTOM) {
12760 char lbl[ITEM_LABEL_LENGTH240];
12761 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12762
12763 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12763, "fmtfunc"))))
;
12764 fmtfunc(lbl, (uint32_t) tmpval);
12765 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12766 hf->name, lbl);
12767 first = false0;
12768 }
12769 else if (hf->strings) {
12770 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12771 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12772 first = false0;
12773 }
12774 else if (!(flags & BMT_NO_INT0x02)) {
12775 char buf[32];
12776 const char *out;
12777
12778 if (!first) {
12779 proto_item_append_text(item, ", ");
12780 }
12781
12782 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12783 proto_item_append_text(item, "%s: %s", hf->name, out);
12784 first = false0;
12785 }
12786
12787 break;
12788
12789 case FT_UINT8:
12790 case FT_UINT16:
12791 case FT_UINT24:
12792 case FT_UINT32:
12793 if (hf->display == BASE_CUSTOM) {
12794 char lbl[ITEM_LABEL_LENGTH240];
12795 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12796
12797 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12797, "fmtfunc"))))
;
12798 fmtfunc(lbl, (uint32_t) tmpval);
12799 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12800 hf->name, lbl);
12801 first = false0;
12802 }
12803 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12804 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12805 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12806 first = false0;
12807 }
12808 else if (!(flags & BMT_NO_INT0x02)) {
12809 char buf[NUMBER_LABEL_LENGTH80];
12810 const char *out = NULL((void*)0);
12811
12812 if (!first) {
12813 proto_item_append_text(item, ", ");
12814 }
12815
12816 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12817 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12818 }
12819 if (out == NULL((void*)0)) {
12820 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12821 }
12822 proto_item_append_text(item, "%s: %s", hf->name, out);
12823 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12824 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12825 }
12826 first = false0;
12827 }
12828
12829 break;
12830
12831 case FT_INT8:
12832 case FT_INT16:
12833 case FT_INT24:
12834 case FT_INT32:
12835 integer32 = (uint32_t) tmpval;
12836 if (hf->bitmask) {
12837 no_of_bits = ws_count_ones(hf->bitmask);
12838 integer32 = ws_sign_ext32(integer32, no_of_bits);
12839 }
12840 if (hf->display == BASE_CUSTOM) {
12841 char lbl[ITEM_LABEL_LENGTH240];
12842 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12843
12844 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12844, "fmtfunc"))))
;
12845 fmtfunc(lbl, (int32_t) integer32);
12846 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12847 hf->name, lbl);
12848 first = false0;
12849 }
12850 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12851 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12852 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12853 first = false0;
12854 }
12855 else if (!(flags & BMT_NO_INT0x02)) {
12856 char buf[NUMBER_LABEL_LENGTH80];
12857 const char *out = NULL((void*)0);
12858
12859 if (!first) {
12860 proto_item_append_text(item, ", ");
12861 }
12862
12863 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12864 out = hf_try_val_to_str((int32_t) integer32, hf);
12865 }
12866 if (out == NULL((void*)0)) {
12867 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12868 }
12869 proto_item_append_text(item, "%s: %s", hf->name, out);
12870 if (hf->display & BASE_UNIT_STRING0x00001000) {
12871 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12872 }
12873 first = false0;
12874 }
12875
12876 break;
12877
12878 case FT_UINT40:
12879 case FT_UINT48:
12880 case FT_UINT56:
12881 case FT_UINT64:
12882 if (hf->display == BASE_CUSTOM) {
12883 char lbl[ITEM_LABEL_LENGTH240];
12884 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12885
12886 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12886, "fmtfunc"))))
;
12887 fmtfunc(lbl, tmpval);
12888 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12889 hf->name, lbl);
12890 first = false0;
12891 }
12892 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12893 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12894 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12895 first = false0;
12896 }
12897 else if (!(flags & BMT_NO_INT0x02)) {
12898 char buf[NUMBER_LABEL_LENGTH80];
12899 const char *out = NULL((void*)0);
12900
12901 if (!first) {
12902 proto_item_append_text(item, ", ");
12903 }
12904
12905 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12906 out = hf_try_val64_to_str(tmpval, hf);
12907 }
12908 if (out == NULL((void*)0)) {
12909 out = hfinfo_number_value_format64(hf, buf, tmpval);
12910 }
12911 proto_item_append_text(item, "%s: %s", hf->name, out);
12912 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12913 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12914 }
12915 first = false0;
12916 }
12917
12918 break;
12919
12920 case FT_INT40:
12921 case FT_INT48:
12922 case FT_INT56:
12923 case FT_INT64:
12924 if (hf->bitmask) {
12925 no_of_bits = ws_count_ones(hf->bitmask);
12926 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12927 }
12928 if (hf->display == BASE_CUSTOM) {
12929 char lbl[ITEM_LABEL_LENGTH240];
12930 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12931
12932 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12932, "fmtfunc"))))
;
12933 fmtfunc(lbl, (int64_t) tmpval);
12934 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12935 hf->name, lbl);
12936 first = false0;
12937 }
12938 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12939 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12940 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12941 first = false0;
12942 }
12943 else if (!(flags & BMT_NO_INT0x02)) {
12944 char buf[NUMBER_LABEL_LENGTH80];
12945 const char *out = NULL((void*)0);
12946
12947 if (!first) {
12948 proto_item_append_text(item, ", ");
12949 }
12950
12951 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12952 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12953 }
12954 if (out == NULL((void*)0)) {
12955 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12956 }
12957 proto_item_append_text(item, "%s: %s", hf->name, out);
12958 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12959 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12960 }
12961 first = false0;
12962 }
12963
12964 break;
12965
12966 case FT_BOOLEAN:
12967 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12968 /* If we have true/false strings, emit full - otherwise messages
12969 might look weird */
12970 const struct true_false_string *tfs =
12971 (const struct true_false_string *)hf->strings;
12972
12973 if (tmpval) {
12974 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12975 hf->name, tfs->true_string);
12976 first = false0;
12977 } else if (!(flags & BMT_NO_FALSE0x04)) {
12978 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12979 hf->name, tfs->false_string);
12980 first = false0;
12981 }
12982 } else if (hf->bitmask & value) {
12983 /* If the flag is set, show the name */
12984 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12985 first = false0;
12986 }
12987 break;
12988 default:
12989 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))
12990 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))
12991 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))
12992 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))
;
12993 break;
12994 }
12995
12996 fields++;
12997 }
12998
12999 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13000 * but then again most dissectors don't set the bitmask field for
13001 * the higher level bitmask hfi, so calculate the bitmask from the
13002 * fields present. */
13003 if (item) {
13004 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13005 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13006 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)
;
13007 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)
;
13008 }
13009 return first;
13010}
13011
13012/* This function will dissect a sequence of bytes that describe a
13013 * bitmask and supply the value of that sequence through a pointer.
13014 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13015 * to be dissected.
13016 * This field will form an expansion under which the individual fields of the
13017 * bitmask is dissected and displayed.
13018 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13019 *
13020 * fields is an array of pointers to int that lists all the fields of the
13021 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13022 * or another integer of the same type/size as hf_hdr with a mask specified.
13023 * This array is terminated by a NULL entry.
13024 *
13025 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13026 * FT_integer fields that have a value_string attached will have the
13027 * matched string displayed on the expansion line.
13028 */
13029proto_item *
13030proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13031 const unsigned offset, const int hf_hdr,
13032 const int ett, int * const *fields,
13033 const unsigned encoding, uint64_t *retval)
13034{
13035 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);
13036}
13037
13038/* This function will dissect a sequence of bytes that describe a
13039 * bitmask.
13040 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13041 * to be dissected.
13042 * This field will form an expansion under which the individual fields of the
13043 * bitmask is dissected and displayed.
13044 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13045 *
13046 * fields is an array of pointers to int that lists all the fields of the
13047 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13048 * or another integer of the same type/size as hf_hdr with a mask specified.
13049 * This array is terminated by a NULL entry.
13050 *
13051 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13052 * FT_integer fields that have a value_string attached will have the
13053 * matched string displayed on the expansion line.
13054 */
13055proto_item *
13056proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13057 const unsigned offset, const int hf_hdr,
13058 const int ett, int * const *fields,
13059 const unsigned encoding)
13060{
13061 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13062}
13063
13064/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13065 * what data is appended to the header.
13066 */
13067proto_item *
13068proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13069 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13070 uint64_t *retval)
13071{
13072 proto_item *item = NULL((void*)0);
13073 header_field_info *hf;
13074 int len;
13075 uint64_t value;
13076
13077 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", 13077, __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", 13077
, "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", 13077, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13078 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", 13078, (hf)->abbrev)))
;
13079 len = ftype_wire_size(hf->type);
13080 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13081
13082 if (parent_tree) {
13083 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13084 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13085 flags, false0, false0, NULL((void*)0), value);
13086 }
13087
13088 *retval = value;
13089 if (hf->bitmask) {
13090 /* Mask out irrelevant portions */
13091 *retval &= hf->bitmask;
13092 /* Shift bits */
13093 *retval >>= hfinfo_bitshift(hf);
13094 }
13095
13096 return item;
13097}
13098
13099/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13100 * what data is appended to the header.
13101 */
13102proto_item *
13103proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13104 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13105{
13106 proto_item *item = NULL((void*)0);
13107 header_field_info *hf;
13108 int len;
13109 uint64_t value;
13110
13111 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", 13111, __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", 13111
, "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", 13111, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13112 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", 13112, (hf)->abbrev)))
;
13113
13114 if (parent_tree) {
13115 len = ftype_wire_size(hf->type);
13116 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13117 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13118 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13119 flags, false0, false0, NULL((void*)0), value);
13120 }
13121
13122 return item;
13123}
13124
13125/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13126 can't be retrieved directly from tvb) */
13127proto_item *
13128proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13129 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13130{
13131 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13132 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13133}
13134
13135/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13136WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13137proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13138 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13139{
13140 proto_item *item = NULL((void*)0);
13141 header_field_info *hf;
13142 int len;
13143
13144 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", 13144, __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", 13144
, "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", 13144, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13145 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", 13145, (hf)->abbrev)))
;
13146 /* the proto_tree_add_uint/_uint64() calls below
13147 will fail if tvb==NULL and len!=0 */
13148 len = tvb ? ftype_wire_size(hf->type) : 0;
13149
13150 if (parent_tree) {
13151 if (len <= 4)
13152 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13153 else
13154 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13155
13156 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13157 flags, false0, false0, NULL((void*)0), value);
13158 }
13159
13160 return item;
13161}
13162
13163/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13164void
13165proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13166 const int len, int * const *fields, const unsigned encoding)
13167{
13168 uint64_t value;
13169
13170 if (tree) {
13171 value = get_uint64_value(tree, tvb, offset, len, encoding);
13172 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13173 BMT_NO_APPEND0x01, false0, true1, tree, value);
13174 }
13175}
13176
13177WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13178proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13179 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13180{
13181 uint64_t value;
13182
13183 value = get_uint64_value(tree, tvb, offset, len, encoding);
13184 if (tree) {
13185 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13186 BMT_NO_APPEND0x01, false0, true1, tree, value);
13187 }
13188 if (retval) {
13189 *retval = value;
13190 }
13191}
13192
13193WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13194proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13195 const int len, int * const *fields, const uint64_t value)
13196{
13197 if (tree) {
13198 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13199 BMT_NO_APPEND0x01, false0, true1, tree, value);
13200 }
13201}
13202
13203
13204/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13205 * This is intended to support bitmask fields whose lengths can vary, perhaps
13206 * as the underlying standard evolves over time.
13207 * With this API there is the possibility of being called to display more or
13208 * less data than the dissector was coded to support.
13209 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13210 * Thus when presented with "too much" or "too little" data, MSbits will be
13211 * ignored or MSfields sacrificed.
13212 *
13213 * Only fields for which all defined bits are available are displayed.
13214 */
13215proto_item *
13216proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13217 const unsigned offset, const unsigned len, const int hf_hdr,
13218 const int ett, int * const *fields, struct expert_field* exp,
13219 const unsigned encoding)
13220{
13221 proto_item *item = NULL((void*)0);
13222 header_field_info *hf;
13223 unsigned decodable_len;
13224 unsigned decodable_offset;
13225 uint32_t decodable_value;
13226 uint64_t value;
13227
13228 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", 13228, __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", 13228
, "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", 13228, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13229 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", 13229, (hf)->abbrev)))
;
13230
13231 decodable_offset = offset;
13232 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13233
13234 /* If we are ftype_wire_size-limited,
13235 * make sure we decode as many LSBs as possible.
13236 */
13237 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13238 decodable_offset += (len - decodable_len);
13239 }
13240
13241 if (parent_tree) {
13242 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13243 decodable_len, encoding);
13244
13245 /* The root item covers all the bytes even if we can't decode them all */
13246 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13247 decodable_value);
13248 }
13249
13250 if (decodable_len < len) {
13251 /* Dissector likely requires updating for new protocol revision */
13252 expert_add_info_format(NULL((void*)0), item, exp,
13253 "Only least-significant %d of %d bytes decoded",
13254 decodable_len, len);
13255 }
13256
13257 if (item) {
13258 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13259 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13260 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13261 }
13262
13263 return item;
13264}
13265
13266/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13267proto_item *
13268proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13269 const unsigned offset, const unsigned len,
13270 const char *name, const char *fallback,
13271 const int ett, int * const *fields,
13272 const unsigned encoding, const int flags)
13273{
13274 proto_item *item = NULL((void*)0);
13275 uint64_t value;
13276
13277 if (parent_tree) {
13278 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13279 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13280 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13281 flags, true1, false0, NULL((void*)0), value) && fallback) {
13282 /* Still at first item - append 'fallback' text if any */
13283 proto_item_append_text(item, "%s", fallback);
13284 }
13285 }
13286
13287 return item;
13288}
13289
13290proto_item *
13291proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13292 const unsigned bit_offset, const int no_of_bits,
13293 const unsigned encoding)
13294{
13295 header_field_info *hfinfo;
13296 int octet_length;
13297 int octet_offset;
13298
13299 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", 13299, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13299
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13299, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13300
13301 if (no_of_bits < 0) {
13302 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13303 }
13304 octet_length = (no_of_bits + 7) >> 3;
13305 octet_offset = bit_offset >> 3;
13306 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13307
13308 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13309 * but only after doing a bunch more work (which we can, in the common
13310 * case, shortcut here).
13311 */
13312 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13313 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", 13313
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13313, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13313, "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", 13313, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13314
13315 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13316}
13317
13318/*
13319 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13320 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13321 * Offset should be given in bits from the start of the tvb.
13322 */
13323
13324static proto_item *
13325_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13326 const unsigned bit_offset, const int no_of_bits,
13327 uint64_t *return_value, const unsigned encoding)
13328{
13329 int offset;
13330 unsigned length;
13331 uint8_t tot_no_bits;
13332 char *bf_str;
13333 char lbl_str[ITEM_LABEL_LENGTH240];
13334 uint64_t value = 0;
13335 uint8_t *bytes = NULL((void*)0);
13336 size_t bytes_length = 0;
13337
13338 proto_item *pi;
13339 header_field_info *hf_field;
13340
13341 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13342 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", 13342, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13342
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13342, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13343
13344 if (hf_field->bitmask != 0) {
13345 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)
13346 " 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)
13347 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)
;
13348 }
13349
13350 if (no_of_bits < 0) {
13351 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13352 } else if (no_of_bits == 0) {
13353 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)
13354 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)
;
13355 }
13356
13357 /* Byte align offset */
13358 offset = bit_offset>>3;
13359
13360 /*
13361 * Calculate the number of octets used to hold the bits
13362 */
13363 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13364 length = (tot_no_bits + 7) >> 3;
13365
13366 if (no_of_bits < 65) {
13367 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13368 } else if (hf_field->type != FT_BYTES) {
13369 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)
13370 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)
;
13371 return NULL((void*)0);
13372 }
13373
13374 /* Sign extend for signed types */
13375 switch (hf_field->type) {
13376 case FT_INT8:
13377 case FT_INT16:
13378 case FT_INT24:
13379 case FT_INT32:
13380 case FT_INT40:
13381 case FT_INT48:
13382 case FT_INT56:
13383 case FT_INT64:
13384 value = ws_sign_ext64(value, no_of_bits);
13385 break;
13386
13387 default:
13388 break;
13389 }
13390
13391 if (return_value) {
13392 *return_value = value;
13393 }
13394
13395 /* Coast clear. Try and fake it */
13396 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13397 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", 13397
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13397, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13397, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; 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", 13397, __func__, "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); } } }
;
13398
13399 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13400
13401 switch (hf_field->type) {
13402 case FT_BOOLEAN:
13403 /* Boolean field */
13404 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13405 "%s = %s: %s",
13406 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13407 break;
13408
13409 case FT_CHAR:
13410 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13411 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13412 break;
13413
13414 case FT_UINT8:
13415 case FT_UINT16:
13416 case FT_UINT24:
13417 case FT_UINT32:
13418 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13419 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13420 break;
13421
13422 case FT_INT8:
13423 case FT_INT16:
13424 case FT_INT24:
13425 case FT_INT32:
13426 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13427 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13428 break;
13429
13430 case FT_UINT40:
13431 case FT_UINT48:
13432 case FT_UINT56:
13433 case FT_UINT64:
13434 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13435 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13436 break;
13437
13438 case FT_INT40:
13439 case FT_INT48:
13440 case FT_INT56:
13441 case FT_INT64:
13442 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13443 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13444 break;
13445
13446 case FT_BYTES:
13447 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13448 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13449 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13450 proto_item_set_text(pi, "%s", lbl_str);
13451 return pi;
13452
13453 /* TODO: should handle FT_UINT_BYTES ? */
13454
13455 default:
13456 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))
13457 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))
13458 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))
13459 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))
;
13460 return NULL((void*)0);
13461 }
13462
13463 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13464 return pi;
13465}
13466
13467proto_item *
13468proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13469 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13470 uint64_t *return_value)
13471{
13472 proto_item *pi;
13473 int no_of_bits;
13474 int octet_offset;
13475 unsigned mask_initial_bit_offset;
13476 unsigned mask_greatest_bit_offset;
13477 unsigned octet_length;
13478 uint8_t i;
13479 char bf_str[256];
13480 char lbl_str[ITEM_LABEL_LENGTH240];
13481 uint64_t value;
13482 uint64_t composite_bitmask;
13483 uint64_t composite_bitmap;
13484
13485 header_field_info *hf_field;
13486
13487 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13488 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", 13488, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13488
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13488, "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
13489
13490 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13491 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)
13492 " 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)
13493 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)
;
13494 }
13495
13496 mask_initial_bit_offset = bit_offset % 8;
13497
13498 no_of_bits = 0;
13499 value = 0;
13500 i = 0;
13501 mask_greatest_bit_offset = 0;
13502 composite_bitmask = 0;
13503 composite_bitmap = 0;
13504
13505 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
13506 uint64_t crumb_mask, crumb_value;
13507 uint8_t crumb_end_bit_offset;
13508
13509 crumb_value = tvb_get_bits64(tvb,
13510 bit_offset + crumb_spec[i].crumb_bit_offset,
13511 crumb_spec[i].crumb_bit_length,
13512 ENC_BIG_ENDIAN0x00000000);
13513 value += crumb_value;
13514 no_of_bits += crumb_spec[i].crumb_bit_length;
13515 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", 13515
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13516
13517 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13518 octet containing the initial offset.
13519 If the mask is beyond 32 bits, then give up on bit map display.
13520 This could be improved in future, probably showing a table
13521 of 32 or 64 bits per row */
13522 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13523 crumb_end_bit_offset = mask_initial_bit_offset
13524 + crumb_spec[i].crumb_bit_offset
13525 + crumb_spec[i].crumb_bit_length;
13526 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'
13527
13528 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13529 mask_greatest_bit_offset = crumb_end_bit_offset;
13530 }
13531 /* Currently the bitmap of the crumbs are only shown if
13532 * smaller than 32 bits. Do not bother calculating the
13533 * mask if it is larger than that. */
13534 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13535 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'
13536 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13537 }
13538 }
13539 /* Shift left for the next segment */
13540 value <<= crumb_spec[++i].crumb_bit_length;
13541 }
13542
13543 /* Sign extend for signed types */
13544 switch (hf_field->type) {
13545 case FT_INT8:
13546 case FT_INT16:
13547 case FT_INT24:
13548 case FT_INT32:
13549 case FT_INT40:
13550 case FT_INT48:
13551 case FT_INT56:
13552 case FT_INT64:
13553 value = ws_sign_ext64(value, no_of_bits);
13554 break;
13555 default:
13556 break;
13557 }
13558
13559 if (return_value) {
13560 *return_value = value;
13561 }
13562
13563 /* Coast clear. Try and fake it */
13564 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13565 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", 13565
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13565, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13565, "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", 13565, __func__, "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); } } }
;
13566
13567 /* initialise the format string */
13568 bf_str[0] = '\0';
13569
13570 octet_offset = bit_offset >> 3;
13571
13572 /* Round up mask length to nearest octet */
13573 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13574 mask_greatest_bit_offset = octet_length << 3;
13575
13576 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13577 It would be a useful enhancement to eliminate this restriction. */
13578 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13579 other_decode_bitfield_value(bf_str,
13580 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13581 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13582 mask_greatest_bit_offset);
13583 } else {
13584 /* If the bitmask is too large, try to describe its contents. */
13585 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13586 }
13587
13588 switch (hf_field->type) {
13589 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13590 /* Boolean field */
13591 return proto_tree_add_boolean_format(tree, hfindex,
13592 tvb, octet_offset, octet_length, value,
13593 "%s = %s: %s",
13594 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13595 break;
13596
13597 case FT_CHAR:
13598 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13599 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13600 break;
13601
13602 case FT_UINT8:
13603 case FT_UINT16:
13604 case FT_UINT24:
13605 case FT_UINT32:
13606 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13607 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13608 break;
13609
13610 case FT_INT8:
13611 case FT_INT16:
13612 case FT_INT24:
13613 case FT_INT32:
13614 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13615 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13616 break;
13617
13618 case FT_UINT40:
13619 case FT_UINT48:
13620 case FT_UINT56:
13621 case FT_UINT64:
13622 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13623 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13624 break;
13625
13626 case FT_INT40:
13627 case FT_INT48:
13628 case FT_INT56:
13629 case FT_INT64:
13630 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13631 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13632 break;
13633
13634 default:
13635 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))
13636 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))
13637 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))
13638 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))
;
13639 return NULL((void*)0);
13640 }
13641 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13642 return pi;
13643}
13644
13645void
13646proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13647 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13648{
13649 header_field_info *hfinfo;
13650 int start = bit_offset >> 3;
13651 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13652
13653 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13654 * so that we can use the tree's memory scope in calculating the string */
13655 if (length == -1) {
13656 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13657 } else {
13658 tvb_ensure_bytes_exist(tvb, start, length);
13659 }
13660 if (!tree) return;
13661
13662 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", 13662, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13662
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13662, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13663 proto_tree_add_text_internal(tree, tvb, start, length,
13664 "%s crumb %d of %s (decoded above)",
13665 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13666 tvb_get_bits32(tvb,
13667 bit_offset,
13668 crumb_spec[crumb_index].crumb_bit_length,
13669 ENC_BIG_ENDIAN0x00000000),
13670 ENC_BIG_ENDIAN0x00000000),
13671 crumb_index,
13672 hfinfo->name);
13673}
13674
13675proto_item *
13676proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13677 const unsigned bit_offset, const int no_of_bits,
13678 uint64_t *return_value, const unsigned encoding)
13679{
13680 proto_item *item;
13681
13682 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13683 bit_offset, no_of_bits,
13684 return_value, encoding))) {
13685 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)
;
13686 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)
;
13687 }
13688 return item;
13689}
13690
13691static proto_item *
13692_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13693 tvbuff_t *tvb, const unsigned bit_offset,
13694 const int no_of_bits, void *value_ptr,
13695 const unsigned encoding, char *value_str)
13696{
13697 int offset;
13698 unsigned length;
13699 uint8_t tot_no_bits;
13700 char *str;
13701 uint64_t value = 0;
13702 header_field_info *hf_field;
13703
13704 /* We do not have to return a value, try to fake it as soon as possible */
13705 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13706 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", 13706
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13706, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13706, "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", 13706, __func__, "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); } } }
;
13707
13708 if (hf_field->bitmask != 0) {
13709 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)
13710 " 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)
13711 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)
;
13712 }
13713
13714 if (no_of_bits < 0) {
13715 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13716 } else if (no_of_bits == 0) {
13717 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)
13718 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)
;
13719 }
13720
13721 /* Byte align offset */
13722 offset = bit_offset>>3;
13723
13724 /*
13725 * Calculate the number of octets used to hold the bits
13726 */
13727 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13728 length = tot_no_bits>>3;
13729 /* If we are using part of the next octet, increase length by 1 */
13730 if (tot_no_bits & 0x07)
13731 length++;
13732
13733 if (no_of_bits < 65) {
13734 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13735 } else {
13736 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)
13737 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)
;
13738 return NULL((void*)0);
13739 }
13740
13741 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13742
13743 (void) g_strlcat(str, " = ", 256+64);
13744 (void) g_strlcat(str, hf_field->name, 256+64);
13745
13746 /*
13747 * This function does not receive an actual value but a dimensionless pointer to that value.
13748 * For this reason, the type of the header field is examined in order to determine
13749 * what kind of value we should read from this address.
13750 * The caller of this function must make sure that for the specific header field type the address of
13751 * a compatible value is provided.
13752 */
13753 switch (hf_field->type) {
13754 case FT_BOOLEAN:
13755 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13756 "%s: %s", str, value_str);
13757 break;
13758
13759 case FT_CHAR:
13760 case FT_UINT8:
13761 case FT_UINT16:
13762 case FT_UINT24:
13763 case FT_UINT32:
13764 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13765 "%s: %s", str, value_str);
13766 break;
13767
13768 case FT_UINT40:
13769 case FT_UINT48:
13770 case FT_UINT56:
13771 case FT_UINT64:
13772 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13773 "%s: %s", str, value_str);
13774 break;
13775
13776 case FT_INT8:
13777 case FT_INT16:
13778 case FT_INT24:
13779 case FT_INT32:
13780 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13781 "%s: %s", str, value_str);
13782 break;
13783
13784 case FT_INT40:
13785 case FT_INT48:
13786 case FT_INT56:
13787 case FT_INT64:
13788 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13789 "%s: %s", str, value_str);
13790 break;
13791
13792 case FT_FLOAT:
13793 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13794 "%s: %s", str, value_str);
13795 break;
13796
13797 default:
13798 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))
13799 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))
13800 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))
13801 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))
;
13802 return NULL((void*)0);
13803 }
13804}
13805
13806static proto_item *
13807proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13808 tvbuff_t *tvb, const unsigned bit_offset,
13809 const int no_of_bits, void *value_ptr,
13810 const unsigned encoding, char *value_str)
13811{
13812 proto_item *item;
13813
13814 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13815 tvb, bit_offset, no_of_bits,
13816 value_ptr, encoding, value_str))) {
13817 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)
;
13818 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)
;
13819 }
13820 return item;
13821}
13822
13823#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);
\
13824 va_start(ap, format)__builtin_va_start(ap, format); \
13825 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13826 va_end(ap)__builtin_va_end(ap);
13827
13828proto_item *
13829proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13830 tvbuff_t *tvb, const unsigned bit_offset,
13831 const int no_of_bits, uint32_t value,
13832 const unsigned encoding,
13833 const char *format, ...)
13834{
13835 va_list ap;
13836 char *dst;
13837 header_field_info *hf_field;
13838
13839 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13840
13841 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", 13841
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13841, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13841, "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", 13841, __func__, "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); } } }
;
13842
13843 switch (hf_field->type) {
13844 case FT_UINT8:
13845 case FT_UINT16:
13846 case FT_UINT24:
13847 case FT_UINT32:
13848 break;
13849
13850 default:
13851 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)
13852 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)
;
13853 return NULL((void*)0);
13854 }
13855
13856 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);
;
13857
13858 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13859}
13860
13861proto_item *
13862proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13863 tvbuff_t *tvb, const unsigned bit_offset,
13864 const int no_of_bits, uint64_t value,
13865 const unsigned encoding,
13866 const char *format, ...)
13867{
13868 va_list ap;
13869 char *dst;
13870 header_field_info *hf_field;
13871
13872 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13873
13874 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", 13874
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13874, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13874, "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", 13874, __func__, "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); } } }
;
13875
13876 switch (hf_field->type) {
13877 case FT_UINT40:
13878 case FT_UINT48:
13879 case FT_UINT56:
13880 case FT_UINT64:
13881 break;
13882
13883 default:
13884 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)
13885 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)
;
13886 return NULL((void*)0);
13887 }
13888
13889 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);
;
13890
13891 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13892}
13893
13894proto_item *
13895proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13896 tvbuff_t *tvb, const unsigned bit_offset,
13897 const int no_of_bits, float value,
13898 const unsigned encoding,
13899 const char *format, ...)
13900{
13901 va_list ap;
13902 char *dst;
13903 header_field_info *hf_field;
13904
13905 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13906
13907 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", 13907
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13907, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13907, "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", 13907, __func__, "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); } } }
;
13908
13909 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",
13909, ((hf_field))->abbrev))))
;
13910
13911 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);
;
13912
13913 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13914}
13915
13916proto_item *
13917proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13918 tvbuff_t *tvb, const unsigned bit_offset,
13919 const int no_of_bits, int32_t value,
13920 const unsigned encoding,
13921 const char *format, ...)
13922{
13923 va_list ap;
13924 char *dst;
13925 header_field_info *hf_field;
13926
13927 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13928
13929 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", 13929
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13929, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13929, "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", 13929, __func__, "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); } } }
;
13930
13931 switch (hf_field->type) {
13932 case FT_INT8:
13933 case FT_INT16:
13934 case FT_INT24:
13935 case FT_INT32:
13936 break;
13937
13938 default:
13939 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)
13940 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)
;
13941 return NULL((void*)0);
13942 }
13943
13944 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);
;
13945
13946 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13947}
13948
13949proto_item *
13950proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13951 tvbuff_t *tvb, const unsigned bit_offset,
13952 const int no_of_bits, int64_t value,
13953 const unsigned encoding,
13954 const char *format, ...)
13955{
13956 va_list ap;
13957 char *dst;
13958 header_field_info *hf_field;
13959
13960 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13961
13962 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", 13962
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13962, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13962, "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", 13962, __func__, "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); } } }
;
13963
13964 switch (hf_field->type) {
13965 case FT_INT40:
13966 case FT_INT48:
13967 case FT_INT56:
13968 case FT_INT64:
13969 break;
13970
13971 default:
13972 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)
13973 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)
;
13974 return NULL((void*)0);
13975 }
13976
13977 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);
;
13978
13979 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13980}
13981
13982proto_item *
13983proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13984 tvbuff_t *tvb, const unsigned bit_offset,
13985 const int no_of_bits, uint64_t value,
13986 const unsigned encoding,
13987 const char *format, ...)
13988{
13989 va_list ap;
13990 char *dst;
13991 header_field_info *hf_field;
13992
13993 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13994
13995 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", 13995
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13995, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13995, "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", 13995, __func__, "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); } } }
;
13996
13997 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"
, 13997, ((hf_field))->abbrev))))
;
13998
13999 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);
;
14000
14001 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14002}
14003
14004proto_item *
14005proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14006 const unsigned bit_offset, const int no_of_chars)
14007{
14008 proto_item *pi;
14009 header_field_info *hfinfo;
14010 int byte_length;
14011 int byte_offset;
14012 char *string;
14013
14014 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14015
14016 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", 14016
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14016, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14016, "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", 14016, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14017
14018 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"
, 14018, ((hfinfo))->abbrev))))
;
14019
14020 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14021 byte_offset = bit_offset >> 3;
14022
14023 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14024
14025 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14026 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14026, "byte_length >= 0"
))))
;
14027 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14028
14029 return pi;
14030}
14031
14032proto_item *
14033proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14034 const unsigned bit_offset, const int no_of_chars)
14035{
14036 proto_item *pi;
14037 header_field_info *hfinfo;
14038 int byte_length;
14039 int byte_offset;
14040 char *string;
14041
14042 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14043
14044 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", 14044
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14044, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14044, "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", 14044, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14045
14046 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"
, 14046, ((hfinfo))->abbrev))))
;
14047
14048 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14049 byte_offset = bit_offset >> 3;
14050
14051 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14052
14053 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14054 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14054, "byte_length >= 0"
))))
;
14055 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14056
14057 return pi;
14058}
14059
14060const value_string proto_checksum_vals[] = {
14061 { PROTO_CHECKSUM_E_BAD, "Bad" },
14062 { PROTO_CHECKSUM_E_GOOD, "Good" },
14063 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14064 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14065 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14066
14067 { 0, NULL((void*)0) }
14068};
14069
14070proto_item *
14071proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14072 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14073 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14074{
14075 header_field_info *hfinfo;
14076 uint32_t checksum;
14077 uint32_t len;
14078 proto_item* ti = NULL((void*)0);
14079 proto_item* ti2;
14080 bool_Bool incorrect_checksum = true1;
14081
14082 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", 14082, __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", 14082
, "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", 14082, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14083
14084 switch (hfinfo->type) {
14085 case FT_UINT8:
14086 len = 1;
14087 break;
14088 case FT_UINT16:
14089 len = 2;
14090 break;
14091 case FT_UINT24:
14092 len = 3;
14093 break;
14094 case FT_UINT32:
14095 len = 4;
14096 break;
14097 default:
14098 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)
14099 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14100 }
14101
14102 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14103 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14104 proto_item_set_generated(ti);
14105 if (hf_checksum_status != -1) {
14106 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14107 proto_item_set_generated(ti2);
14108 }
14109 return ti;
14110 }
14111
14112 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14113 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14114 proto_item_set_generated(ti);
14115 } else {
14116 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14117 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14118 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14119 if (computed_checksum == 0) {
14120 proto_item_append_text(ti, " [correct]");
14121 if (hf_checksum_status != -1) {
14122 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14123 proto_item_set_generated(ti2);
14124 }
14125 incorrect_checksum = false0;
14126 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14127 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14128 /* XXX - This can't distinguish between "shouldbe"
14129 * 0x0000 and 0xFFFF unless we know whether there
14130 * were any nonzero bits (other than the checksum).
14131 * Protocols should not use this path if they might
14132 * have an all zero packet.
14133 * Some implementations put the wrong zero; maybe
14134 * we should have a special expert info for that?
14135 */
14136 }
14137 } else {
14138 if (checksum == computed_checksum) {
14139 proto_item_append_text(ti, " [correct]");
14140 if (hf_checksum_status != -1) {
14141 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14142 proto_item_set_generated(ti2);
14143 }
14144 incorrect_checksum = false0;
14145 }
14146 }
14147
14148 if (incorrect_checksum) {
14149 if (hf_checksum_status != -1) {
14150 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14151 proto_item_set_generated(ti2);
14152 }
14153 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14154 proto_item_append_text(ti, " [incorrect]");
14155 if (bad_checksum_expert != NULL((void*)0))
14156 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14157 } else {
14158 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14159 if (bad_checksum_expert != NULL((void*)0))
14160 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);
14161 }
14162 }
14163 } else {
14164 if (hf_checksum_status != -1) {
14165 proto_item_append_text(ti, " [unverified]");
14166 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14167 proto_item_set_generated(ti2);
14168 }
14169 }
14170 }
14171
14172 return ti;
14173}
14174
14175proto_item *
14176proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14177 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14178 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14179{
14180 header_field_info *hfinfo;
14181 uint8_t *checksum = NULL((void*)0);
14182 proto_item* ti = NULL((void*)0);
14183 proto_item* ti2;
14184 bool_Bool incorrect_checksum = true1;
14185
14186 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", 14186, __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", 14186
, "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", 14186, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14187
14188 if (hfinfo->type != FT_BYTES) {
14189 REPORT_DISSECTOR_BUG("field %s is not of type FT_BYTES",proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
14190 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14191 }
14192
14193 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14194 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14195 proto_item_set_generated(ti);
14196 if (hf_checksum_status != -1) {
14197 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14198 proto_item_set_generated(ti2);
14199 }
14200 return ti;
14201 }
14202
14203 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14204 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14205 proto_item_set_generated(ti);
14206 } else {
14207 checksum = (uint8_t*)wmem_alloc0_array(pinfo->pool, uint8_t, checksum_len)((uint8_t*)wmem_alloc0((pinfo->pool), (((((checksum_len)) <=
0) || ((size_t)sizeof(uint8_t) > (9223372036854775807L / (
size_t)((checksum_len))))) ? 0 : (sizeof(uint8_t) * ((checksum_len
))))))
;
14208 tvb_memcpy(tvb, checksum, offset, checksum_len);
14209 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14210 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14211 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14212 if (computed_checksum == 0) {
14213 proto_item_append_text(ti, " [correct]");
14214 if (hf_checksum_status != -1) {
14215 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14216 proto_item_set_generated(ti2);
14217 }
14218 incorrect_checksum = false0;
14219 }
14220 } else {
14221 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14222 proto_item_append_text(ti, " [correct]");
14223 if (hf_checksum_status != -1) {
14224 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14225 proto_item_set_generated(ti2);
14226 }
14227 incorrect_checksum = false0;
14228 }
14229 }
14230
14231 if (incorrect_checksum) {
14232 if (hf_checksum_status != -1) {
14233 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14234 proto_item_set_generated(ti2);
14235 }
14236 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14237 proto_item_append_text(ti, " [incorrect]");
14238 if (bad_checksum_expert != NULL((void*)0))
14239 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14240 } else {
14241 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14242 char *computed_checksum_str = (char*)wmem_alloc0_array(pinfo->pool, char, computed_checksum_str_len)((char*)wmem_alloc0((pinfo->pool), (((((computed_checksum_str_len
)) <= 0) || ((size_t)sizeof(char) > (9223372036854775807L
/ (size_t)((computed_checksum_str_len))))) ? 0 : (sizeof(char
) * ((computed_checksum_str_len))))))
;
14243 for (size_t counter = 0; counter < checksum_len; ++counter) {
14244 snprintf(
14245 /* On ecah iteration inserts two characters */
14246 (char*)&computed_checksum_str[counter << 1],
14247 computed_checksum_str_len - (counter << 1),
14248 "%02x",
14249 computed_checksum[counter]);
14250 }
14251 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14252 if (bad_checksum_expert != NULL((void*)0))
14253 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14254 }
14255 }
14256 } else {
14257 if (hf_checksum_status != -1) {
14258 proto_item_append_text(ti, " [unverified]");
14259 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14260 proto_item_set_generated(ti2);
14261 }
14262 }
14263 }
14264
14265 return ti;
14266}
14267
14268unsigned char
14269proto_check_field_name(const char *field_name)
14270{
14271 return module_check_valid_name(field_name, false0);
14272}
14273
14274unsigned char
14275proto_check_field_name_lower(const char *field_name)
14276{
14277 return module_check_valid_name(field_name, true1);
14278}
14279
14280bool_Bool
14281tree_expanded(int tree_type)
14282{
14283 if (tree_type <= 0) {
14284 return false0;
14285 }
14286 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", 14286, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14287 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14288}
14289
14290void
14291tree_expanded_set(int tree_type, bool_Bool value)
14292{
14293 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", 14293, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14294
14295 if (value)
14296 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14297 else
14298 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14299}
14300
14301/*
14302 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14303 *
14304 * Local variables:
14305 * c-basic-offset: 8
14306 * tab-width: 8
14307 * indent-tabs-mode: t
14308 * End:
14309 *
14310 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14311 * :indentSize=8:tabSize=8:noTabs=false:
14312 */