Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/lua5.5 -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-03-100307-3576-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <[email protected]>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 unsigned cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is equal to 0 */
102#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
103 if (length == 0) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is equal to 0 */
111#define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
112 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (length == 0) { ((void)0); return ((void*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const unsigned start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 unsigned start, int *length);
300
301static proto_item *
302proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303 unsigned start, unsigned *length);
304
305static void
306proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307static void
308proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309
310static void
311proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312static void
313proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314static void
315proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316static void
317proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318static void
319proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320static void
321proto_tree_set_string(field_info *fi, const char* value);
322static void
323proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326static void
327proto_tree_set_vines(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330static void
331proto_tree_set_ether(field_info *fi, const uint8_t* value);
332static void
333proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334static void
335proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336static void
337proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338static void
339proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340static void
341proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342static void
343proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344static void
345proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346static void
347proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348static void
349proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350static void
351proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352static void
353proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354static void
355proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356static void
357proto_tree_set_boolean(field_info *fi, uint64_t value);
358static void
359proto_tree_set_float(field_info *fi, float value);
360static void
361proto_tree_set_double(field_info *fi, double value);
362static void
363proto_tree_set_uint(field_info *fi, uint32_t value);
364static void
365proto_tree_set_int(field_info *fi, int32_t value);
366static void
367proto_tree_set_uint64(field_info *fi, uint64_t value);
368static void
369proto_tree_set_int64(field_info *fi, int64_t value);
370static void
371proto_tree_set_eui64(field_info *fi, const uint64_t value);
372static void
373proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374
375/* Handle type length mismatch (now filterable) expert info */
376static int proto_type_length_mismatch;
377static expert_field ei_type_length_mismatch_error;
378static expert_field ei_type_length_mismatch_warn;
379static void register_type_length_mismatch(void);
380
381/* Handle byte array string decoding errors with expert info */
382static int proto_byte_array_string_decoding_error;
383static expert_field ei_byte_array_string_decoding_failed_error;
384static void register_byte_array_string_decodinws_error(void);
385
386/* Handle date and time string decoding errors with expert info */
387static int proto_date_time_string_decoding_error;
388static expert_field ei_date_time_string_decoding_failed_error;
389static void register_date_time_string_decodinws_error(void);
390
391/* Handle string errors expert info */
392static int proto_string_errors;
393static expert_field ei_string_trailing_characters;
394static void register_string_errors(void);
395
396static int proto_register_field_init(header_field_info *hfinfo, const int parent);
397
398/* special-case header field used within proto.c */
399static header_field_info hfi_text_only =
400 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
401int hf_text_only;
402
403/* Structure for information about a protocol */
404struct _protocol {
405 const char *name; /* long description */
406 const char *short_name; /* short description */
407 const char *filter_name; /* name of this protocol in filters */
408 GPtrArray *fields; /* fields for this protocol */
409 int proto_id; /* field ID for this protocol */
410 bool_Bool is_enabled; /* true if protocol is enabled */
411 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
412 bool_Bool can_toggle; /* true if is_enabled can be changed */
413 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
414 For dissectors that need a protocol name so they
415 can be added to a dissector table, but use the
416 parent_proto_id for things like enable/disable */
417 GList *heur_list; /* Heuristic dissectors associated with this protocol */
418};
419
420/* List of all protocols */
421static GList *protocols;
422
423/* Structure stored for deregistered g_slice */
424struct g_slice_data {
425 size_t block_size;
426 void *mem_block;
427};
428
429/* Deregistered fields */
430static GPtrArray *deregistered_fields;
431static GPtrArray *deregistered_data;
432static GPtrArray *deregistered_slice;
433
434/* indexed by prefix, contains initializers */
435static GHashTable* prefixes;
436
437/* Contains information about a field when a dissector calls
438 * proto_tree_add_item. */
439#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
440#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
441
442/* Contains the space for proto_nodes. */
443#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
444 node->first_child = NULL((void*)0); \
445 node->last_child = NULL((void*)0); \
446 node->next = NULL((void*)0);
447
448#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
449 wmem_free(pool, node)
450
451/* String space for protocol and field items for the GUI */
452#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
453 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
454 il->value_pos = 0; \
455 il->value_len = 0;
456#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
457 wmem_free(pool, il);
458
459#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 459, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 459, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
460 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
461 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 461
, __func__, "Unregistered hf! index=%d", hfindex)
; \
462 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 462, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
463 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
464 hfinfo = gpa_hfinfo.hfi[hfindex];
465
466#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
467
468/* List which stores protocols and fields that have been registered */
469typedef struct _gpa_hfinfo_t {
470 uint32_t len;
471 uint32_t allocated_len;
472 header_field_info **hfi;
473} gpa_hfinfo_t;
474
475static gpa_hfinfo_t gpa_hfinfo;
476
477/* Hash table of abbreviations and IDs */
478static wmem_map_t *gpa_name_map;
479static header_field_info *same_name_hfinfo;
480
481/* Hash table protocol aliases. const char * -> const char * */
482static GHashTable *gpa_protocol_aliases;
483
484/*
485 * We're called repeatedly with the same field name when sorting a column.
486 * Cache our last gpa_name_map hit for faster lookups.
487 */
488static char *last_field_name;
489static header_field_info *last_hfinfo;
490
491/* Points to the first element of an array of bits, indexed by
492 a subtree item type; that array element is true if subtrees of
493 an item of that type are to be expanded. */
494static uint32_t *tree_is_expanded;
495
496/* Number of elements in that array. The entry with index 0 is not used. */
497int num_tree_types = 1;
498
499/* Name hashtables for fast detection of duplicate names */
500static GHashTable* proto_names;
501static GHashTable* proto_short_names;
502static GHashTable* proto_filter_names;
503
504static const char * const reserved_filter_names[] = {
505 /* Display filter keywords. */
506 "eq",
507 "ne",
508 "all_eq",
509 "any_eq",
510 "all_ne",
511 "any_ne",
512 "gt",
513 "ge",
514 "lt",
515 "le",
516 "bitand",
517 "bitwise_and",
518 "contains",
519 "matches",
520 "not",
521 "and",
522 "or",
523 "xor",
524 "in",
525 "any",
526 "all",
527 "true",
528 "false",
529 "nan",
530 "inf",
531 "infinity",
532 NULL((void*)0)
533};
534
535static GHashTable *proto_reserved_filter_names;
536static GQueue* saved_dir_queue;
537
538static int
539proto_compare_name(const void *p1_arg, const void *p2_arg)
540{
541 const protocol_t *p1 = (const protocol_t *)p1_arg;
542 const protocol_t *p2 = (const protocol_t *)p2_arg;
543
544 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
545}
546
547static GSList *dissector_plugins;
548
549#ifdef HAVE_PLUGINS1
550void
551proto_register_plugin(const proto_plugin *plug)
552{
553 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
554}
555#else /* HAVE_PLUGINS */
556void
557proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
558{
559 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 559, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
560}
561#endif /* HAVE_PLUGINS */
562
563static void
564call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
565{
566 proto_plugin *plug = (proto_plugin *)data;
567
568 if (plug->register_protoinfo) {
569 plug->register_protoinfo();
570 }
571}
572
573static void
574call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
575{
576 proto_plugin *plug = (proto_plugin *)data;
577
578 if (plug->register_handoff) {
579 plug->register_handoff();
580 }
581}
582
583void proto_pre_init(void)
584{
585 saved_dir_queue = g_queue_new();
586
587 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
589 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
590
591 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
592 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
593 /* GHashTable has no key destructor so the cast is safe. */
594 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
595 }
596
597 gpa_hfinfo.len = 0;
598 gpa_hfinfo.allocated_len = 0;
599 gpa_hfinfo.hfi = NULL((void*)0);
600 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
601 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
602 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
603 deregistered_fields = g_ptr_array_new();
604 deregistered_data = g_ptr_array_new();
605 deregistered_slice = g_ptr_array_new();
606}
607
608/* initialize data structures and register protocols and fields */
609void
610proto_init(GSList *register_all_plugin_protocols_list,
611 GSList *register_all_plugin_handoffs_list,
612 register_entity_func register_func, register_entity_func handoff_func,
613 register_cb cb,
614 void *client_data)
615{
616 /* Initialize the ftype subsystem */
617 ftypes_initialize();
618
619 /* Initialize the address type subsystem */
620 address_types_initialize();
621
622 /* Register one special-case FT_TEXT_ONLY field for use when
623 converting wireshark to new-style proto_tree. These fields
624 are merely strings on the GUI tree; they are not filterable */
625 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
626
627 /* Register the pseudo-protocols used for exceptions. */
628 register_show_exception();
629 register_type_length_mismatch();
630 register_byte_array_string_decodinws_error();
631 register_date_time_string_decodinws_error();
632 register_string_errors();
633 ftypes_register_pseudofields();
634 col_register_protocol();
635
636 /* Have each built-in dissector register its protocols, fields,
637 dissector tables, and dissectors to be called through a
638 handle, and do whatever one-time initialization it needs to
639 do. */
640 if (register_func != NULL((void*)0))
641 register_func(cb, client_data);
642
643 /* Now call the registration routines for all epan plugins. */
644 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
645 ((void (*)(register_cb, void *))l->data)(cb, client_data);
646 }
647
648 /* Now call the registration routines for all dissector plugins. */
649 if (cb)
650 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
651 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
652
653 /* Now call the "handoff registration" routines of all built-in
654 dissectors; those routines register the dissector in other
655 dissectors' handoff tables, and fetch any dissector handles
656 they need. */
657 if (handoff_func != NULL((void*)0))
658 handoff_func(cb, client_data);
659
660 /* Now do the same with epan plugins. */
661 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
662 ((void (*)(register_cb, void *))l->data)(cb, client_data);
663 }
664
665 /* Now do the same with dissector plugins. */
666 if (cb)
667 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
668 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
669
670 /* sort the protocols by protocol name */
671 protocols = g_list_sort(protocols, proto_compare_name);
672
673 /* sort the dissector handles in dissector tables (for -G reports
674 * and -d error messages. The GUI sorts the handles itself.) */
675 packet_all_tables_sort_handles();
676
677 /* We've assigned all the subtree type values; allocate the array
678 for them, and zero it out. */
679 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
680}
681
682static void
683proto_cleanup_base(void)
684{
685 protocol_t *protocol;
686 header_field_info *hfinfo;
687
688 /* Free the abbrev/ID hash table */
689 if (gpa_name_map) {
690 // XXX - We don't have a wmem_map_destroy, but
691 // it does get cleaned up when epan scope is
692 // destroyed
693 //g_hash_table_destroy(gpa_name_map);
694 gpa_name_map = NULL((void*)0);
695 }
696 if (gpa_protocol_aliases) {
697 g_hash_table_destroy(gpa_protocol_aliases);
698 gpa_protocol_aliases = NULL((void*)0);
699 }
700 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
701 last_field_name = NULL((void*)0);
702
703 while (protocols) {
704 protocol = (protocol_t *)protocols->data;
705 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 705
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 705, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 705, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
706 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 706, "protocol->proto_id == hfinfo->id"
))))
;
707
708 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
709 if (protocol->parent_proto_id != -1) {
710 // pino protocol
711 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 711, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
712 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 712, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
713 } else {
714 if (protocol->fields) {
715 g_ptr_array_free(protocol->fields, true1);
716 }
717 g_list_free(protocol->heur_list);
718 }
719 protocols = g_list_remove(protocols, protocol);
720 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
721 }
722
723 if (proto_names) {
724 g_hash_table_destroy(proto_names);
725 proto_names = NULL((void*)0);
726 }
727
728 if (proto_short_names) {
729 g_hash_table_destroy(proto_short_names);
730 proto_short_names = NULL((void*)0);
731 }
732
733 if (proto_filter_names) {
734 g_hash_table_destroy(proto_filter_names);
735 proto_filter_names = NULL((void*)0);
736 }
737
738 if (proto_reserved_filter_names) {
739 g_hash_table_destroy(proto_reserved_filter_names);
740 proto_reserved_filter_names = NULL((void*)0);
741 }
742
743 if (gpa_hfinfo.allocated_len) {
744 gpa_hfinfo.len = 0;
745 gpa_hfinfo.allocated_len = 0;
746 g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1
)) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo
.hfi), 0)) : (g_free) (gpa_hfinfo.hfi)
;
747 gpa_hfinfo.hfi = NULL((void*)0);
748 }
749
750 if (deregistered_fields) {
751 g_ptr_array_free(deregistered_fields, true1);
752 deregistered_fields = NULL((void*)0);
753 }
754
755 if (deregistered_data) {
756 g_ptr_array_free(deregistered_data, true1);
757 deregistered_data = NULL((void*)0);
758 }
759
760 if (deregistered_slice) {
761 g_ptr_array_free(deregistered_slice, true1);
762 deregistered_slice = NULL((void*)0);
763 }
764
765 g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) -
1)) ? g_free_sized (tree_is_expanded, __builtin_object_size (
(tree_is_expanded), 0)) : (g_free) (tree_is_expanded)
;
766 tree_is_expanded = NULL((void*)0);
767
768 if (prefixes)
769 g_hash_table_destroy(prefixes);
770
771 if (saved_dir_queue != NULL((void*)0)) {
772 g_queue_clear_full(saved_dir_queue, g_free);
773 g_queue_free(saved_dir_queue);
774 saved_dir_queue = NULL((void*)0);
775 }
776}
777
778void
779proto_cleanup(void)
780{
781 proto_free_deregistered_fields();
782 proto_cleanup_base();
783
784 g_slist_free(dissector_plugins);
785 dissector_plugins = NULL((void*)0);
786}
787
788static bool_Bool
789ws_pushd(const char* dir)
790{
791 //Save the current working directory
792 const char* save_wd = get_current_working_dir();
793 if (save_wd != NULL((void*)0))
794 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
795
796 //Change to the new one
797#ifdef _WIN32
798 SetCurrentDirectory(utf_8to16(dir));
799 return true1;
800#else
801 return (chdir(dir) == 0);
802#endif
803}
804
805static bool_Bool
806ws_popd(void)
807{
808 int ret = 0;
809 char* saved_wd = g_queue_pop_head(saved_dir_queue);
810 if (saved_wd == NULL((void*)0))
811 return false0;
812
813 //Restore the previous one
814#ifdef _WIN32
815 SetCurrentDirectory(utf_8to16(saved_wd));
816#else
817 ret = chdir(saved_wd);
818#endif
819 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
820 return (ret == 0);
821}
822
823void
824proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
825{
826 if (ws_pushd(dir))
827 {
828 func(param);
829 ws_popd();
830 }
831}
832
833static bool_Bool
834// NOLINTNEXTLINE(misc-no-recursion)
835proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
836 void *data)
837{
838 proto_node *pnode = tree;
839 proto_node *child;
840 proto_node *current;
841
842 if (func(pnode, data))
843 return true1;
844
845 child = pnode->first_child;
846 while (child != NULL((void*)0)) {
847 /*
848 * The routine we call might modify the child, e.g. by
849 * freeing it, so we get the child's successor before
850 * calling that routine.
851 */
852 current = child;
853 child = current->next;
854 // We recurse here, but we're limited by prefs.gui_max_tree_depth
855 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
856 return true1;
857 }
858
859 return false0;
860}
861
862void
863proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
864 void *data)
865{
866 proto_node *node = tree;
867 proto_node *current;
868
869 if (!node)
870 return;
871
872 node = node->first_child;
873 while (node != NULL((void*)0)) {
874 current = node;
875 node = current->next;
876 func((proto_tree *)current, data);
877 }
878}
879
880static void
881free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
882{
883 GPtrArray *ptrs = (GPtrArray *)value;
884 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
885 header_field_info *hfinfo;
886
887 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 887, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 887, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 887, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
888 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
889 /* when a field is referenced by a filter this also
890 affects the refcount for the parent protocol so we need
891 to adjust the refcount for the parent as well
892 */
893 if (hfinfo->parent != -1) {
894 header_field_info *parent_hfinfo;
895 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 895
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 895, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 895, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
896 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
897 }
898 hfinfo->ref_type = HF_REF_TYPE_NONE;
899 }
900
901 g_ptr_array_free(ptrs, true1);
902}
903
904static void
905proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
906{
907 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
908
909 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
910
911 if (finfo) {
912 fvalue_free(finfo->value);
913 finfo->value = NULL((void*)0);
914 }
915}
916
917void
918proto_tree_reset(proto_tree *tree)
919{
920 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
921
922 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
923
924 /* free tree data */
925 if (tree_data->interesting_hfids) {
926 /* Free all the GPtrArray's in the interesting_hfids hash. */
927 g_hash_table_foreach(tree_data->interesting_hfids,
928 free_GPtrArray_value, NULL((void*)0));
929
930 /* And then remove all values. */
931 g_hash_table_remove_all(tree_data->interesting_hfids);
932 }
933
934 /* Reset track of the number of children */
935 tree_data->count = 0;
936
937 /* Reset our loop checks */
938 tree_data->idle_count_ds_tvb = NULL((void*)0);
939 tree_data->max_start = 0;
940 tree_data->start_idle_count = 0;
941
942 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
943}
944
945/* frees the resources that the dissection a proto_tree uses */
946void
947proto_tree_free(proto_tree *tree)
948{
949 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
950
951 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
952
953 /* free tree data */
954 if (tree_data->interesting_hfids) {
955 /* Free all the GPtrArray's in the interesting_hfids hash. */
956 g_hash_table_foreach(tree_data->interesting_hfids,
957 free_GPtrArray_value, NULL((void*)0));
958
959 /* And then destroy the hash. */
960 g_hash_table_destroy(tree_data->interesting_hfids);
961 }
962
963 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)
;
964
965 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
966}
967
968/* Is the parsing being done for a visible proto_tree or an invisible one?
969 * By setting this correctly, the proto_tree creation is sped up by not
970 * having to call vsnprintf and copy strings around.
971 */
972bool_Bool
973proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
974{
975 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
976
977 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
978
979 return old_visible;
980}
981
982void
983proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
984{
985 if (tree)
986 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
987}
988
989/* Assume dissector set only its protocol fields.
990 This function is called by dissectors and allows the speeding up of filtering
991 in wireshark; if this function returns false it is safe to reset tree to NULL
992 and thus skip calling most of the expensive proto_tree_add_...()
993 functions.
994 If the tree is visible we implicitly assume the field is referenced.
995*/
996bool_Bool
997proto_field_is_referenced(proto_tree *tree, int proto_id)
998{
999 register header_field_info *hfinfo;
1000
1001
1002 if (!tree)
1003 return false0;
1004
1005 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1006 return true1;
1007
1008 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", 1008, __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", 1008,
"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", 1008, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1009 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1010 return true1;
1011
1012 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1013 return true1;
1014
1015 return false0;
1016}
1017
1018
1019/* Finds a record in the hfinfo array by id. */
1020header_field_info *
1021proto_registrar_get_nth(unsigned hfindex)
1022{
1023 register header_field_info *hfinfo;
1024
1025 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", 1025, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1025,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1025, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1026 return hfinfo;
1027}
1028
1029
1030/* Prefix initialization
1031 * this allows for a dissector to register a display filter name prefix
1032 * so that it can delay the initialization of the hf array as long as
1033 * possible.
1034 */
1035
1036/* compute a hash for the part before the dot of a display filter */
1037static unsigned
1038prefix_hash (const void *key) {
1039 /* end the string at the dot and compute its hash */
1040 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1041 char* c = copy;
1042 unsigned tmp;
1043
1044 for (; *c; c++) {
1045 if (*c == '.') {
1046 *c = 0;
1047 break;
1048 }
1049 }
1050
1051 tmp = wmem_str_hash(copy);
1052 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1053 return tmp;
1054}
1055
1056/* are both strings equal up to the end or the dot? */
1057static gboolean
1058prefix_equal (const void *ap, const void *bp) {
1059 const char* a = (const char *)ap;
1060 const char* b = (const char *)bp;
1061
1062 do {
1063 char ac = *a++;
1064 char bc = *b++;
1065
1066 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1067
1068 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1069 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1070
1071 if (ac != bc) return FALSE(0);
1072 } while (1);
1073
1074 return FALSE(0);
1075}
1076
1077/* Register a new prefix for "delayed" initialization of field arrays */
1078void
1079proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1080 if (! prefixes ) {
1081 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1082 }
1083
1084 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1085}
1086
1087/* helper to call all prefix initializers */
1088static gboolean
1089initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1090 ((prefix_initializer_t)v)((const char *)k);
1091 return TRUE(!(0));
1092}
1093
1094/** Initialize every remaining uninitialized prefix. */
1095void
1096proto_initialize_all_prefixes(void) {
1097 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1098}
1099
1100/* Finds a record in the hfinfo array by name.
1101 * If it fails to find it in the already registered fields,
1102 * it tries to find and call an initializer in the prefixes
1103 * table and if so it looks again.
1104 */
1105
1106header_field_info *
1107proto_registrar_get_byname(const char *field_name)
1108{
1109 header_field_info *hfinfo;
1110 prefix_initializer_t pi;
1111
1112 if (!field_name)
1113 return NULL((void*)0);
1114
1115 if (g_strcmp0(field_name, last_field_name) == 0) {
1116 return last_hfinfo;
1117 }
1118
1119 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1120
1121 if (hfinfo) {
1122 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1123 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1124 last_hfinfo = hfinfo;
1125 return hfinfo;
1126 }
1127
1128 if (!prefixes)
1129 return NULL((void*)0);
1130
1131 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1132 pi(field_name);
1133 g_hash_table_remove(prefixes, field_name);
1134 } else {
1135 return NULL((void*)0);
1136 }
1137
1138 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1139
1140 if (hfinfo) {
1141 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1142 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1143 last_hfinfo = hfinfo;
1144 }
1145 return hfinfo;
1146}
1147
1148header_field_info*
1149proto_registrar_get_byalias(const char *alias_name)
1150{
1151 if (!alias_name) {
1152 return NULL((void*)0);
1153 }
1154
1155 /* Find our aliased protocol. */
1156 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1157 char *dot = strchr(an_copy, '.');
1158 if (dot) {
1159 *dot = '\0';
1160 }
1161 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1162 if (!proto_pfx) {
1163 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1164 return NULL((void*)0);
1165 }
1166
1167 /* Construct our aliased field and look it up. */
1168 GString *filter_name = g_string_new(proto_pfx);
1169 if (dot) {
1170 g_string_append_printf(filter_name, ".%s", dot+1);
1171 }
1172 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1173 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1174 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)))))
;
1175
1176 return hfinfo;
1177}
1178
1179int
1180proto_registrar_get_id_byname(const char *field_name)
1181{
1182 header_field_info *hfinfo;
1183
1184 hfinfo = proto_registrar_get_byname(field_name);
1185
1186 if (!hfinfo)
1187 return -1;
1188
1189 return hfinfo->id;
1190}
1191
1192static int
1193label_strcat_flags(const header_field_info *hfinfo)
1194{
1195 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1196 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1197
1198 return 0;
1199}
1200
1201static char *
1202format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1203 const uint8_t *bytes, unsigned length, size_t max_str_len)
1204{
1205 char *str = NULL((void*)0);
1206 const uint8_t *p;
1207 bool_Bool is_printable;
1208
1209 if (bytes) {
1210 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1211 /*
1212 * If all bytes are valid and printable UTF-8, show the
1213 * bytes as a string - in quotes to indicate that it's
1214 * a string.
1215 */
1216 if (isprint_utf8_string((const char*)bytes, length)) {
1217 str = wmem_strdup_printf(scope, "\"%.*s\"",
1218 (int)length, bytes);
1219 return str;
1220 }
1221 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1222 /*
1223 * Check whether all bytes are printable.
1224 */
1225 is_printable = true1;
1226 for (p = bytes; p < bytes+length; p++) {
1227 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1228 /* Not printable. */
1229 is_printable = false0;
1230 break;
1231 }
1232 }
1233
1234 /*
1235 * If all bytes are printable ASCII, show the bytes
1236 * as a string - in quotes to indicate that it's
1237 * a string.
1238 */
1239 if (is_printable) {
1240 str = wmem_strdup_printf(scope, "\"%.*s\"",
1241 (int)length, bytes);
1242 return str;
1243 }
1244 }
1245
1246 /*
1247 * Either it's not printable ASCII, or we don't care whether
1248 * it's printable ASCII; show it as hex bytes.
1249 */
1250 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1251 case SEP_DOT:
1252 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1253 break;
1254 case SEP_DASH:
1255 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1256 break;
1257 case SEP_COLON:
1258 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1259 break;
1260 case SEP_SPACE:
1261 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1262 break;
1263 case BASE_NONE:
1264 default:
1265 if (prefs.display_byte_fields_with_spaces) {
1266 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1267 } else {
1268 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1269 }
1270 break;
1271 }
1272 }
1273 else {
1274 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1275 str = wmem_strdup(scope, "<none>");
1276 } else {
1277 str = wmem_strdup(scope, "<MISSING>");
1278 }
1279 }
1280 return str;
1281}
1282
1283static char *
1284format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1285 const uint8_t *bytes, unsigned length)
1286{
1287 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1288}
1289
1290static void
1291ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1292{
1293 subtree_lvl *pushed_tree;
1294
1295 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"
, 1295, "ptvc->pushed_tree_max <= 256-8"))))
;
1296 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1297
1298 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1299 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1299, "pushed_tree != ((void*)0)"
))))
;
1300 ptvc->pushed_tree = pushed_tree;
1301}
1302
1303static void
1304ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1305{
1306 ptvc->pushed_tree = NULL((void*)0);
1307 ptvc->pushed_tree_max = 0;
1308 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", 1308, "ptvc->pushed_tree_index == 0"
))))
;
1309 ptvc->pushed_tree_index = 0;
1310}
1311
1312/* Allocates an initializes a ptvcursor_t with 3 variables:
1313 * proto_tree, tvbuff, and offset. */
1314ptvcursor_t *
1315ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1316{
1317 ptvcursor_t *ptvc;
1318
1319 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1320 ptvc->scope = scope;
1321 ptvc->tree = tree;
1322 ptvc->tvb = tvb;
1323 ptvc->offset = offset;
1324 ptvc->pushed_tree = NULL((void*)0);
1325 ptvc->pushed_tree_max = 0;
1326 ptvc->pushed_tree_index = 0;
1327 return ptvc;
1328}
1329
1330
1331/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1332void
1333ptvcursor_free(ptvcursor_t *ptvc)
1334{
1335 ptvcursor_free_subtree_levels(ptvc);
1336 wmem_free(ptvc->scope, ptvc);
1337}
1338
1339/* Returns tvbuff. */
1340tvbuff_t *
1341ptvcursor_tvbuff(ptvcursor_t *ptvc)
1342{
1343 return ptvc->tvb;
1344}
1345
1346/* Returns current offset. */
1347unsigned
1348ptvcursor_current_offset(ptvcursor_t *ptvc)
1349{
1350 return ptvc->offset;
1351}
1352
1353proto_tree *
1354ptvcursor_tree(ptvcursor_t *ptvc)
1355{
1356 if (!ptvc)
1357 return NULL((void*)0);
1358
1359 return ptvc->tree;
1360}
1361
1362void
1363ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1364{
1365 ptvc->tree = tree;
1366}
1367
1368/* creates a subtree, sets it as the working tree and pushes the old working tree */
1369proto_tree *
1370ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1371{
1372 subtree_lvl *subtree;
1373 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1374 ptvcursor_new_subtree_levels(ptvc);
1375
1376 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1377 subtree->tree = ptvc->tree;
1378 subtree->it= NULL((void*)0);
1379 ptvc->pushed_tree_index++;
1380 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1381}
1382
1383/* pops a subtree */
1384void
1385ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1386{
1387 subtree_lvl *subtree;
1388
1389 if (ptvc->pushed_tree_index <= 0)
1390 return;
1391
1392 ptvc->pushed_tree_index--;
1393 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1394 if (subtree->it != NULL((void*)0))
1395 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1396
1397 ptvc->tree = subtree->tree;
1398}
1399
1400/* saves the current tvb offset and the item in the current subtree level */
1401static void
1402ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1403{
1404 subtree_lvl *subtree;
1405
1406 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", 1406, "ptvc->pushed_tree_index > 0"
))))
;
1407
1408 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1409 subtree->it = it;
1410 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1411}
1412
1413/* Creates a subtree and adds it to the cursor as the working tree but does not
1414 * save the old working tree */
1415proto_tree *
1416ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1417{
1418 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1419 return ptvc->tree;
1420}
1421
1422static proto_tree *
1423ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1424{
1425 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1426 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1427 ptvcursor_subtree_set_item(ptvc, it);
1428 return ptvcursor_tree(ptvc);
1429}
1430
1431/* Add an item to the tree and create a subtree
1432 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1433 * In this case, when the subtree will be closed, the parent item length will
1434 * be equal to the advancement of the cursor since the creation of the subtree.
1435 */
1436proto_tree *
1437ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1438 const unsigned encoding, int ett_subtree)
1439{
1440 proto_item *it;
1441
1442 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1443 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1444}
1445
1446static proto_item *
1447proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1448
1449/* Add a text node to the tree and create a subtree
1450 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1451 * In this case, when the subtree will be closed, the item length will be equal
1452 * to the advancement of the cursor since the creation of the subtree.
1453 */
1454proto_tree *
1455ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1456 int ett_subtree, const char *format, ...)
1457{
1458 proto_item *pi;
1459 va_list ap;
1460 header_field_info *hfinfo;
1461 proto_tree *tree;
1462
1463 tree = ptvcursor_tree(ptvc);
1464
1465 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1466
1467 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", 1467
, __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", 1467, "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", 1467, "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", 1467, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1468
1469 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1470 ptvcursor_current_offset(ptvc), length);
1471
1472 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1472, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1473
1474 va_start(ap, format)__builtin_va_start(ap, format);
1475 proto_tree_set_representation(pi, format, ap);
1476 va_end(ap)__builtin_va_end(ap);
1477
1478 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1479}
1480
1481/* Add a text-only node, leaving it to our caller to fill the text in */
1482static proto_item *
1483proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1484{
1485 proto_item *pi;
1486
1487 if (tree == NULL((void*)0))
1488 return NULL((void*)0);
1489
1490 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1491
1492 return pi;
1493}
1494
1495/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1496proto_item *
1497proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1498 const char *format, ...)
1499{
1500 proto_item *pi;
1501 va_list ap;
1502 header_field_info *hfinfo;
1503
1504 tvb_ensure_bytes_exist(tvb, start, length);
1505
1506 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507
1508 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1509
1510 pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1513
1514 va_start(ap, format)__builtin_va_start(ap, format);
1515 proto_tree_set_representation(pi, format, ap);
1516 va_end(ap)__builtin_va_end(ap);
1517
1518 return pi;
1519}
1520
1521/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522proto_item *
1523proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1524 unsigned length, const char *format, va_list ap)
1525{
1526 proto_item *pi;
1527 header_field_info *hfinfo;
1528
1529 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 * the length to be what's in the tvbuff if length is -1, and the
1532 * minimum of length and what's in the tvbuff if not.
1533 */
1534
1535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536
1537 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1538
1539 pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1542
1543 proto_tree_set_representation(pi, format, ap);
1544
1545 return pi;
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1552{
1553 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554}
1555
1556/* Add a text-only node that creates a subtree underneath.
1557 */
1558proto_tree *
1559proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560{
1561 proto_tree *pt;
1562 proto_item *pi;
1563 va_list ap;
1564
1565 if (length == -1) {
1566 length = tvb_captured_length_remaining(tvb, start);
1567 }
1568
1569 va_start(ap, format)__builtin_va_start(ap, format);
1570 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1571 va_end(ap)__builtin_va_end(ap);
1572
1573 if (tree_item != NULL((void*)0))
1574 *tree_item = pi;
1575
1576 pt = proto_item_add_subtree(pi, idx);
1577
1578 return pt;
1579}
1580
1581/* Add a text-only node for debugging purposes. The caller doesn't need
1582 * to worry about tvbuff, start, or length. Debug message gets sent to
1583 * STDOUT, too */
1584proto_item *
1585proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1586{
1587 proto_item *pi;
1588 va_list ap;
1589
1590 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1591
1592 if (pi) {
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 proto_tree_set_representation(pi, format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 }
1597 va_start(ap, format)__builtin_va_start(ap, format);
1598 vprintf(format, ap);
1599 va_end(ap)__builtin_va_end(ap);
1600 printf("\n");
1601
1602 return pi;
1603}
1604
1605proto_item *
1606proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1607{
1608 proto_item *pi;
1609 header_field_info *hfinfo;
1610
1611 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1612
1613 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", 1613
, __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", 1613, "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", 1613, "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", 1613, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1614
1615 pi = proto_tree_add_text_node(tree, tvb, start, length);
1616
1617 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1617, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1618
1619 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1620
1621 return pi;
1622}
1623
1624proto_item *
1625proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1626{
1627 proto_item *pi;
1628 header_field_info *hfinfo;
1629 char *str;
1630
1631 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1632
1633 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", 1633
, __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", 1633, "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", 1633, "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", 1633, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1634
1635 pi = proto_tree_add_text_node(tree, tvb, start, length);
1636
1637 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1637, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1638
1639 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1640 proto_item_set_text(pi, "%s", str);
1641 wmem_free(NULL((void*)0), str);
1642
1643 return pi;
1644}
1645
1646void proto_report_dissector_bug(const char *format, ...)
1647{
1648 va_list args;
1649
1650 if (wireshark_abort_on_dissector_bug) {
1651 /*
1652 * Try to have the error message show up in the crash
1653 * information.
1654 */
1655 va_start(args, format)__builtin_va_start(args, format);
1656 ws_vadd_crash_info(format, args);
1657 va_end(args)__builtin_va_end(args);
1658
1659 /*
1660 * Print the error message.
1661 */
1662 va_start(args, format)__builtin_va_start(args, format);
1663 vfprintf(stderrstderr, format, args);
1664 va_end(args)__builtin_va_end(args);
1665 putc('\n', stderrstderr);
1666
1667 /*
1668 * And crash.
1669 */
1670 abort();
1671 } else {
1672 va_start(args, format)__builtin_va_start(args, format);
1673 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1674 va_end(args)__builtin_va_end(args);
1675 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1675
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1676 }
1677}
1678
1679/* We could probably get away with changing is_error to a minimum length value. */
1680static void
1681report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1682{
1683 if (is_error) {
1684 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1685 } else {
1686 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1687 }
1688
1689 if (is_error) {
1690 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1691 }
1692}
1693
1694static uint32_t
1695get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1696{
1697 uint32_t value;
1698 bool_Bool length_error;
1699
1700 switch (length) {
1701
1702 case 1:
1703 value = tvb_get_uint8(tvb, offset);
1704 if (encoding & ENC_ZIGBEE0x40000000) {
1705 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1706 value = 0;
1707 }
1708 }
1709 break;
1710
1711 case 2:
1712 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1713 : tvb_get_ntohs(tvb, offset);
1714 if (encoding & ENC_ZIGBEE0x40000000) {
1715 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1716 value = 0;
1717 }
1718 }
1719 break;
1720
1721 case 3:
1722 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1723 : tvb_get_ntoh24(tvb, offset);
1724 break;
1725
1726 case 4:
1727 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1728 : tvb_get_ntohl(tvb, offset);
1729 break;
1730
1731 default:
1732 if (length < 1) {
1733 length_error = true1;
1734 value = 0;
1735 } else {
1736 length_error = false0;
1737 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1738 : tvb_get_ntohl(tvb, offset);
1739 }
1740 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1741 break;
1742 }
1743 return value;
1744}
1745
1746static inline uint64_t
1747get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1748{
1749 uint64_t value;
1750
1751 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1752
1753 if (length < 1 || length > 8) {
1754 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1755 }
1756
1757 return value;
1758}
1759
1760static int32_t
1761get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1762{
1763 int32_t value;
1764 bool_Bool length_error;
1765
1766 switch (length) {
1767
1768 case 1:
1769 value = tvb_get_int8(tvb, offset);
1770 break;
1771
1772 case 2:
1773 value = encoding ? tvb_get_letohis(tvb, offset)
1774 : tvb_get_ntohis(tvb, offset);
1775 break;
1776
1777 case 3:
1778 value = encoding ? tvb_get_letohi24(tvb, offset)
1779 : tvb_get_ntohi24(tvb, offset);
1780 break;
1781
1782 case 4:
1783 value = encoding ? tvb_get_letohil(tvb, offset)
1784 : tvb_get_ntohil(tvb, offset);
1785 break;
1786
1787 default:
1788 if (length < 1) {
1789 length_error = true1;
1790 value = 0;
1791 } else {
1792 length_error = false0;
1793 value = encoding ? tvb_get_letohil(tvb, offset)
1794 : tvb_get_ntohil(tvb, offset);
1795 }
1796 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1797 break;
1798 }
1799 return value;
1800}
1801
1802/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1803 * be cast-able as a int64_t. This is weird, but what the code has always done.
1804 */
1805static inline uint64_t
1806get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1807{
1808 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1809
1810 switch (length) {
1811 case 7:
1812 value = ws_sign_ext64(value, 56);
1813 break;
1814 case 6:
1815 value = ws_sign_ext64(value, 48);
1816 break;
1817 case 5:
1818 value = ws_sign_ext64(value, 40);
1819 break;
1820 case 4:
1821 value = ws_sign_ext64(value, 32);
1822 break;
1823 case 3:
1824 value = ws_sign_ext64(value, 24);
1825 break;
1826 case 2:
1827 value = ws_sign_ext64(value, 16);
1828 break;
1829 case 1:
1830 value = ws_sign_ext64(value, 8);
1831 break;
1832 }
1833
1834 return value;
1835}
1836
1837/* For FT_STRING */
1838static inline const uint8_t *
1839get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1840 int length, int *ret_length, const unsigned encoding)
1841{
1842 if (length == -1) {
1843 length = tvb_ensure_captured_length_remaining(tvb, start);
1844 }
1845 *ret_length = length;
1846 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1847}
1848
1849/* For FT_STRINGZ */
1850static inline const uint8_t *
1851get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1852 unsigned start, int length, int *ret_length, const unsigned encoding)
1853{
1854 const uint8_t *value;
1855
1856 if (length < -1) {
1857 report_type_length_mismatch(tree, "a string", length, true1);
1858 }
1859
1860 /* XXX - Ideally, every "null-terminated string which fits into a
1861 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1862 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1863 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1864 * as unknown length as well (since there is a trailing '\0', the real
1865 * length is never zero), allowing switching to unsigned lengths.
1866 */
1867 if (length == -1) {
1868 /* This can throw an exception */
1869 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1870 } else {
1871 /* In this case, length signifies the length of the string.
1872 *
1873 * This could either be a null-padded string, which doesn't
1874 * necessarily have a '\0' at the end, or a null-terminated
1875 * string, with a trailing '\0'. (Yes, there are cases
1876 * where you have a string that's both counted and null-
1877 * terminated.)
1878 *
1879 * In the first case, we must allocate a buffer of length
1880 * "length+1", to make room for a trailing '\0'.
1881 *
1882 * In the second case, we don't assume that there is a
1883 * trailing '\0' there, as the packet might be malformed.
1884 * (XXX - should we throw an exception if there's no
1885 * trailing '\0'?) Therefore, we allocate a buffer of
1886 * length "length+1", and put in a trailing '\0', just to
1887 * be safe.
1888 *
1889 * (XXX - this would change if we made string values counted
1890 * rather than null-terminated.)
1891 */
1892 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1893 }
1894 *ret_length = length;
1895 return value;
1896}
1897
1898/* For FT_UINT_STRING */
1899static inline const uint8_t *
1900get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1901 tvbuff_t *tvb, unsigned start, int length, int *ret_length,
1902 const unsigned encoding)
1903{
1904 uint32_t n;
1905 const uint8_t *value;
1906
1907 /* I believe it's ok if this is called with a NULL tree */
1908 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1909 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1910 length += n;
1911 *ret_length = length;
1912 return value;
1913}
1914
1915/* For FT_STRINGZPAD */
1916static inline const uint8_t *
1917get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1918 int length, int *ret_length, const unsigned encoding)
1919{
1920 /*
1921 * XXX - currently, string values are null-
1922 * terminated, so a "zero-padded" string
1923 * isn't special. If we represent string
1924 * values as something that includes a counted
1925 * array of bytes, we'll need to strip the
1926 * trailing NULs.
1927 */
1928 if (length == -1) {
1929 length = tvb_ensure_captured_length_remaining(tvb, start);
1930 }
1931 *ret_length = length;
1932 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1933}
1934
1935/* For FT_STRINGZTRUNC */
1936static inline const uint8_t *
1937get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1938 int length, int *ret_length, const unsigned encoding)
1939{
1940 /*
1941 * XXX - currently, string values are null-
1942 * terminated, so a "zero-truncated" string
1943 * isn't special. If we represent string
1944 * values as something that includes a counted
1945 * array of bytes, we'll need to strip everything
1946 * starting with the terminating NUL.
1947 */
1948 if (length == -1) {
1949 length = tvb_ensure_captured_length_remaining(tvb, start);
1950 }
1951 *ret_length = length;
1952 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1953}
1954
1955/*
1956 * Deltas between the epochs for various non-UN*X time stamp formats and
1957 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1958 * stamp format.
1959 */
1960
1961/*
1962 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1963 * XXX - if it's OK if this is unsigned, can we just use
1964 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1965 */
1966#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1967
1968/*
1969 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1970 */
1971#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1972
1973/* this can be called when there is no tree, so tree may be null */
1974static void
1975get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1976 const int length, const unsigned encoding, nstime_t *time_stamp,
1977 const bool_Bool is_relative)
1978{
1979 uint32_t tmpsecs;
1980 uint64_t tmp64secs;
1981 uint64_t todusecs;
1982
1983 switch (encoding) {
1984
1985 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1986 /*
1987 * If the length is 16, 8-byte seconds, followed
1988 * by 8-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 12, 8-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * If the length is 8, 4-byte seconds, followed
1996 * by 4-byte fractional time in nanoseconds,
1997 * both big-endian.
1998 *
1999 * For absolute times, the seconds are seconds
2000 * since the UN*X epoch.
2001 */
2002 if (length == 16) {
2003 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2004 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2005 } else if (length == 12) {
2006 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2007 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2008 } else if (length == 8) {
2009 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2010 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2011 } else if (length == 4) {
2012 /*
2013 * Backwards compatibility.
2014 * ENC_TIME_SECS_NSECS is 0; using
2015 * ENC_BIG_ENDIAN by itself with a 4-byte
2016 * time-in-seconds value was done in the
2017 * past.
2018 */
2019 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2020 time_stamp->nsecs = 0;
2021 } else {
2022 time_stamp->secs = 0;
2023 time_stamp->nsecs = 0;
2024 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2025 }
2026 break;
2027
2028 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2029 /*
2030 * If the length is 16, 8-byte seconds, followed
2031 * by 8-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 12, 8-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * If the length is 8, 4-byte seconds, followed
2039 * by 4-byte fractional time in nanoseconds,
2040 * both little-endian.
2041 *
2042 * For absolute times, the seconds are seconds
2043 * since the UN*X epoch.
2044 */
2045 if (length == 16) {
2046 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2047 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2048 } else if (length == 12) {
2049 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2050 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2051 } else if (length == 8) {
2052 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2053 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2054 } else if (length == 4) {
2055 /*
2056 * Backwards compatibility.
2057 * ENC_TIME_SECS_NSECS is 0; using
2058 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2059 * time-in-seconds value was done in the
2060 * past.
2061 */
2062 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2063 time_stamp->nsecs = 0;
2064 } else {
2065 time_stamp->secs = 0;
2066 time_stamp->nsecs = 0;
2067 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2068 }
2069 break;
2070
2071 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2072 /*
2073 * NTP time stamp, big-endian.
2074 * Only supported for absolute times.
2075 */
2076 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2076, "!is_relative"
))))
;
2077
2078 /* We need a temporary variable here so the unsigned math
2079 * works correctly (for years > 2036 according to RFC 2030
2080 * chapter 3).
2081 *
2082 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2083 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2084 * If bit 0 is not set, the time is in the range 2036-2104 and
2085 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2086 */
2087 tmpsecs = tvb_get_ntohl(tvb, start);
2088 if ((tmpsecs & 0x80000000) != 0)
2089 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2090 else
2091 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2092
2093 if (length == 8) {
2094 tmp64secs = tvb_get_ntoh64(tvb, start);
2095 if (tmp64secs == 0) {
2096 //This is "NULL" time
2097 time_stamp->secs = 0;
2098 time_stamp->nsecs = 0;
2099 } else {
2100 /*
2101 * Convert 1/2^32s of a second to
2102 * nanoseconds.
2103 */
2104 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2105 }
2106 } else if (length == 4) {
2107 /*
2108 * Backwards compatibility.
2109 */
2110 if (tmpsecs == 0) {
2111 //This is "NULL" time
2112 time_stamp->secs = 0;
2113 }
2114 time_stamp->nsecs = 0;
2115 } else {
2116 time_stamp->secs = 0;
2117 time_stamp->nsecs = 0;
2118 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2119 }
2120 break;
2121
2122 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2123 /*
2124 * NTP time stamp, little-endian.
2125 * Only supported for absolute times.
2126 *
2127 * NTP doesn't use this, because it's an Internet format
2128 * and hence big-endian. Any implementation must decide
2129 * whether the NTP timestamp is a 64-bit unsigned fixed
2130 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2131 * with a 32-bit unsigned seconds field followed by a
2132 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2133 * the previous two).
2134 *
2135 * XXX: We do the latter, but no dissector uses this format.
2136 * OTOH, ERF timestamps do the former, so perhaps we
2137 * should switch the interpretation so that packet-erf.c
2138 * could use this directly?
2139 */
2140 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2140, "!is_relative"
))))
;
2141
2142 /* We need a temporary variable here so the unsigned math
2143 * works correctly (for years > 2036 according to RFC 2030
2144 * chapter 3).
2145 *
2146 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2147 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2148 * If bit 0 is not set, the time is in the range 2036-2104 and
2149 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2150 */
2151 tmpsecs = tvb_get_letohl(tvb, start);
2152 if ((tmpsecs & 0x80000000) != 0)
2153 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2154 else
2155 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2156
2157 if (length == 8) {
2158 tmp64secs = tvb_get_letoh64(tvb, start);
2159 if (tmp64secs == 0) {
2160 //This is "NULL" time
2161 time_stamp->secs = 0;
2162 time_stamp->nsecs = 0;
2163 } else {
2164 /*
2165 * Convert 1/2^32s of a second to
2166 * nanoseconds.
2167 */
2168 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2169 }
2170 } else if (length == 4) {
2171 /*
2172 * Backwards compatibility.
2173 */
2174 if (tmpsecs == 0) {
2175 //This is "NULL" time
2176 time_stamp->secs = 0;
2177 }
2178 time_stamp->nsecs = 0;
2179 } else {
2180 time_stamp->secs = 0;
2181 time_stamp->nsecs = 0;
2182 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2183 }
2184 break;
2185
2186 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2187 /*
2188 * S/3x0 and z/Architecture TOD clock time stamp,
2189 * big-endian. The epoch is January 1, 1900,
2190 * 00:00:00 (proleptic?) UTC.
2191 *
2192 * Only supported for absolute times.
2193 */
2194 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2194, "!is_relative"
))))
;
2195 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2195, "length == 8"
))))
;
2196
2197 if (length == 8) {
2198 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2199 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2200 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2201 } else {
2202 time_stamp->secs = 0;
2203 time_stamp->nsecs = 0;
2204 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2205 }
2206 break;
2207
2208 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2209 /*
2210 * S/3x0 and z/Architecture TOD clock time stamp,
2211 * little-endian. The epoch is January 1, 1900,
2212 * 00:00:00 (proleptic?) UTC.
2213 *
2214 * Only supported for absolute times.
2215 */
2216 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2216, "!is_relative"
))))
;
2217
2218 if (length == 8) {
2219 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2220 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2221 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2222 } else {
2223 time_stamp->secs = 0;
2224 time_stamp->nsecs = 0;
2225 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2226 }
2227 break;
2228
2229 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2230 /*
2231 * Time stamp using the same seconds/fraction format
2232 * as NTP, but with the origin of the time stamp being
2233 * the UNIX epoch rather than the NTP epoch; big-
2234 * endian.
2235 *
2236 * Only supported for absolute times.
2237 */
2238 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2238, "!is_relative"
))))
;
2239
2240 if (length == 8) {
2241 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2242 /*
2243 * Convert 1/2^32s of a second to nanoseconds.
2244 */
2245 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2246 } else {
2247 time_stamp->secs = 0;
2248 time_stamp->nsecs = 0;
2249 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2250 }
2251 break;
2252
2253 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2254 /*
2255 * Time stamp using the same seconds/fraction format
2256 * as NTP, but with the origin of the time stamp being
2257 * the UNIX epoch rather than the NTP epoch; little-
2258 * endian.
2259 *
2260 * Only supported for absolute times.
2261 *
2262 * The RTPS specification explicitly supports Little
2263 * Endian encoding. In one place, it states that its
2264 * Time_t representation "is the one defined by ...
2265 * RFC 1305", but in another explicitly defines it as
2266 * a struct consisting of an 32 bit unsigned seconds
2267 * field and a 32 bit unsigned fraction field, not a 64
2268 * bit fixed point, so we do that here.
2269 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2270 */
2271 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2271, "!is_relative"
))))
;
2272
2273 if (length == 8) {
2274 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2275 /*
2276 * Convert 1/2^32s of a second to nanoseconds.
2277 */
2278 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2279 } else {
2280 time_stamp->secs = 0;
2281 time_stamp->nsecs = 0;
2282 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2283 }
2284 break;
2285
2286 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2287 /*
2288 * MIP6 time stamp, big-endian.
2289 * A 64-bit unsigned integer field containing a timestamp. The
2290 * value indicates the number of seconds since January 1, 1970,
2291 * 00:00 UTC, by using a fixed point format. In this format, the
2292 * integer number of seconds is contained in the first 48 bits of
2293 * the field, and the remaining 16 bits indicate the number of
2294 * 1/65536 fractions of a second.
2295
2296 * Only supported for absolute times.
2297 */
2298 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2298, "!is_relative"
))))
;
2299
2300 if (length == 8) {
2301 /* We need a temporary variable here so the casting and fractions
2302 * of a second work correctly.
2303 */
2304 tmp64secs = tvb_get_ntoh48(tvb, start);
2305 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2306 tmpsecs <<= 16;
2307
2308 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2309 //This is "NULL" time
2310 time_stamp->secs = 0;
2311 time_stamp->nsecs = 0;
2312 } else {
2313 time_stamp->secs = (time_t)tmp64secs;
2314 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2315 }
2316 } else {
2317 time_stamp->secs = 0;
2318 time_stamp->nsecs = 0;
2319 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2320 }
2321 break;
2322
2323 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2324 /*
2325 * If the length is 16, 8-byte seconds, followed
2326 * by 8-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 12, 8-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * If the length is 8, 4-byte seconds, followed
2334 * by 4-byte fractional time in microseconds,
2335 * both big-endian.
2336 *
2337 * For absolute times, the seconds are seconds
2338 * since the UN*X epoch.
2339 */
2340 if (length == 16) {
2341 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2342 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2343 } else if (length == 12) {
2344 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2345 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2346 } else if (length == 8) {
2347 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2348 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2349 } else {
2350 time_stamp->secs = 0;
2351 time_stamp->nsecs = 0;
2352 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2353 }
2354 break;
2355
2356 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2357 /*
2358 * If the length is 16, 8-byte seconds, followed
2359 * by 8-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 12, 8-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * If the length is 8, 4-byte seconds, followed
2367 * by 4-byte fractional time in microseconds,
2368 * both little-endian.
2369 *
2370 * For absolute times, the seconds are seconds
2371 * since the UN*X epoch.
2372 */
2373 if (length == 16) {
2374 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2375 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2376 } else if (length == 12) {
2377 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2378 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2379 } else if (length == 8) {
2380 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2381 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2382 } else {
2383 time_stamp->secs = 0;
2384 time_stamp->nsecs = 0;
2385 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2386 }
2387 break;
2388
2389 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2390 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2391 /*
2392 * Seconds, 1 to 8 bytes.
2393 * For absolute times, it's seconds since the
2394 * UN*X epoch.
2395 */
2396 if (length >= 1 && length <= 8) {
2397 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2398 time_stamp->nsecs = 0;
2399 } else {
2400 time_stamp->secs = 0;
2401 time_stamp->nsecs = 0;
2402 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2403 }
2404 break;
2405
2406 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2407 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2408 /*
2409 * Milliseconds, 1 to 8 bytes.
2410 * For absolute times, it's milliseconds since the
2411 * UN*X epoch.
2412 */
2413 if (length >= 1 && length <= 8) {
2414 uint64_t msecs;
2415
2416 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2417 time_stamp->secs = (time_t)(msecs / 1000);
2418 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2419 } else {
2420 time_stamp->secs = 0;
2421 time_stamp->nsecs = 0;
2422 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2423 }
2424 break;
2425
2426 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2427 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2428 /*
2429 * Microseconds, 1 to 8 bytes.
2430 * For absolute times, it's microseconds since the
2431 * UN*X epoch.
2432 */
2433 if (length >= 1 && length <= 8) {
2434 uint64_t usecs;
2435
2436 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2437 time_stamp->secs = (time_t)(usecs / 1000000);
2438 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2439 } else {
2440 time_stamp->secs = 0;
2441 time_stamp->nsecs = 0;
2442 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2443 }
2444 break;
2445
2446 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2447 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2448 /*
2449 * nanoseconds, 1 to 8 bytes.
2450 * For absolute times, it's nanoseconds since the
2451 * UN*X epoch.
2452 */
2453
2454 if (length >= 1 && length <= 8) {
2455 uint64_t nsecs;
2456
2457 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2458 time_stamp->secs = (time_t)(nsecs / 1000000000);
2459 time_stamp->nsecs = (int)(nsecs % 1000000000);
2460 } else {
2461 time_stamp->secs = 0;
2462 time_stamp->nsecs = 0;
2463 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2464 }
2465 break;
2466
2467 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2468 /*
2469 * 1/64ths of a second since the UN*X epoch,
2470 * big-endian.
2471 *
2472 * Only supported for absolute times.
2473 */
2474 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2474, "!is_relative"
))))
;
2475
2476 if (length == 8) {
2477 /*
2478 * The upper 48 bits are seconds since the
2479 * UN*X epoch.
2480 */
2481 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2482 /*
2483 * The lower 16 bits are 1/2^16s of a second;
2484 * convert them to nanoseconds.
2485 *
2486 * XXX - this may give the impression of higher
2487 * precision than you actually get.
2488 */
2489 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2490 } else {
2491 time_stamp->secs = 0;
2492 time_stamp->nsecs = 0;
2493 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2494 }
2495 break;
2496
2497 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2498 /*
2499 * 1/64ths of a second since the UN*X epoch,
2500 * little-endian.
2501 *
2502 * Only supported for absolute times.
2503 */
2504 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2504, "!is_relative"
))))
;
2505
2506 if (length == 8) {
2507 /*
2508 * XXX - this is assuming that, if anybody
2509 * were ever to use this format - RFC 3971
2510 * doesn't, because that's an Internet
2511 * protocol, and those use network byte
2512 * order, i.e. big-endian - they'd treat it
2513 * as a 64-bit count of 1/2^16s of a second,
2514 * putting the upper 48 bits at the end.
2515 *
2516 * The lower 48 bits are seconds since the
2517 * UN*X epoch.
2518 */
2519 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2520 /*
2521 * The upper 16 bits are 1/2^16s of a second;
2522 * convert them to nanoseconds.
2523 *
2524 * XXX - this may give the impression of higher
2525 * precision than you actually get.
2526 */
2527 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2528 } else {
2529 time_stamp->secs = 0;
2530 time_stamp->nsecs = 0;
2531 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2532 }
2533 break;
2534
2535 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2536 /*
2537 * NTP time stamp, with 1-second resolution (i.e.,
2538 * seconds since the NTP epoch), big-endian.
2539 * Only supported for absolute times.
2540 */
2541 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2541, "!is_relative"
))))
;
2542
2543 if (length == 4) {
2544 /*
2545 * We need a temporary variable here so the unsigned math
2546 * works correctly (for years > 2036 according to RFC 2030
2547 * chapter 3).
2548 *
2549 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2550 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2551 * If bit 0 is not set, the time is in the range 2036-2104 and
2552 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2553 */
2554 tmpsecs = tvb_get_ntohl(tvb, start);
2555 if ((tmpsecs & 0x80000000) != 0)
2556 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2557 else
2558 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2559 time_stamp->nsecs = 0;
2560 } else {
2561 time_stamp->secs = 0;
2562 time_stamp->nsecs = 0;
2563 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2564 }
2565 break;
2566
2567 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2568 /*
2569 * NTP time stamp, with 1-second resolution (i.e.,
2570 * seconds since the NTP epoch), little-endian.
2571 * Only supported for absolute times.
2572 */
2573 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2573, "!is_relative"
))))
;
2574
2575 /*
2576 * We need a temporary variable here so the unsigned math
2577 * works correctly (for years > 2036 according to RFC 2030
2578 * chapter 3).
2579 *
2580 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2581 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2582 * If bit 0 is not set, the time is in the range 2036-2104 and
2583 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2584 */
2585 if (length == 4) {
2586 tmpsecs = tvb_get_letohl(tvb, start);
2587 if ((tmpsecs & 0x80000000) != 0)
2588 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2589 else
2590 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2591 time_stamp->nsecs = 0;
2592 } else {
2593 time_stamp->secs = 0;
2594 time_stamp->nsecs = 0;
2595 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2596 }
2597 break;
2598
2599 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2600 /*
2601 * Milliseconds, 6 to 8 bytes.
2602 * For absolute times, it's milliseconds since the
2603 * NTP epoch.
2604 *
2605 * ETSI TS 129.274 8.119 defines this as:
2606 * "a 48 bit unsigned integer in network order format
2607 * ...encoded as the number of milliseconds since
2608 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2609 * rounded value of 1000 x the value of the 64-bit
2610 * timestamp (Seconds + (Fraction / (1<<32))) defined
2611 * in clause 6 of IETF RFC 5905."
2612 *
2613 * Taken literally, the part after "i.e." would
2614 * mean that the value rolls over before reaching
2615 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2616 * when the 64 bit timestamp rolls over, and we have
2617 * to pick an NTP Era equivalence class to support
2618 * (such as 1968-01-20 to 2104-02-06).
2619 *
2620 * OTOH, the extra room might be used to store Era
2621 * information instead, in which case times until
2622 * 10819-08-03 can be represented with 6 bytes without
2623 * ambiguity. We handle both implementations, and assume
2624 * that times before 1968-01-20 are not represented.
2625 *
2626 * Only 6 bytes or more makes sense as an absolute
2627 * time. 5 bytes or fewer could express a span of
2628 * less than 35 years, either 1900-1934 or 2036-2070.
2629 */
2630 if (length >= 6 && length <= 8) {
2631 uint64_t msecs;
2632
2633 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2634 tmp64secs = (msecs / 1000);
2635 /*
2636 * Assume that times in the first half of NTP
2637 * Era 0 really represent times in the NTP
2638 * Era 1.
2639 */
2640 if (tmp64secs >= 0x80000000)
2641 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2642 else
2643 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2644 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2645 }
2646 else {
2647 time_stamp->secs = 0;
2648 time_stamp->nsecs = 0;
2649 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2650 }
2651 break;
2652
2653 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2654 /*
2655 * MP4 file time stamps, big-endian.
2656 * Only supported for absolute times.
2657 */
2658 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2658, "!is_relative"
))))
;
2659
2660 if (length == 8) {
2661 tmp64secs = tvb_get_ntoh64(tvb, start);
2662 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else if (length == 4) {
2665 tmpsecs = tvb_get_ntohl(tvb, start);
2666 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2667 time_stamp->nsecs = 0;
2668 } else {
2669 time_stamp->secs = 0;
2670 time_stamp->nsecs = 0;
2671 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2672 }
2673 break;
2674
2675 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2676 /*
2677 * Zigbee ZCL time stamps, big-endian.
2678 * Only supported for absolute times.
2679 */
2680 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2680, "!is_relative"
))))
;
2681
2682 if (length == 8) {
2683 tmp64secs = tvb_get_ntoh64(tvb, start);
2684 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2685 /* There are several other possible choices for what to do
2686 * with overflow; make sure to coordinate with whatever
2687 * packet-zbee-zcl.h does. */
2688 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2689 }
2690 time_stamp->nsecs = 0;
2691 } else if (length == 4) {
2692 tmpsecs = tvb_get_ntohl(tvb, start);
2693 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2694 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2695 }
2696 time_stamp->nsecs = 0;
2697 } else {
2698 time_stamp->secs = 0;
2699 time_stamp->nsecs = 0;
2700 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2701 }
2702 break;
2703
2704 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2705 /*
2706 * Zigbee ZCL time stamps, little-endian.
2707 * Only supported for absolute times.
2708 */
2709 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2709, "!is_relative"
))))
;
2710
2711 if (length == 8) {
2712 tmp64secs = tvb_get_letoh64(tvb, start);
2713 if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365
)*24*3600UL), (&time_stamp->secs))
) {
2714 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2715 }
2716 time_stamp->nsecs = 0;
2717 } else if (length == 4) {
2718 tmpsecs = tvb_get_letohl(tvb, start);
2719 if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)*
24*3600UL), (&time_stamp->secs))
) {
2720 time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) -
1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8
- 1))))))
;
2721 }
2722 time_stamp->nsecs = 0;
2723 } else {
2724 time_stamp->secs = 0;
2725 time_stamp->nsecs = 0;
2726 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2727 }
2728 break;
2729
2730 default:
2731 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2731))
;
2732 break;
2733 }
2734}
2735
2736static void
2737tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2738{
2739 const header_field_info *hfinfo = fi->hfinfo;
2740
2741 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2742 GPtrArray *ptrs = NULL((void*)0);
2743
2744 if (tree_data->interesting_hfids == NULL((void*)0)) {
2745 /* Initialize the hash because we now know that it is needed */
2746 tree_data->interesting_hfids =
2747 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2748 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2749 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2750 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2751 }
2752
2753 if (!ptrs) {
2754 /* First element triggers the creation of pointer array */
2755 ptrs = g_ptr_array_new();
2756 g_hash_table_insert(tree_data->interesting_hfids,
2757 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2758 }
2759
2760 g_ptr_array_add(ptrs, fi);
2761 }
2762}
2763
2764
2765/*
2766 * Validates that field length bytes are available starting from
2767 * start (pos/neg). Throws an exception if they aren't.
2768 */
2769static void
2770test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2771 unsigned start, int length, const unsigned encoding)
2772{
2773 int size = length;
2774
2775 if (!tvb)
2776 return;
2777
2778 if ((hfinfo->type == FT_STRINGZ) ||
2779 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2780 (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
))
))) {
2781 /* If we're fetching until the end of the TVB, only validate
2782 * that the offset is within range.
2783 */
2784 if (length == -1)
2785 size = 0;
2786 }
2787
2788 tvb_ensure_bytes_exist(tvb, start, size);
2789}
2790
2791static void
2792detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2793{
2794 bool_Bool found_stray_character = false0;
2795
2796 if (!string)
2797 return;
2798
2799 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2800 case ENC_ASCII0x00000000:
2801 case ENC_UTF_80x00000002:
2802 for (int i = (int)strlen(string); i < length; i++) {
2803 if (string[i] != '\0') {
2804 found_stray_character = true1;
2805 break;
2806 }
2807 }
2808 break;
2809
2810 default:
2811 break;
2812 }
2813
2814 if (found_stray_character) {
2815 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2816 }
2817}
2818
2819static void
2820free_fvalue_cb(void *data)
2821{
2822 fvalue_t *fv = (fvalue_t*)data;
2823 fvalue_free(fv);
2824}
2825
2826/* Add an item to a proto_tree, using the text label registered to that item;
2827 the item is extracted from the tvbuff handed to it. */
2828static proto_item *
2829proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2830 tvbuff_t *tvb, unsigned start, int length,
2831 unsigned encoding)
2832{
2833 proto_item *pi;
2834 uint32_t value, n;
2835 uint64_t value64;
2836 ws_in4_addr ipv4_value;
2837 float floatval;
2838 double doubleval;
2839 const char *stringval = NULL((void*)0);
2840 nstime_t time_stamp;
2841 bool_Bool length_error;
2842
2843 /* Ensure that the newly created fvalue_t is freed if we throw an
2844 * exception before adding it to the tree. (gcc creates clobbering
2845 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2846 * XXX: Move the new_field_info() call inside here?
2847 */
2848 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))
;
2849
2850 switch (new_fi->hfinfo->type) {
2851 case FT_NONE:
2852 /* no value to set for FT_NONE */
2853 break;
2854
2855 case FT_PROTOCOL:
2856 /* Set the protocol_tvb via the start offset, but include
2857 * rest of the ds_tvb so that if finfo_set_len is called
2858 * later it can be lengthened as much as possible. */
2859 proto_tree_set_protocol_tvb(new_fi, new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0), new_fi->hfinfo->name, length);
2860 break;
2861
2862 case FT_BYTES:
2863 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2864 break;
2865
2866 case FT_UINT_BYTES:
2867 n = get_uint_value(tree, tvb, start, length, encoding);
2868 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2869
2870 /* Instead of calling proto_item_set_len(), since we don't yet
2871 * have a proto_item, we set the field_info's length ourselves. */
2872 new_fi->length = n + length;
2873 break;
2874
2875 case FT_BOOLEAN:
2876 /*
2877 * Map all non-zero values to little-endian for
2878 * backwards compatibility.
2879 */
2880 if (encoding)
2881 encoding = ENC_LITTLE_ENDIAN0x80000000;
2882 proto_tree_set_boolean(new_fi,
2883 get_uint64_value(tree, tvb, start, length, encoding));
2884 break;
2885
2886 case FT_CHAR:
2887 /* XXX - make these just FT_UINT? */
2888 case FT_UINT8:
2889 case FT_UINT16:
2890 case FT_UINT24:
2891 case FT_UINT32:
2892 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2893 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2894 value = (uint32_t)value64;
2895 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2896 new_fi->flags |= FI_VARINT0x00040000;
2897 }
2898 }
2899 else {
2900 /*
2901 * Map all non-zero values to little-endian for
2902 * backwards compatibility.
2903 */
2904 if (encoding)
2905 encoding = ENC_LITTLE_ENDIAN0x80000000;
2906
2907 value = get_uint_value(tree, tvb, start, length, encoding);
2908 }
2909 proto_tree_set_uint(new_fi, value);
2910 break;
2911
2912 case FT_UINT40:
2913 case FT_UINT48:
2914 case FT_UINT56:
2915 case FT_UINT64:
2916 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2917 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2918 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2919 new_fi->flags |= FI_VARINT0x00040000;
2920 }
2921 }
2922 else {
2923 /*
2924 * Map all other non-zero values to little-endian for
2925 * backwards compatibility.
2926 */
2927 if (encoding)
2928 encoding = ENC_LITTLE_ENDIAN0x80000000;
2929
2930 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2931 }
2932 proto_tree_set_uint64(new_fi, value64);
2933 break;
2934
2935 /* XXX - make these just FT_INT? */
2936 case FT_INT8:
2937 case FT_INT16:
2938 case FT_INT24:
2939 case FT_INT32:
2940 /*
2941 * Map all non-zero values to little-endian for
2942 * backwards compatibility.
2943 */
2944 if (encoding)
2945 encoding = ENC_LITTLE_ENDIAN0x80000000;
2946 proto_tree_set_int(new_fi,
2947 get_int_value(tree, tvb, start, length, encoding));
2948 break;
2949
2950 case FT_INT40:
2951 case FT_INT48:
2952 case FT_INT56:
2953 case FT_INT64:
2954 /*
2955 * Map all non-zero values to little-endian for
2956 * backwards compatibility.
2957 */
2958 if (encoding)
2959 encoding = ENC_LITTLE_ENDIAN0x80000000;
2960 proto_tree_set_int64(new_fi,
2961 get_int64_value(tree, tvb, start, length, encoding));
2962 break;
2963
2964 case FT_IPv4:
2965 /*
2966 * Map all non-zero values to little-endian for
2967 * backwards compatibility.
2968 */
2969 if (encoding)
2970 encoding = ENC_LITTLE_ENDIAN0x80000000;
2971 if (length != FT_IPv4_LEN4) {
2972 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2973 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2974 }
2975 ipv4_value = tvb_get_ipv4(tvb, start);
2976 /*
2977 * NOTE: to support code written when
2978 * proto_tree_add_item() took a bool as its
2979 * last argument, with false meaning "big-endian"
2980 * and true meaning "little-endian", we treat any
2981 * non-zero value of "encoding" as meaning
2982 * "little-endian".
2983 */
2984 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value)(((guint32) ( (((guint32) (ipv4_value) & (guint32) 0x000000ffU
) << 24) | (((guint32) (ipv4_value) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (ipv4_value) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (ipv4_value) & (guint32) 0xff000000U
) >> 24))))
: ipv4_value);
2985 break;
2986
2987 case FT_IPXNET:
2988 if (length != FT_IPXNET_LEN4) {
2989 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2990 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2991 }
2992 proto_tree_set_ipxnet(new_fi,
2993 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2994 break;
2995
2996 case FT_IPv6:
2997 if (length != FT_IPv6_LEN16) {
2998 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2999 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3000 }
3001 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3002 break;
3003
3004 case FT_FCWWN:
3005 if (length != FT_FCWWN_LEN8) {
3006 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3007 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3008 }
3009 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3010 break;
3011
3012 case FT_AX25:
3013 if (length != 7) {
3014 length_error = length < 7 ? true1 : false0;
3015 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3016 }
3017 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3018 break;
3019
3020 case FT_VINES:
3021 if (length != VINES_ADDR_LEN6) {
3022 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3023 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3024 }
3025 proto_tree_set_vines_tvb(new_fi, tvb, start);
3026 break;
3027
3028 case FT_ETHER:
3029 if (length != FT_ETHER_LEN6) {
3030 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3031 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3032 }
3033 proto_tree_set_ether_tvb(new_fi, tvb, start);
3034 break;
3035
3036 case FT_EUI64:
3037 /*
3038 * Map all non-zero values to little-endian for
3039 * backwards compatibility.
3040 */
3041 if (encoding)
3042 encoding = ENC_LITTLE_ENDIAN0x80000000;
3043 if (length != FT_EUI64_LEN8) {
3044 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3045 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3046 }
3047 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3048 break;
3049 case FT_GUID:
3050 /*
3051 * Map all non-zero values to little-endian for
3052 * backwards compatibility.
3053 */
3054 if (encoding)
3055 encoding = ENC_LITTLE_ENDIAN0x80000000;
3056 if (length != FT_GUID_LEN16) {
3057 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3058 report_type_length_mismatch(tree, "a GUID", length, length_error);
3059 }
3060 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3061 break;
3062
3063 case FT_OID:
3064 case FT_REL_OID:
3065 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3066 break;
3067
3068 case FT_SYSTEM_ID:
3069 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3070 break;
3071
3072 case FT_FLOAT:
3073 /*
3074 * NOTE: to support code written when
3075 * proto_tree_add_item() took a bool as its
3076 * last argument, with false meaning "big-endian"
3077 * and true meaning "little-endian", we treat any
3078 * non-zero value of "encoding" as meaning
3079 * "little-endian".
3080 *
3081 * At some point in the future, we might
3082 * support non-IEEE-binary floating-point
3083 * formats in the encoding as well
3084 * (IEEE decimal, System/3x0, VAX).
3085 */
3086 if (encoding)
3087 encoding = ENC_LITTLE_ENDIAN0x80000000;
3088 if (length != 4) {
3089 length_error = length < 4 ? true1 : false0;
3090 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3091 }
3092 if (encoding)
3093 floatval = tvb_get_letohieee_float(tvb, start);
3094 else
3095 floatval = tvb_get_ntohieee_float(tvb, start);
3096 proto_tree_set_float(new_fi, floatval);
3097 break;
3098
3099 case FT_DOUBLE:
3100 /*
3101 * NOTE: to support code written when
3102 * proto_tree_add_item() took a bool as its
3103 * last argument, with false meaning "big-endian"
3104 * and true meaning "little-endian", we treat any
3105 * non-zero value of "encoding" as meaning
3106 * "little-endian".
3107 *
3108 * At some point in the future, we might
3109 * support non-IEEE-binary floating-point
3110 * formats in the encoding as well
3111 * (IEEE decimal, System/3x0, VAX).
3112 */
3113 if (encoding == true1)
3114 encoding = ENC_LITTLE_ENDIAN0x80000000;
3115 if (length != 8) {
3116 length_error = length < 8 ? true1 : false0;
3117 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3118 }
3119 if (encoding)
3120 doubleval = tvb_get_letohieee_double(tvb, start);
3121 else
3122 doubleval = tvb_get_ntohieee_double(tvb, start);
3123 proto_tree_set_double(new_fi, doubleval);
3124 break;
3125
3126 case FT_STRING:
3127 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3128 tvb, start, length, &length, encoding);
3129 proto_tree_set_string(new_fi, stringval);
3130
3131 /* Instead of calling proto_item_set_len(), since we
3132 * don't yet have a proto_item, we set the
3133 * field_info's length ourselves.
3134 *
3135 * XXX - our caller can't use that length to
3136 * advance an offset unless they arrange that
3137 * there always be a protocol tree into which
3138 * we're putting this item.
3139 */
3140 new_fi->length = length;
3141 break;
3142
3143 case FT_STRINGZ:
3144 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3145 tree, tvb, start, length, &length, encoding);
3146 proto_tree_set_string(new_fi, stringval);
3147
3148 /* Instead of calling proto_item_set_len(),
3149 * since we don't yet have a proto_item, we
3150 * set the field_info's length ourselves.
3151 *
3152 * XXX - our caller can't use that length to
3153 * advance an offset unless they arrange that
3154 * there always be a protocol tree into which
3155 * we're putting this item.
3156 */
3157 new_fi->length = length;
3158 break;
3159
3160 case FT_UINT_STRING:
3161 /*
3162 * NOTE: to support code written when
3163 * proto_tree_add_item() took a bool as its
3164 * last argument, with false meaning "big-endian"
3165 * and true meaning "little-endian", if the
3166 * encoding value is true, treat that as
3167 * ASCII with a little-endian length.
3168 *
3169 * This won't work for code that passes
3170 * arbitrary non-zero values; that code
3171 * will need to be fixed.
3172 */
3173 if (encoding == true1)
3174 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3175 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3176 tree, tvb, start, length, &length, encoding);
3177 proto_tree_set_string(new_fi, stringval);
3178
3179 /* Instead of calling proto_item_set_len(), since we
3180 * don't yet have a proto_item, we set the
3181 * field_info's length ourselves.
3182 *
3183 * XXX - our caller can't use that length to
3184 * advance an offset unless they arrange that
3185 * there always be a protocol tree into which
3186 * we're putting this item.
3187 */
3188 new_fi->length = length;
3189 break;
3190
3191 case FT_STRINGZPAD:
3192 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3193 tvb, start, length, &length, encoding);
3194 proto_tree_set_string(new_fi, stringval);
3195
3196 /* Instead of calling proto_item_set_len(), since we
3197 * don't yet have a proto_item, we set the
3198 * field_info's length ourselves.
3199 *
3200 * XXX - our caller can't use that length to
3201 * advance an offset unless they arrange that
3202 * there always be a protocol tree into which
3203 * we're putting this item.
3204 */
3205 new_fi->length = length;
3206 break;
3207
3208 case FT_STRINGZTRUNC:
3209 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3210 tvb, start, length, &length, encoding);
3211 proto_tree_set_string(new_fi, stringval);
3212
3213 /* Instead of calling proto_item_set_len(), since we
3214 * don't yet have a proto_item, we set the
3215 * field_info's length ourselves.
3216 *
3217 * XXX - our caller can't use that length to
3218 * advance an offset unless they arrange that
3219 * there always be a protocol tree into which
3220 * we're putting this item.
3221 */
3222 new_fi->length = length;
3223 break;
3224
3225 case FT_ABSOLUTE_TIME:
3226 /*
3227 * Absolute times can be in any of a number of
3228 * formats, and they can be big-endian or
3229 * little-endian.
3230 *
3231 * Historically FT_TIMEs were only timespecs;
3232 * the only question was whether they were stored
3233 * in big- or little-endian format.
3234 *
3235 * For backwards compatibility, we interpret an
3236 * encoding of 1 as meaning "little-endian timespec",
3237 * so that passing true is interpreted as that.
3238 */
3239 if (encoding == true1)
3240 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3241
3242 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3243
3244 proto_tree_set_time(new_fi, &time_stamp);
3245 break;
3246
3247 case FT_RELATIVE_TIME:
3248 /*
3249 * Relative times can be in any of a number of
3250 * formats, and they can be big-endian or
3251 * little-endian.
3252 *
3253 * Historically FT_TIMEs were only timespecs;
3254 * the only question was whether they were stored
3255 * in big- or little-endian format.
3256 *
3257 * For backwards compatibility, we interpret an
3258 * encoding of 1 as meaning "little-endian timespec",
3259 * so that passing true is interpreted as that.
3260 */
3261 if (encoding == true1)
3262 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3263
3264 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3265
3266 proto_tree_set_time(new_fi, &time_stamp);
3267 break;
3268 case FT_IEEE_11073_SFLOAT:
3269 if (encoding)
3270 encoding = ENC_LITTLE_ENDIAN0x80000000;
3271 if (length != 2) {
3272 length_error = length < 2 ? true1 : false0;
3273 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3274 }
3275
3276 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3277
3278 break;
3279 case FT_IEEE_11073_FLOAT:
3280 if (encoding)
3281 encoding = ENC_LITTLE_ENDIAN0x80000000;
3282 if (length != 4) {
3283 length_error = length < 4 ? true1 : false0;
3284 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3285 }
3286 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3287
3288 break;
3289 default:
3290 REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3291 new_fi->hfinfo->abbrev,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3292 new_fi->hfinfo->type,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3293 ftype_name(new_fi->hfinfo->type))proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
;
3294 break;
3295 }
3296 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
3297
3298 /* Don't add new node to proto_tree until now so that any exceptions
3299 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3300 /* XXX. wouldn't be better to add this item to tree, with some special
3301 * flag (FI_EXCEPTION?) to know which item caused exception? For
3302 * strings and bytes, we would have to set new_fi->value to something
3303 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3304 * could handle NULL values. */
3305 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3306 pi = proto_tree_add_node(tree, new_fi);
3307
3308 switch (new_fi->hfinfo->type) {
3309
3310 case FT_STRING:
3311 /* XXX: trailing stray character detection should be done
3312 * _before_ conversion to UTF-8, because conversion can change
3313 * the length, or else get_string_length should return a value
3314 * for the "length in bytes of the string after conversion
3315 * including internal nulls." (Noting that we do, for other
3316 * reasons, still need the "length in bytes in the field",
3317 * especially for FT_STRINGZ.)
3318 *
3319 * This is true even for ASCII and UTF-8, because
3320 * substituting REPLACEMENT CHARACTERS for illegal characters
3321 * can also do so (and for UTF-8 possibly even make the
3322 * string _shorter_).
3323 */
3324 detect_trailing_stray_characters(encoding, stringval, length, pi);
3325 break;
3326
3327 default:
3328 break;
3329 }
3330
3331 return pi;
3332}
3333
3334proto_item *
3335proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3336 const unsigned start, unsigned length,
3337 const unsigned encoding, int32_t *retval)
3338{
3339 header_field_info *hfinfo;
3340 field_info *new_fi;
3341 int32_t value;
3342
3343 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", 3343, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3343,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3343, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3344
3345 switch (hfinfo->type) {
3346 case FT_INT8:
3347 case FT_INT16:
3348 case FT_INT24:
3349 case FT_INT32:
3350 break;
3351 case FT_INT64:
3352 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)
3353 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3354 default:
3355 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)
3356 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3357 }
3358
3359 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3360 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3361 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3362 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3363 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3364 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3365 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3366
3367 if (encoding & ENC_STRING0x07000000) {
3368 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3369 }
3370 /* I believe it's ok if this is called with a NULL tree */
3371 value = get_int_value(tree, tvb, start, length, encoding);
3372
3373 if (retval) {
3374 int no_of_bits;
3375 *retval = value;
3376 if (hfinfo->bitmask) {
3377 /* Mask out irrelevant portions */
3378 *retval &= (uint32_t)(hfinfo->bitmask);
3379 /* Shift bits */
3380 *retval >>= hfinfo_bitshift(hfinfo);
3381 }
3382 no_of_bits = ws_count_ones(hfinfo->bitmask);
3383 *retval = ws_sign_ext32(*retval, no_of_bits);
3384 }
3385
3386 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3387
3388 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", 3388
, __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", 3388, "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", 3388, "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", 3388, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3389
3390 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3391
3392 proto_tree_set_int(new_fi, value);
3393
3394 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3395
3396 return proto_tree_add_node(tree, new_fi);
3397}
3398
3399proto_item *
3400proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3401 const unsigned start, unsigned length,
3402 const unsigned encoding, uint32_t *retval)
3403{
3404 header_field_info *hfinfo;
3405 field_info *new_fi;
3406 uint32_t value;
3407
3408 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", 3408, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3408,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3408, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3409
3410 switch (hfinfo->type) {
3411 case FT_CHAR:
3412 case FT_UINT8:
3413 case FT_UINT16:
3414 case FT_UINT24:
3415 case FT_UINT32:
3416 break;
3417 default:
3418 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)
3419 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)
;
3420 }
3421
3422 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3423 {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3424 if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3425 *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3426 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3427 return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3428 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3429 )if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
;
3430
3431 if (encoding & ENC_STRING0x07000000) {
3432 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3433 }
3434 /* I believe it's ok if this is called with a NULL tree */
3435 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3436 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3437 uint64_t temp64;
3438 tvb_get_varint(tvb, start, length, &temp64, encoding);
3439 value = (uint32_t)temp64;
3440 } else {
3441 value = get_uint_value(tree, tvb, start, length, encoding);
3442 }
3443
3444 if (retval) {
3445 *retval = value;
3446 if (hfinfo->bitmask) {
3447 /* Mask out irrelevant portions */
3448 *retval &= (uint32_t)(hfinfo->bitmask);
3449 /* Shift bits */
3450 *retval >>= hfinfo_bitshift(hfinfo);
3451 }
3452 }
3453
3454 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3455
3456 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", 3456
, __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", 3456, "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", 3456, "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", 3456, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3457
3458 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3459
3460 proto_tree_set_uint(new_fi, value);
3461
3462 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3463 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3464 new_fi->flags |= FI_VARINT0x00040000;
3465 }
3466 return proto_tree_add_node(tree, new_fi);
3467}
3468
3469proto_item *
3470proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3471 const unsigned start, unsigned length,
3472 const unsigned encoding, uint32_t *retval)
3473{
3474 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3475}
3476
3477proto_item *
3478proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3479 const unsigned start, unsigned length,
3480 const unsigned encoding, uint8_t *retval)
3481{
3482 /* TODO: further restrict by hfinfo->type ? */
3483 uint32_t val32;
3484 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3485 *retval = (uint8_t)val32;
3486 return item;
3487}
3488
3489proto_item *
3490proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3491 const unsigned start, unsigned length,
3492 const unsigned encoding, uint16_t *retval)
3493{
3494 /* TODO: further restrict by hfinfo->type ? */
3495 uint32_t val32;
3496 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3497 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3498 return item;
3499}
3500
3501
3502/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3503 * and returns proto_item* and uint value retrieved*/
3504proto_item *
3505ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3506 const unsigned encoding, uint32_t *retval)
3507{
3508 field_info *new_fi;
3509 header_field_info *hfinfo;
3510 unsigned item_length;
3511 unsigned offset;
3512 uint32_t value;
3513
3514 offset = ptvc->offset;
3515 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", 3515, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3515,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3515, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3516
3517 switch (hfinfo->type) {
3518 case FT_CHAR:
3519 case FT_UINT8:
3520 case FT_UINT16:
3521 case FT_UINT24:
3522 case FT_UINT32:
3523 break;
3524 default:
3525 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)
3526 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)
;
3527 }
3528
3529 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3530 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3531
3532 /* I believe it's ok if this is called with a NULL tree */
3533 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3534 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3535
3536 if (retval) {
3537 *retval = value;
3538 if (hfinfo->bitmask) {
3539 /* Mask out irrelevant portions */
3540 *retval &= (uint32_t)(hfinfo->bitmask);
3541 /* Shift bits */
3542 *retval >>= hfinfo_bitshift(hfinfo);
3543 }
3544 }
3545
3546 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3547
3548 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3549
3550 /* Coast clear. Try and fake it */
3551 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", 3551
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3551, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3551, "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", 3551, __func__, "Adding %s would put more than %d 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); } } }
;
3552
3553 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3554
3555 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3556 offset, length, encoding);
3557}
3558
3559/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3560 * and returns proto_item* and int value retrieved*/
3561proto_item *
3562ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3563 const unsigned encoding, int32_t *retval)
3564{
3565 field_info *new_fi;
3566 header_field_info *hfinfo;
3567 unsigned item_length;
3568 unsigned offset;
3569 uint32_t value;
3570
3571 offset = ptvc->offset;
3572 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", 3572, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3572,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3572, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3573
3574 switch (hfinfo->type) {
3575 case FT_INT8:
3576 case FT_INT16:
3577 case FT_INT24:
3578 case FT_INT32:
3579 break;
3580 default:
3581 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)
3582 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3583 }
3584
3585 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3586 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3587
3588 /* I believe it's ok if this is called with a NULL tree */
3589 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3590 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3591
3592 if (retval) {
3593 int no_of_bits;
3594 *retval = value;
3595 if (hfinfo->bitmask) {
3596 /* Mask out irrelevant portions */
3597 *retval &= (uint32_t)(hfinfo->bitmask);
3598 /* Shift bits */
3599 *retval >>= hfinfo_bitshift(hfinfo);
3600 }
3601 no_of_bits = ws_count_ones(hfinfo->bitmask);
3602 *retval = ws_sign_ext32(*retval, no_of_bits);
3603 }
3604
3605 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3606
3607 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3608
3609 /* Coast clear. Try and fake it */
3610 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", 3610
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3610, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3610, "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", 3610, __func__, "Adding %s would put more than %d 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); } } }
;
3611
3612 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3613
3614 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3615 offset, length, encoding);
3616}
3617
3618/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3619 * and returns proto_item* and string value retrieved */
3620proto_item*
3621ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3622{
3623 header_field_info *hfinfo;
3624 field_info *new_fi;
3625 const uint8_t *value;
3626 unsigned item_length;
3627 unsigned offset;
3628
3629 offset = ptvc->offset;
3630
3631 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", 3631
, __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", 3631, "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", 3631, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3632
3633 switch (hfinfo->type) {
3634 case FT_STRING:
3635 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3636 break;
3637 case FT_STRINGZ:
3638 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3639 break;
3640 case FT_UINT_STRING:
3641 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3642 break;
3643 case FT_STRINGZPAD:
3644 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3645 break;
3646 case FT_STRINGZTRUNC:
3647 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3648 break;
3649 default:
3650 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)
3651 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)
;
3652 }
3653
3654 if (retval)
3655 *retval = value;
3656
3657 ptvcursor_advance(ptvc, item_length);
3658
3659 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3660
3661 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", 3661, __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", 3661,
"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", 3661, "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", 3661
, __func__, "Adding %s would put more than %d 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); } } }
;
3662
3663 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3664
3665 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3666 offset, length, encoding);
3667}
3668
3669/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3670 * and returns proto_item* and boolean value retrieved */
3671proto_item*
3672ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3673{
3674 header_field_info *hfinfo;
3675 field_info *new_fi;
3676 unsigned item_length;
3677 unsigned offset;
3678 uint64_t value, bitval;
3679
3680 offset = ptvc->offset;
3681 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", 3681, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3681,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3681, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3682
3683 if (hfinfo->type != FT_BOOLEAN) {
3684 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)
3685 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3686 }
3687
3688 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3689 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3690 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3691 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3692 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3693 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3694 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3695
3696 if (encoding & ENC_STRING0x07000000) {
3697 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3698 }
3699
3700 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3701 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3702
3703 /* I believe it's ok if this is called with a NULL tree */
3704 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3705
3706 if (retval) {
3707 bitval = value;
3708 if (hfinfo->bitmask) {
3709 /* Mask out irrelevant portions */
3710 bitval &= hfinfo->bitmask;
3711 }
3712 *retval = (bitval != 0);
3713 }
3714
3715 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3716
3717 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3718
3719 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", 3719, __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", 3719,
"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", 3719, "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", 3719
, __func__, "Adding %s would put more than %d 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); } } }
;
3720
3721 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3722
3723 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3724 offset, length, encoding);
3725}
3726
3727proto_item *
3728proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3729 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3730{
3731 header_field_info *hfinfo;
3732 field_info *new_fi;
3733 uint64_t value;
3734
3735 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", 3735, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3735,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3735, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3736
3737 switch (hfinfo->type) {
3738 case FT_UINT40:
3739 case FT_UINT48:
3740 case FT_UINT56:
3741 case FT_UINT64:
3742 break;
3743 default:
3744 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)
3745 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3746 }
3747
3748 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3749 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3750 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3751 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3752 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3753 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3754 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3755
3756 if (encoding & ENC_STRING0x07000000) {
3757 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3758 }
3759 /* I believe it's ok if this is called with a NULL tree */
3760 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3761 tvb_get_varint(tvb, start, length, &value, encoding);
3762 } else {
3763 value = get_uint64_value(tree, tvb, start, length, encoding);
3764 }
3765
3766 if (retval) {
3767 *retval = value;
3768 if (hfinfo->bitmask) {
3769 /* Mask out irrelevant portions */
3770 *retval &= hfinfo->bitmask;
3771 /* Shift bits */
3772 *retval >>= hfinfo_bitshift(hfinfo);
3773 }
3774 }
3775
3776 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3777
3778 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", 3778
, __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", 3778, "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", 3778, "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", 3778, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3779
3780 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3781
3782 proto_tree_set_uint64(new_fi, value);
3783
3784 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3785 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3786 new_fi->flags |= FI_VARINT0x00040000;
3787 }
3788
3789 return proto_tree_add_node(tree, new_fi);
3790}
3791
3792proto_item *
3793proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3794 const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3795{
3796 header_field_info *hfinfo;
3797 field_info *new_fi;
3798 int64_t value;
3799
3800 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", 3800, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3800,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3800, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3801
3802 switch (hfinfo->type) {
3803 case FT_INT40:
3804 case FT_INT48:
3805 case FT_INT56:
3806 case FT_INT64:
3807 break;
3808 default:
3809 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)
3810 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3811 }
3812
3813 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3814 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3815 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3816 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3817 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3818 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3819 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3820
3821 if (encoding & ENC_STRING0x07000000) {
3822 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3823 }
3824 /* I believe it's ok if this is called with a NULL tree */
3825 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3826 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3827 }
3828 else {
3829 value = get_int64_value(tree, tvb, start, length, encoding);
3830 }
3831
3832 if (retval) {
3833 *retval = value;
3834 }
3835
3836 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3837
3838 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", 3838
, __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", 3838, "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", 3838, "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", 3838, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3839
3840 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3841
3842 proto_tree_set_int64(new_fi, value);
3843
3844 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3845 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3846 new_fi->flags |= FI_VARINT0x00040000;
3847 }
3848
3849 return proto_tree_add_node(tree, new_fi);
3850}
3851
3852proto_item *
3853proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3854 const unsigned start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3855{
3856 header_field_info *hfinfo;
3857 field_info *new_fi;
3858 uint64_t value;
3859
3860 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", 3860, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3860,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3860, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3861
3862 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
))
)) {
3863 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)
3864 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3865 }
3866
3867 /* length validation for native number encoding caught by get_uint64_value() */
3868 /* length has to be -1 or > 0 regardless of encoding */
3869 if (length == 0)
3870 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)
3871 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3872
3873 if (encoding & ENC_STRING0x07000000) {
3874 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3875 }
3876
3877 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3878
3879 if (retval) {
3880 *retval = value;
3881 if (hfinfo->bitmask) {
3882 /* Mask out irrelevant portions */
3883 *retval &= hfinfo->bitmask;
3884 /* Shift bits */
3885 *retval >>= hfinfo_bitshift(hfinfo);
3886 }
3887 }
3888
3889 if (lenretval) {
3890 *lenretval = length;
3891 }
3892
3893 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3894
3895 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", 3895
, __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", 3895, "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", 3895, "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", 3895, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3896
3897 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3898
3899 proto_tree_set_uint64(new_fi, value);
3900
3901 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3902 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3903 new_fi->flags |= FI_VARINT0x00040000;
3904 }
3905
3906 return proto_tree_add_node(tree, new_fi);
3907
3908}
3909
3910proto_item *
3911proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3912 const unsigned start, unsigned length,
3913 const unsigned encoding, bool_Bool *retval)
3914{
3915 header_field_info *hfinfo;
3916 field_info *new_fi;
3917 uint64_t value, bitval;
3918
3919 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", 3919, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3919,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3919, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3920
3921 if (hfinfo->type != FT_BOOLEAN) {
3922 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)
3923 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3924 }
3925
3926 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3927 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3928 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3929 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3930 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3931 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3932 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3933
3934 if (encoding & ENC_STRING0x07000000) {
3935 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3936 }
3937 /* I believe it's ok if this is called with a NULL tree */
3938 value = get_uint64_value(tree, tvb, start, length, encoding);
3939
3940 if (retval) {
3941 bitval = value;
3942 if (hfinfo->bitmask) {
3943 /* Mask out irrelevant portions */
3944 bitval &= hfinfo->bitmask;
3945 }
3946 *retval = (bitval != 0);
3947 }
3948
3949 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3950
3951 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", 3951
, __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", 3951, "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", 3951, "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", 3951, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3952
3953 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3954
3955 proto_tree_set_boolean(new_fi, value);
3956
3957 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3958
3959 return proto_tree_add_node(tree, new_fi);
3960}
3961
3962proto_item *
3963proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3964 const unsigned start, unsigned length,
3965 const unsigned encoding, float *retval)
3966{
3967 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3968 field_info *new_fi;
3969 float value;
3970
3971 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", 3971,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3972
3973 if (hfinfo->type != FT_FLOAT) {
3974 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)
;
3975 }
3976
3977 if (length != 4) {
3978 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3979 }
3980
3981 /* treat any nonzero encoding as little endian for backwards compatibility */
3982 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3983 if (retval) {
3984 *retval = value;
3985 }
3986
3987 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3988
3989 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", 3989
, __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", 3989, "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", 3989, "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", 3989, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3990
3991 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3992 if (encoding) {
3993 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3994 }
3995
3996 proto_tree_set_float(new_fi, value);
3997
3998 return proto_tree_add_node(tree, new_fi);
3999}
4000
4001proto_item *
4002proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4003 const unsigned start, unsigned length,
4004 const unsigned encoding, double *retval)
4005{
4006 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4007 field_info *new_fi;
4008 double value;
4009
4010 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", 4010,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4011
4012 if (hfinfo->type != FT_DOUBLE) {
4013 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)
;
4014 }
4015
4016 if (length != 8) {
4017 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4018 }
4019
4020 /* treat any nonzero encoding as little endian for backwards compatibility */
4021 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4022 if (retval) {
4023 *retval = value;
4024 }
4025
4026 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4027
4028 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", 4028
, __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", 4028, "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", 4028, "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", 4028, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4029
4030 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4031 if (encoding) {
4032 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4033 }
4034
4035 proto_tree_set_double(new_fi, value);
4036
4037 return proto_tree_add_node(tree, new_fi);
4038}
4039
4040proto_item *
4041proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4042 const unsigned start, unsigned length,
4043 const unsigned encoding, ws_in4_addr *retval)
4044{
4045 header_field_info *hfinfo;
4046 field_info *new_fi;
4047 ws_in4_addr value;
4048
4049 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", 4049, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4049,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4049, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4050
4051 switch (hfinfo->type) {
4052 case FT_IPv4:
4053 break;
4054 default:
4055 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)
4056 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4057 }
4058
4059 if (length != FT_IPv4_LEN4)
4060 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)
4061 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4062
4063 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4064 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4065 }
4066
4067 /*
4068 * NOTE: to support code written when proto_tree_add_item() took
4069 * a bool as its last argument, with false meaning "big-endian"
4070 * and true meaning "little-endian", we treat any non-zero value
4071 * of "encoding" as meaning "little-endian".
4072 */
4073 value = tvb_get_ipv4(tvb, start);
4074 if (encoding)
4075 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))))
;
4076
4077 if (retval) {
4078 *retval = value;
4079 }
4080
4081 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4082
4083 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", 4083
, __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", 4083, "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", 4083, "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", 4083, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4084
4085 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4086
4087 proto_tree_set_ipv4(new_fi, value);
4088
4089 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4090 return proto_tree_add_node(tree, new_fi);
4091}
4092
4093proto_item *
4094proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4095 const unsigned start, unsigned length,
4096 const unsigned encoding, ws_in6_addr *addr)
4097{
4098 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4099 field_info *new_fi;
4100
4101 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", 4101,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4102
4103 switch (hfinfo->type) {
4104 case FT_IPv6:
4105 break;
4106 default:
4107 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)
4108 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4109 }
4110
4111 if (length != FT_IPv6_LEN16)
4112 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)
4113 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4114
4115 if (encoding) {
4116 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"
)
;
4117 }
4118
4119 tvb_get_ipv6(tvb, start, addr);
4120
4121 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4122
4123 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", 4123
, __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", 4123, "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", 4123, "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", 4123, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4124
4125 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4126
4127 proto_tree_set_ipv6(new_fi, addr);
4128
4129 return proto_tree_add_node(tree, new_fi);
4130}
4131
4132proto_item *
4133proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4134 const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4135
4136 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4137 field_info *new_fi;
4138
4139 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", 4139,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4140
4141 switch (hfinfo->type) {
4142 case FT_ETHER:
4143 break;
4144 default:
4145 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)
4146 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4147 }
4148
4149 if (length != FT_ETHER_LEN6)
4150 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)
4151 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4152
4153 if (encoding) {
4154 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"
)
;
4155 }
4156
4157 tvb_memcpy(tvb, retval, start, length);
4158
4159 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4160
4161 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", 4161
, __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", 4161, "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", 4161, "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", 4161, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4162
4163 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4164
4165 proto_tree_set_ether(new_fi, retval);
4166
4167 return proto_tree_add_node(tree, new_fi);
4168}
4169
4170
4171proto_item *
4172proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4173 tvbuff_t *tvb,
4174 const unsigned start, int length,
4175 const unsigned encoding,
4176 wmem_allocator_t *scope,
4177 const uint8_t **retval,
4178 int *lenretval)
4179{
4180 proto_item *pi;
4181 header_field_info *hfinfo;
4182 field_info *new_fi;
4183 const uint8_t *value;
4184
4185 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", 4185, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4185,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4185, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4186
4187 switch (hfinfo->type) {
4188 case FT_STRING:
4189 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4190 break;
4191 case FT_STRINGZ:
4192 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4193 break;
4194 case FT_UINT_STRING:
4195 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4196 break;
4197 case FT_STRINGZPAD:
4198 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4199 break;
4200 case FT_STRINGZTRUNC:
4201 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4202 break;
4203 default:
4204 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)
4205 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)
;
4206 }
4207
4208 if (retval)
4209 *retval = value;
4210
4211 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4212
4213 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", 4213
, __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", 4213, "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", 4213, "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", 4213, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4214
4215 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4216
4217 proto_tree_set_string(new_fi, (const char*)value);
4218
4219 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4220
4221 pi = proto_tree_add_node(tree, new_fi);
4222
4223 switch (hfinfo->type) {
4224
4225 case FT_STRINGZ:
4226 case FT_STRINGZPAD:
4227 case FT_STRINGZTRUNC:
4228 case FT_UINT_STRING:
4229 break;
4230
4231 case FT_STRING:
4232 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4233 break;
4234
4235 default:
4236 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4236
, __func__, "assertion \"not reached\" failed")
;
4237 }
4238
4239 return pi;
4240}
4241
4242proto_item *
4243proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4244 const unsigned start, int length,
4245 const unsigned encoding, wmem_allocator_t *scope,
4246 const uint8_t **retval)
4247{
4248 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4249 tvb, start, length, encoding, scope, retval, &length);
4250}
4251
4252proto_item *
4253proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4254 tvbuff_t *tvb,
4255 const unsigned start, int length,
4256 const unsigned encoding,
4257 wmem_allocator_t *scope,
4258 char **retval,
4259 int *lenretval)
4260{
4261 proto_item *pi;
4262 header_field_info *hfinfo;
4263 field_info *new_fi;
4264 const uint8_t *value;
4265 uint32_t n = 0;
4266
4267 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", 4267, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4267,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4267, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4268
4269 switch (hfinfo->type) {
4270 case FT_STRING:
4271 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4272 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4273 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4274 break;
4275 case FT_STRINGZ:
4276 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4277 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4278 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4279 break;
4280 case FT_UINT_STRING:
4281 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4282 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4283 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4284 break;
4285 case FT_STRINGZPAD:
4286 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4287 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4288 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4289 break;
4290 case FT_STRINGZTRUNC:
4291 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4292 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4293 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4294 break;
4295 case FT_BYTES:
4296 tvb_ensure_bytes_exist(tvb, start, length);
4297 value = tvb_get_ptr(tvb, start, length);
4298 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4299 *lenretval = length;
4300 break;
4301 case FT_UINT_BYTES:
4302 n = get_uint_value(tree, tvb, start, length, encoding);
4303 tvb_ensure_bytes_exist(tvb, start + length, n);
4304 value = tvb_get_ptr(tvb, start + length, n);
4305 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4306 *lenretval = length + n;
4307 break;
4308 default:
4309 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)
4310 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)
;
4311 }
4312
4313 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4314
4315 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", 4315
, __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", 4315, "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", 4315, "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", 4315, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4316
4317 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4318
4319 switch (hfinfo->type) {
4320
4321 case FT_STRING:
4322 case FT_STRINGZ:
4323 case FT_UINT_STRING:
4324 case FT_STRINGZPAD:
4325 case FT_STRINGZTRUNC:
4326 proto_tree_set_string(new_fi, (const char*)value);
4327 break;
4328
4329 case FT_BYTES:
4330 proto_tree_set_bytes(new_fi, value, length);
4331 break;
4332
4333 case FT_UINT_BYTES:
4334 proto_tree_set_bytes(new_fi, value, n);
4335 break;
4336
4337 default:
4338 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4338
, __func__, "assertion \"not reached\" failed")
;
4339 }
4340
4341 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4342
4343 pi = proto_tree_add_node(tree, new_fi);
4344
4345 switch (hfinfo->type) {
4346
4347 case FT_STRINGZ:
4348 case FT_STRINGZPAD:
4349 case FT_STRINGZTRUNC:
4350 case FT_UINT_STRING:
4351 break;
4352
4353 case FT_STRING:
4354 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4355 break;
4356
4357 case FT_BYTES:
4358 case FT_UINT_BYTES:
4359 break;
4360
4361 default:
4362 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4362
, __func__, "assertion \"not reached\" failed")
;
4363 }
4364
4365 return pi;
4366}
4367
4368proto_item *
4369proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4370 tvbuff_t *tvb,
4371 const unsigned start, int length,
4372 const unsigned encoding,
4373 wmem_allocator_t *scope,
4374 char **retval)
4375{
4376 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4377 tvb, start, length, encoding, scope, retval, &length);
4378}
4379
4380proto_item *
4381proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4382 tvbuff_t *tvb,
4383 const unsigned start, int length, const unsigned encoding,
4384 wmem_allocator_t *scope, char **retval)
4385{
4386 header_field_info *hfinfo;
4387 field_info *new_fi;
4388 nstime_t time_stamp;
4389 int flags;
4390
4391 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", 4391, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4391,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4391, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4392
4393 switch (hfinfo->type) {
4394 case FT_ABSOLUTE_TIME:
4395 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4396 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4397 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4398 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4399 }
4400 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4401 break;
4402 case FT_RELATIVE_TIME:
4403 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4404 *retval = rel_time_to_secs_str(scope, &time_stamp);
4405 break;
4406 default:
4407 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)
4408 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4409 }
4410
4411 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4412
4413 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", 4413
, __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", 4413, "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", 4413, "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", 4413, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4414
4415 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4416
4417 switch (hfinfo->type) {
4418
4419 case FT_ABSOLUTE_TIME:
4420 case FT_RELATIVE_TIME:
4421 proto_tree_set_time(new_fi, &time_stamp);
4422 break;
4423 default:
4424 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4424
, __func__, "assertion \"not reached\" failed")
;
4425 }
4426
4427 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4428
4429 return proto_tree_add_node(tree, new_fi);
4430}
4431
4432/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4433 and returns proto_item* */
4434proto_item *
4435ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4436 const unsigned encoding)
4437{
4438 field_info *new_fi;
4439 header_field_info *hfinfo;
4440 int item_length;
4441 unsigned offset;
4442
4443 offset = ptvc->offset;
4444 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", 4444, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4444,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4444, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4445 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4446 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4447
4448 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4449
4450 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4451
4452 /* Coast clear. Try and fake it */
4453 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", 4453
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4453, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4453, "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", 4453, __func__, "Adding %s would put more than %d 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); } } }
;
4454
4455 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4456
4457 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4458 offset, length, encoding);
4459}
4460
4461/* Add an item to a proto_tree, using the text label registered to that item;
4462 the item is extracted from the tvbuff handed to it. */
4463proto_item *
4464proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4465 const unsigned start, int length, const unsigned encoding)
4466{
4467 field_info *new_fi;
4468 int item_length;
4469
4470 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", 4470,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4471
4472 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4473 test_length(hfinfo, tvb, start, item_length, encoding);
4474
4475 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4476
4477 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", 4477
, __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", 4477, "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", 4477, "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", 4477, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4478
4479 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4480
4481 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4482}
4483
4484proto_item *
4485proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4486 const unsigned start, int length, const unsigned encoding)
4487{
4488 register header_field_info *hfinfo;
4489
4490 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", 4490, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4490,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4490, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4491 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4492}
4493
4494/* Add an item to a proto_tree, using the text label registered to that item;
4495 the item is extracted from the tvbuff handed to it.
4496
4497 Return the length of the item through the pointer. */
4498proto_item *
4499proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4500 tvbuff_t *tvb, const unsigned start,
4501 int length, const unsigned encoding,
4502 int *lenretval)
4503{
4504 field_info *new_fi;
4505 int item_length;
4506 proto_item *item;
4507
4508 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", 4508,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4509
4510 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4511 test_length(hfinfo, tvb, start, item_length, encoding);
4512
4513 if (!tree) {
4514 /*
4515 * We need to get the correct item length here.
4516 * That's normally done by proto_tree_new_item(),
4517 * but we won't be calling it.
4518 */
4519 *lenretval = get_full_length(hfinfo, tvb, start, length,
4520 item_length, encoding);
4521 return NULL((void*)0);
4522 }
4523
4524 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", 4531
, __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", 4531, "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", 4531, "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", 4531
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4525 /*((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", 4531
, __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", 4531, "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", 4531, "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", 4531
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4526 * 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", 4531
, __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", 4531, "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", 4531, "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", 4531
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4527 * 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", 4531
, __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", 4531, "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", 4531, "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", 4531
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4528 */((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", 4531
, __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", 4531, "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", 4531, "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", 4531
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4529 *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", 4531
, __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", 4531, "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", 4531, "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", 4531
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4530 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", 4531
, __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", 4531, "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", 4531, "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", 4531
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4531 })((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", 4531
, __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", 4531, "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", 4531, "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", 4531
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4532
4533 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4534
4535 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4536 *lenretval = new_fi->length;
4537 return item;
4538}
4539
4540proto_item *
4541proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4542 const unsigned start, int length,
4543 const unsigned encoding, int *lenretval)
4544{
4545 register header_field_info *hfinfo;
4546
4547 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", 4547, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4547,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4547, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4548 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4549}
4550
4551/* which FT_ types can use proto_tree_add_bytes_item() */
4552static inline bool_Bool
4553validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4554{
4555 return (type == FT_BYTES ||
4556 type == FT_UINT_BYTES ||
4557 type == FT_OID ||
4558 type == FT_REL_OID ||
4559 type == FT_SYSTEM_ID );
4560}
4561
4562/* Note: this does no validation that the byte array of an FT_OID or
4563 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4564 so I think it's ok to continue not validating it?
4565 */
4566proto_item *
4567proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4568 const unsigned start, unsigned length,
4569 const unsigned encoding,
4570 GByteArray *retval, unsigned *endoff, int *err)
4571{
4572 field_info *new_fi;
4573 GByteArray *bytes = retval;
4574 GByteArray *created_bytes = NULL((void*)0);
4575 bool_Bool failed = false0;
4576 uint32_t n = 0;
4577 header_field_info *hfinfo;
4578 bool_Bool generate = (bytes || tree) ? true1 : false0;
4579
4580 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", 4580, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4580,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4580, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4581
4582 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", 4582,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4583
4584 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", 4585, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4585 "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", 4585, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4586
4587 if (length == 0) {
4588 return NULL((void*)0);
4589 }
4590
4591 if (encoding & ENC_STR_NUM0x01000000) {
4592 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"
)
;
4593 }
4594
4595 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4596 if (hfinfo->type == FT_UINT_BYTES) {
4597 /* can't decode FT_UINT_BYTES from strings */
4598 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")
4599 "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")
;
4600 }
4601
4602 unsigned hex_encoding = encoding;
4603 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4604 /* If none of the separator values are used,
4605 * assume no separator (the common case). */
4606 hex_encoding |= ENC_SEP_NONE0x00010000;
4607#if 0
4608 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")
4609 "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")
;
4610#endif
4611 }
4612
4613 if (!bytes) {
4614 /* caller doesn't care about return value, but we need it to
4615 call tvb_get_string_bytes() and set the tree later */
4616 bytes = created_bytes = g_byte_array_new();
4617 }
4618
4619 /*
4620 * bytes might be NULL after this, but can't add expert
4621 * error until later; if it's NULL, just note that
4622 * it failed.
4623 */
4624 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4625 if (bytes == NULL((void*)0))
4626 failed = true1;
4627 }
4628 else if (generate) {
4629 tvb_ensure_bytes_exist(tvb, start, length);
4630
4631 if (hfinfo->type == FT_UINT_BYTES) {
4632 n = length; /* n is now the "header" length */
4633 length = get_uint_value(tree, tvb, start, n, encoding);
4634 /* length is now the value's length; only store the value in the array */
4635 tvb_ensure_bytes_exist(tvb, start + n, length);
4636 if (!bytes) {
4637 /* caller doesn't care about return value, but
4638 * we may need it to set the tree later */
4639 bytes = created_bytes = g_byte_array_new();
4640 }
4641 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4642 }
4643 else if (length > 0) {
4644 if (!bytes) {
4645 /* caller doesn't care about return value, but
4646 * we may need it to set the tree later */
4647 bytes = created_bytes = g_byte_array_new();
4648 }
4649 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4650 }
4651
4652 if (endoff)
4653 *endoff = start + n + length;
4654 }
4655
4656 if (err)
4657 *err = failed ? EINVAL22 : 0;
4658
4659 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); }
4660 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4661 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); }
4662 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); }
4663 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); }
4664 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4665 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4666
4667 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", 4673
, __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", 4673, "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", 4673, "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", 4673
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4668 {((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", 4673
, __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", 4673, "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", 4673, "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", 4673
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4669 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", 4673
, __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", 4673, "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", 4673, "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", 4673
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4670 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", 4673
, __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", 4673, "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", 4673, "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", 4673
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4671 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", 4673
, __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", 4673, "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", 4673, "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", 4673
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4672 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", 4673
, __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", 4673, "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", 4673, "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", 4673
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4673 } )((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", 4673
, __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", 4673, "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", 4673, "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", 4673
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4674
4675 /* n will be zero except when it's a FT_UINT_BYTES */
4676 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4677
4678 if (encoding & ENC_STRING0x07000000) {
4679 if (failed)
4680 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4681
4682 if (bytes)
4683 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4684 else
4685 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4686
4687 if (created_bytes)
4688 g_byte_array_free(created_bytes, true1);
4689 }
4690 else {
4691 /* n will be zero except when it's a FT_UINT_BYTES */
4692 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4693
4694 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4695 * use the byte array created above in this case.
4696 */
4697 if (created_bytes)
4698 g_byte_array_free(created_bytes, true1);
4699
4700 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4701 (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)
;
4702 }
4703
4704 return proto_tree_add_node(tree, new_fi);
4705}
4706
4707
4708proto_item *
4709proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4710 const unsigned start, const unsigned length,
4711 const unsigned encoding,
4712 nstime_t *retval, unsigned *endoff, int *err)
4713{
4714 field_info *new_fi;
4715 nstime_t time_stamp;
4716 int saved_err = 0;
4717 header_field_info *hfinfo;
4718
4719 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", 4719, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4719,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4719, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4720
4721 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", 4721,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4722
4723 if (length == 0) {
4724 if(retval) {
4725 nstime_set_zero(retval);
4726 }
4727 return NULL((void*)0);
4728 }
4729
4730 nstime_set_zero(&time_stamp);
4731
4732 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4733 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", 4733, ((hfinfo))->abbrev))))
;
4734 /* The only string format that could be a relative time is
4735 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4736 * relative to "now" currently.
4737 */
4738 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4739 saved_err = EINVAL22;
4740 }
4741 else {
4742 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", 4742, ((hfinfo))->abbrev))))
;
4743 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4744
4745 tvb_ensure_bytes_exist(tvb, start, length);
4746 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4747 if (endoff) *endoff = start + length;
4748 }
4749
4750 if (err) *err = saved_err;
4751
4752 if (retval) {
4753 retval->secs = time_stamp.secs;
4754 retval->nsecs = time_stamp.nsecs;
4755 }
4756
4757 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4758
4759 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", 4759
, __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", 4759, "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", 4759, "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", 4759, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4760
4761 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4762
4763 proto_tree_set_time(new_fi, &time_stamp);
4764
4765 if (encoding & ENC_STRING0x07000000) {
4766 if (saved_err)
4767 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4768 }
4769 else {
4770 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4771 (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)
;
4772 }
4773
4774 return proto_tree_add_node(tree, new_fi);
4775}
4776
4777/* Add a FT_NONE to a proto_tree */
4778proto_item *
4779proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4780 const unsigned start, int length, const char *format,
4781 ...)
4782{
4783 proto_item *pi;
4784 va_list ap;
4785 header_field_info *hfinfo;
4786
4787 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4788
4789 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", 4789
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4789, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4789, "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", 4789, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4790
4791 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", 4791
, ((hfinfo))->abbrev))))
;
4792
4793 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4794
4795 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4795, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4796
4797 va_start(ap, format)__builtin_va_start(ap, format);
4798 proto_tree_set_representation(pi, format, ap);
4799 va_end(ap)__builtin_va_end(ap);
4800
4801 /* no value to set for FT_NONE */
4802 return pi;
4803}
4804
4805/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4806 * offset, and returns proto_item* */
4807proto_item *
4808ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4809 const unsigned encoding)
4810{
4811 proto_item *item;
4812
4813 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4814 length, encoding);
4815
4816 return item;
4817}
4818
4819/* Advance the ptvcursor's offset within its tvbuff without
4820 * adding anything to the proto_tree. */
4821void
4822ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4823{
4824 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4825 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4826 }
4827}
4828
4829
4830static void
4831proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4832{
4833 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4833, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4834 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4835}
4836
4837/* Add a FT_PROTOCOL to a proto_tree */
4838proto_item *
4839proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4840 unsigned start, int length, const char *format, ...)
4841{
4842 proto_item *pi;
4843 field_info *new_fi;
4844 tvbuff_t *protocol_tvb;
4845 va_list ap;
4846 header_field_info *hfinfo;
4847 char* protocol_rep;
4848
4849 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4850
4851 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", 4851
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4851, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4851, "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", 4851, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4852
4853 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"
, 4853, ((hfinfo))->abbrev))))
;
4854
4855 /*
4856 * This can throw an exception when it calls get_hfi_length before
4857 * it allocates anything, if length is nonzero and start is past
4858 * the end of the tvb. Afterwards it can't throw an exception,
4859 * as length is clamped to the captured length remaining.
4860 */
4861 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4862 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4863 /* Start the protocol_tvb at the correct start offset, but allow it
4864 * to be lengthened later via finfo_set_len. */
4865 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4866
4867 va_start(ap, format)__builtin_va_start(ap, format);
4868 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4869 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4870 g_free(protocol_rep)(__builtin_object_size ((protocol_rep), 0) != ((size_t) - 1))
? g_free_sized (protocol_rep, __builtin_object_size ((protocol_rep
), 0)) : (g_free) (protocol_rep)
;
4871 va_end(ap)__builtin_va_end(ap);
4872
4873 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4873, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4874
4875 va_start(ap, format)__builtin_va_start(ap, format);
4876 proto_tree_set_representation(pi, format, ap);
4877 va_end(ap)__builtin_va_end(ap);
4878
4879 return pi;
4880}
4881
4882/* Add a FT_BYTES to a proto_tree */
4883proto_item *
4884proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4885 int length, const uint8_t *start_ptr)
4886{
4887 proto_item *pi;
4888 header_field_info *hfinfo;
4889 int item_length;
4890
4891 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", 4891, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4891,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4891, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4892 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4893 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4894
4895 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4896
4897 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", 4897
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4897, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4897, "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", 4897, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4898
4899 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",
4899, ((hfinfo))->abbrev))))
;
4900
4901 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4902 start_ptr = tvb_get_ptr(tvb, start, length);
4903
4904 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4905 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4906
4907 return pi;
4908}
4909
4910/* Add a FT_BYTES to a proto_tree */
4911proto_item *
4912proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4913 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4914{
4915 proto_item *pi;
4916 header_field_info *hfinfo;
4917 int item_length;
4918
4919 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", 4919, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4919,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4919, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4920 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4921 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4922
4923 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4924
4925 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", 4925
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4925, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4925, "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", 4925, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4926
4927 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",
4927, ((hfinfo))->abbrev))))
;
4928
4929 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4930 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4931
4932 return pi;
4933}
4934
4935proto_item *
4936proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4937 unsigned start, int length,
4938 const uint8_t *start_ptr,
4939 const char *format, ...)
4940{
4941 proto_item *pi;
4942 va_list ap;
4943
4944 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4945
4946 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; }
;
4947
4948 va_start(ap, format)__builtin_va_start(ap, format);
4949 proto_tree_set_representation_value(pi, format, ap);
4950 va_end(ap)__builtin_va_end(ap);
4951
4952 return pi;
4953}
4954
4955proto_item *
4956proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4957 unsigned start, int length, const uint8_t *start_ptr,
4958 const char *format, ...)
4959{
4960 proto_item *pi;
4961 va_list ap;
4962
4963 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4964
4965 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; }
;
4966
4967 va_start(ap, format)__builtin_va_start(ap, format);
4968 proto_tree_set_representation(pi, format, ap);
4969 va_end(ap)__builtin_va_end(ap);
4970
4971 return pi;
4972}
4973
4974static void
4975proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4976{
4977 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4977, "length >= 0"
))))
;
4978 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", 4978, "start_ptr != ((void*)0) || length == 0"
))))
;
4979
4980 fvalue_set_bytes_data(fi->value, start_ptr, length);
4981}
4982
4983
4984static void
4985proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
4986{
4987 tvb_ensure_bytes_exist(tvb, offset, length);
4988 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4989}
4990
4991static void
4992proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4993{
4994 GByteArray *bytes;
4995
4996 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4996, "value != ((void*)0)"
))))
;
4997
4998 bytes = byte_array_dup(value);
4999
5000 fvalue_set_byte_array(fi->value, bytes);
5001}
5002
5003/* Add a FT_*TIME to a proto_tree */
5004proto_item *
5005proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5006 unsigned length, const nstime_t *value_ptr)
5007{
5008 proto_item *pi;
5009 header_field_info *hfinfo;
5010
5011 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5012
5013 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", 5013
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5013, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5013, "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", 5013, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5014
5015 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", 5015, ((hfinfo))->abbrev))))
;
5016
5017 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5018 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5019
5020 return pi;
5021}
5022
5023proto_item *
5024proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5025 unsigned start, unsigned length, nstime_t *value_ptr,
5026 const char *format, ...)
5027{
5028 proto_item *pi;
5029 va_list ap;
5030
5031 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5032 if (pi != tree) {
5033 va_start(ap, format)__builtin_va_start(ap, format);
5034 proto_tree_set_representation_value(pi, format, ap);
5035 va_end(ap)__builtin_va_end(ap);
5036 }
5037
5038 return pi;
5039}
5040
5041proto_item *
5042proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5043 unsigned start, unsigned length, nstime_t *value_ptr,
5044 const char *format, ...)
5045{
5046 proto_item *pi;
5047 va_list ap;
5048
5049 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5050 if (pi != tree) {
5051 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5051, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5052
5053 va_start(ap, format)__builtin_va_start(ap, format);
5054 proto_tree_set_representation(pi, format, ap);
5055 va_end(ap)__builtin_va_end(ap);
5056 }
5057
5058 return pi;
5059}
5060
5061/* Set the FT_*TIME value */
5062static void
5063proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5064{
5065 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5065, "value_ptr != ((void*)0)"
))))
;
5066
5067 fvalue_set_time(fi->value, value_ptr);
5068}
5069
5070/* Add a FT_IPXNET to a proto_tree */
5071proto_item *
5072proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5073 unsigned length, uint32_t value)
5074{
5075 proto_item *pi;
5076 header_field_info *hfinfo;
5077
5078 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5079
5080 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", 5080
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5080, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5080, "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", 5080, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5081
5082 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"
, 5082, ((hfinfo))->abbrev))))
;
5083
5084 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5085 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5086
5087 return pi;
5088}
5089
5090proto_item *
5091proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5092 unsigned start, unsigned length, uint32_t value,
5093 const char *format, ...)
5094{
5095 proto_item *pi;
5096 va_list ap;
5097
5098 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5099 if (pi != tree) {
5100 va_start(ap, format)__builtin_va_start(ap, format);
5101 proto_tree_set_representation_value(pi, format, ap);
5102 va_end(ap)__builtin_va_end(ap);
5103 }
5104
5105 return pi;
5106}
5107
5108proto_item *
5109proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5110 unsigned start, unsigned length, uint32_t value,
5111 const char *format, ...)
5112{
5113 proto_item *pi;
5114 va_list ap;
5115
5116 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5117 if (pi != tree) {
5118 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5118, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5119
5120 va_start(ap, format)__builtin_va_start(ap, format);
5121 proto_tree_set_representation(pi, format, ap);
5122 va_end(ap)__builtin_va_end(ap);
5123 }
5124
5125 return pi;
5126}
5127
5128/* Set the FT_IPXNET value */
5129static void
5130proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5131{
5132 fvalue_set_uinteger(fi->value, value);
5133}
5134
5135/* Add a FT_IPv4 to a proto_tree */
5136proto_item *
5137proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5138 unsigned length, ws_in4_addr value)
5139{
5140 proto_item *pi;
5141 header_field_info *hfinfo;
5142
5143 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5144
5145 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", 5145
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5145, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5145, "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", 5145, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5146
5147 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", 5147
, ((hfinfo))->abbrev))))
;
5148
5149 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5150 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5151
5152 return pi;
5153}
5154
5155proto_item *
5156proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5157 unsigned start, unsigned length, ws_in4_addr value,
5158 const char *format, ...)
5159{
5160 proto_item *pi;
5161 va_list ap;
5162
5163 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5164 if (pi != tree) {
5165 va_start(ap, format)__builtin_va_start(ap, format);
5166 proto_tree_set_representation_value(pi, format, ap);
5167 va_end(ap)__builtin_va_end(ap);
5168 }
5169
5170 return pi;
5171}
5172
5173proto_item *
5174proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5175 unsigned start, unsigned length, ws_in4_addr value,
5176 const char *format, ...)
5177{
5178 proto_item *pi;
5179 va_list ap;
5180
5181 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5182 if (pi != tree) {
5183 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5183, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5184
5185 va_start(ap, format)__builtin_va_start(ap, format);
5186 proto_tree_set_representation(pi, format, ap);
5187 va_end(ap)__builtin_va_end(ap);
5188 }
5189
5190 return pi;
5191}
5192
5193/* Set the FT_IPv4 value */
5194static void
5195proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5196{
5197 ipv4_addr_and_mask ipv4;
5198 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5199 fvalue_set_ipv4(fi->value, &ipv4);
5200}
5201
5202/* Add a FT_IPv6 to a proto_tree */
5203proto_item *
5204proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5205 unsigned length, const ws_in6_addr *value)
5206{
5207 proto_item *pi;
5208 header_field_info *hfinfo;
5209
5210 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5211
5212 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", 5212
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5212, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5212, "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", 5212, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5213
5214 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", 5214
, ((hfinfo))->abbrev))))
;
5215
5216 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5217 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5218
5219 return pi;
5220}
5221
5222proto_item *
5223proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5224 unsigned start, unsigned length,
5225 const ws_in6_addr *value_ptr,
5226 const char *format, ...)
5227{
5228 proto_item *pi;
5229 va_list ap;
5230
5231 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5232 if (pi != tree) {
5233 va_start(ap, format)__builtin_va_start(ap, format);
5234 proto_tree_set_representation_value(pi, format, ap);
5235 va_end(ap)__builtin_va_end(ap);
5236 }
5237
5238 return pi;
5239}
5240
5241proto_item *
5242proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5243 unsigned start, unsigned length,
5244 const ws_in6_addr *value_ptr,
5245 const char *format, ...)
5246{
5247 proto_item *pi;
5248 va_list ap;
5249
5250 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5251 if (pi != tree) {
5252 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5252, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5253
5254 va_start(ap, format)__builtin_va_start(ap, format);
5255 proto_tree_set_representation(pi, format, ap);
5256 va_end(ap)__builtin_va_end(ap);
5257 }
5258
5259 return pi;
5260}
5261
5262/* Set the FT_IPv6 value */
5263static void
5264proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5265{
5266 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5266, "value != ((void*)0)"
))))
;
5267 ipv6_addr_and_prefix ipv6;
5268 ipv6.addr = *value;
5269 ipv6.prefix = 128;
5270 fvalue_set_ipv6(fi->value, &ipv6);
5271}
5272
5273static void
5274proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5275{
5276 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5277}
5278
5279/* Set the FT_FCWWN value */
5280static void
5281proto_tree_set_fcwwn(field_info *fi, const uint8_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_fcwwn(fi->value, value_ptr);
5285}
5286
5287static void
5288proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5289{
5290 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5291}
5292
5293/* Add a FT_GUID to a proto_tree */
5294proto_item *
5295proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5296 unsigned length, const e_guid_t *value_ptr)
5297{
5298 proto_item *pi;
5299 header_field_info *hfinfo;
5300
5301 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5302
5303 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", 5303
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5303, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5303, "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", 5303, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5304
5305 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", 5305
, ((hfinfo))->abbrev))))
;
5306
5307 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5308 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5309
5310 return pi;
5311}
5312
5313proto_item *
5314proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5315 unsigned start, unsigned length,
5316 const e_guid_t *value_ptr,
5317 const char *format, ...)
5318{
5319 proto_item *pi;
5320 va_list ap;
5321
5322 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5323 if (pi != tree) {
5324 va_start(ap, format)__builtin_va_start(ap, format);
5325 proto_tree_set_representation_value(pi, format, ap);
5326 va_end(ap)__builtin_va_end(ap);
5327 }
5328
5329 return pi;
5330}
5331
5332proto_item *
5333proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5334 unsigned start, unsigned length, const e_guid_t *value_ptr,
5335 const char *format, ...)
5336{
5337 proto_item *pi;
5338 va_list ap;
5339
5340 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5341 if (pi != tree) {
5342 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5342, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5343
5344 va_start(ap, format)__builtin_va_start(ap, format);
5345 proto_tree_set_representation(pi, format, ap);
5346 va_end(ap)__builtin_va_end(ap);
5347 }
5348
5349 return pi;
5350}
5351
5352/* Set the FT_GUID value */
5353static void
5354proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5355{
5356 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5356, "value_ptr != ((void*)0)"
))))
;
5357 fvalue_set_guid(fi->value, value_ptr);
5358}
5359
5360static void
5361proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5362 const unsigned encoding)
5363{
5364 e_guid_t guid;
5365
5366 tvb_get_guid(tvb, start, &guid, encoding);
5367 proto_tree_set_guid(fi, &guid);
5368}
5369
5370/* Add a FT_OID to a proto_tree */
5371proto_item *
5372proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5373 unsigned length, const uint8_t* value_ptr)
5374{
5375 proto_item *pi;
5376 header_field_info *hfinfo;
5377
5378 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5379
5380 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", 5380
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5380, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5380, "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", 5380, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5381
5382 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", 5382
, ((hfinfo))->abbrev))))
;
5383
5384 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5385 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5386
5387 return pi;
5388}
5389
5390proto_item *
5391proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5392 unsigned start, unsigned length,
5393 const uint8_t* value_ptr,
5394 const char *format, ...)
5395{
5396 proto_item *pi;
5397 va_list ap;
5398
5399 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5400 if (pi != tree) {
5401 va_start(ap, format)__builtin_va_start(ap, format);
5402 proto_tree_set_representation_value(pi, format, ap);
5403 va_end(ap)__builtin_va_end(ap);
5404 }
5405
5406 return pi;
5407}
5408
5409proto_item *
5410proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5411 unsigned start, unsigned length, const uint8_t* value_ptr,
5412 const char *format, ...)
5413{
5414 proto_item *pi;
5415 va_list ap;
5416
5417 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5418 if (pi != tree) {
5419 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5419, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5420
5421 va_start(ap, format)__builtin_va_start(ap, format);
5422 proto_tree_set_representation(pi, format, ap);
5423 va_end(ap)__builtin_va_end(ap);
5424 }
5425
5426 return pi;
5427}
5428
5429/* Set the FT_OID value */
5430static void
5431proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5432{
5433 GByteArray *bytes;
5434
5435 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", 5435, "value_ptr != ((void*)0) || length == 0"
))))
;
5436
5437 bytes = g_byte_array_new();
5438 if (length > 0) {
5439 g_byte_array_append(bytes, value_ptr, length);
5440 }
5441 fvalue_set_byte_array(fi->value, bytes);
5442}
5443
5444static void
5445proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5446{
5447 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5448}
5449
5450/* Set the FT_SYSTEM_ID value */
5451static void
5452proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5453{
5454 GByteArray *bytes;
5455
5456 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", 5456, "value_ptr != ((void*)0) || length == 0"
))))
;
5457
5458 bytes = g_byte_array_new();
5459 if (length > 0) {
5460 g_byte_array_append(bytes, value_ptr, length);
5461 }
5462 fvalue_set_byte_array(fi->value, bytes);
5463}
5464
5465static void
5466proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5467{
5468 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5469}
5470
5471/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5472 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5473 * is destroyed. */
5474proto_item *
5475proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5476 int length, const char* value)
5477{
5478 proto_item *pi;
5479 header_field_info *hfinfo;
5480 int item_length;
5481
5482 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", 5482, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5482,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5482, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5483 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5484 /*
5485 * Special case - if the length is 0, skip the test, so that
5486 * we can have an empty string right after the end of the
5487 * packet. (This handles URL-encoded forms where the last field
5488 * has no value so the form ends right after the =.)
5489 *
5490 * XXX - length zero makes sense for FT_STRING, and more or less
5491 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5492 * for FT_STRINGZ (except that a number of fields that should be
5493 * one of the others are actually registered as FT_STRINGZ.)
5494 */
5495 if (item_length != 0)
5496 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5497
5498 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5499
5500 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", 5500
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5500, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5500, "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", 5500, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5501
5502 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", 5502, ((hfinfo))->abbrev))))
;
5503
5504 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5505 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5505, "length >= 0"
))))
;
5506
5507 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", 5507, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5508 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5509
5510 return pi;
5511}
5512
5513proto_item *
5514proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5515 unsigned start, int length, const char* value,
5516 const char *format,
5517 ...)
5518{
5519 proto_item *pi;
5520 va_list ap;
5521
5522 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5523 if (pi != tree) {
5524 va_start(ap, format)__builtin_va_start(ap, format);
5525 proto_tree_set_representation_value(pi, format, ap);
5526 va_end(ap)__builtin_va_end(ap);
5527 }
5528
5529 return pi;
5530}
5531
5532proto_item *
5533proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5534 unsigned start, int length, const char* value,
5535 const char *format, ...)
5536{
5537 proto_item *pi;
5538 va_list ap;
5539
5540 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5541 if (pi != tree) {
5542 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5542, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5543
5544 va_start(ap, format)__builtin_va_start(ap, format);
5545 proto_tree_set_representation(pi, format, ap);
5546 va_end(ap)__builtin_va_end(ap);
5547 }
5548
5549 return pi;
5550}
5551
5552/* Set the FT_STRING value */
5553static void
5554proto_tree_set_string(field_info *fi, const char* value)
5555{
5556 if (value) {
5557 fvalue_set_string(fi->value, value);
5558 } else {
5559 /*
5560 * XXX - why is a null value for a string field
5561 * considered valid?
5562 */
5563 fvalue_set_string(fi->value, "[ Null ]");
5564 }
5565}
5566
5567/* Set the FT_AX25 value */
5568static void
5569proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5570{
5571 fvalue_set_ax25(fi->value, value);
5572}
5573
5574static void
5575proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5576{
5577 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5578}
5579
5580/* Set the FT_VINES value */
5581static void
5582proto_tree_set_vines(field_info *fi, const uint8_t* value)
5583{
5584 fvalue_set_vines(fi->value, value);
5585}
5586
5587static void
5588proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5589{
5590 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5591}
5592
5593/* Add a FT_ETHER to a proto_tree */
5594proto_item *
5595proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5596 unsigned length, const uint8_t* value)
5597{
5598 proto_item *pi;
5599 header_field_info *hfinfo;
5600
5601 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5602
5603 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", 5603
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5603, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5603, "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", 5603, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5604
5605 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",
5605, ((hfinfo))->abbrev))))
;
5606
5607 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5608 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5609
5610 return pi;
5611}
5612
5613proto_item *
5614proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5615 unsigned start, unsigned length, const uint8_t* value,
5616 const char *format, ...)
5617{
5618 proto_item *pi;
5619 va_list ap;
5620
5621 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5622 if (pi != tree) {
5623 va_start(ap, format)__builtin_va_start(ap, format);
5624 proto_tree_set_representation_value(pi, format, ap);
5625 va_end(ap)__builtin_va_end(ap);
5626 }
5627
5628 return pi;
5629}
5630
5631proto_item *
5632proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5633 unsigned start, unsigned length, const uint8_t* value,
5634 const char *format, ...)
5635{
5636 proto_item *pi;
5637 va_list ap;
5638
5639 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5640 if (pi != tree) {
5641 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5641, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5642
5643 va_start(ap, format)__builtin_va_start(ap, format);
5644 proto_tree_set_representation(pi, format, ap);
5645 va_end(ap)__builtin_va_end(ap);
5646 }
5647
5648 return pi;
5649}
5650
5651/* Set the FT_ETHER value */
5652static void
5653proto_tree_set_ether(field_info *fi, const uint8_t* value)
5654{
5655 fvalue_set_ether(fi->value, value);
5656}
5657
5658static void
5659proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5660{
5661 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5662}
5663
5664/* Add a FT_BOOLEAN to a proto_tree */
5665proto_item *
5666proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5667 unsigned length, uint64_t value)
5668{
5669 proto_item *pi;
5670 header_field_info *hfinfo;
5671
5672 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5673
5674 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", 5674
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5674, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5674, "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", 5674, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5675
5676 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"
, 5676, ((hfinfo))->abbrev))))
;
5677
5678 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5679 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5680
5681 return pi;
5682}
5683
5684proto_item *
5685proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5686 tvbuff_t *tvb, unsigned start, unsigned length,
5687 uint64_t value, const char *format, ...)
5688{
5689 proto_item *pi;
5690 va_list ap;
5691
5692 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5693 if (pi != tree) {
5694 va_start(ap, format)__builtin_va_start(ap, format);
5695 proto_tree_set_representation_value(pi, format, ap);
5696 va_end(ap)__builtin_va_end(ap);
5697 }
5698
5699 return pi;
5700}
5701
5702proto_item *
5703proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5704 unsigned start, unsigned length, uint64_t value,
5705 const char *format, ...)
5706{
5707 proto_item *pi;
5708 va_list ap;
5709
5710 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5711 if (pi != tree) {
5712 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5712, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5713
5714 va_start(ap, format)__builtin_va_start(ap, format);
5715 proto_tree_set_representation(pi, format, ap);
5716 va_end(ap)__builtin_va_end(ap);
5717 }
5718
5719 return pi;
5720}
5721
5722/* Set the FT_BOOLEAN value */
5723static void
5724proto_tree_set_boolean(field_info *fi, uint64_t value)
5725{
5726 proto_tree_set_uint64(fi, value);
5727}
5728
5729/* Generate, into "buf", a string showing the bits of a bitfield.
5730 Return a pointer to the character after that string. */
5731static char *
5732other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5733{
5734 int i = 0;
5735 uint64_t bit;
5736 char *p;
5737
5738 p = buf;
5739
5740 /* This is a devel error. It is safer to stop here. */
5741 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5741, "width >= 1"
))))
;
5742
5743 bit = UINT64_C(1)1UL << (width - 1);
5744 for (;;) {
5745 if (mask & bit) {
5746 /* This bit is part of the field. Show its value. */
5747 if (val & bit)
5748 *p++ = '1';
5749 else
5750 *p++ = '0';
5751 } else {
5752 /* This bit is not part of the field. */
5753 *p++ = '.';
5754 }
5755 bit >>= 1;
5756 i++;
5757 if (i >= width)
5758 break;
5759 if (i % 4 == 0)
5760 *p++ = ' ';
5761 }
5762 *p = '\0';
5763 return p;
5764}
5765
5766static char *
5767decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5768{
5769 char *p;
5770
5771 p = other_decode_bitfield_value(buf, val, mask, width);
5772 p = g_stpcpy(p, " = ");
5773
5774 return p;
5775}
5776
5777static char *
5778other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5779{
5780 int i = 0;
5781 uint64_t bit;
5782 char *p;
5783
5784 p = buf;
5785
5786 /* This is a devel error. It is safer to stop here. */
5787 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5787, "width >= 1"
))))
;
5788
5789 bit = UINT64_C(1)1UL << (width - 1);
5790 for (;;) {
5791 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5792 (mask & bit)) {
5793 /* This bit is part of the field. Show its value. */
5794 if (val & bit)
5795 *p++ = '1';
5796 else
5797 *p++ = '0';
5798 } else {
5799 /* This bit is not part of the field. */
5800 *p++ = '.';
5801 }
5802 bit >>= 1;
5803 i++;
5804 if (i >= width)
5805 break;
5806 if (i % 4 == 0)
5807 *p++ = ' ';
5808 }
5809
5810 *p = '\0';
5811 return p;
5812}
5813
5814static char *
5815decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5816{
5817 char *p;
5818
5819 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5820 p = g_stpcpy(p, " = ");
5821
5822 return p;
5823}
5824
5825/* Add a FT_FLOAT to a proto_tree */
5826proto_item *
5827proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5828 unsigned length, float value)
5829{
5830 proto_item *pi;
5831 header_field_info *hfinfo;
5832
5833 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5834
5835 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", 5835
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5835, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5835, "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", 5835, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5836
5837 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",
5837, ((hfinfo))->abbrev))))
;
5838
5839 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5840 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5841
5842 return pi;
5843}
5844
5845proto_item *
5846proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5847 unsigned start, unsigned length, float value,
5848 const char *format, ...)
5849{
5850 proto_item *pi;
5851 va_list ap;
5852
5853 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5854 if (pi != tree) {
5855 va_start(ap, format)__builtin_va_start(ap, format);
5856 proto_tree_set_representation_value(pi, format, ap);
5857 va_end(ap)__builtin_va_end(ap);
5858 }
5859
5860 return pi;
5861}
5862
5863proto_item *
5864proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5865 unsigned start, unsigned length, float value,
5866 const char *format, ...)
5867{
5868 proto_item *pi;
5869 va_list ap;
5870
5871 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5872 if (pi != tree) {
5873 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5873, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5874
5875 va_start(ap, format)__builtin_va_start(ap, format);
5876 proto_tree_set_representation(pi, format, ap);
5877 va_end(ap)__builtin_va_end(ap);
5878 }
5879
5880 return pi;
5881}
5882
5883/* Set the FT_FLOAT value */
5884static void
5885proto_tree_set_float(field_info *fi, float value)
5886{
5887 fvalue_set_floating(fi->value, value);
5888}
5889
5890/* Add a FT_DOUBLE to a proto_tree */
5891proto_item *
5892proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5893 unsigned length, double value)
5894{
5895 proto_item *pi;
5896 header_field_info *hfinfo;
5897
5898 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5899
5900 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", 5900
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5900, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5900, "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", 5900, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5901
5902 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"
, 5902, ((hfinfo))->abbrev))))
;
5903
5904 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5905 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5906
5907 return pi;
5908}
5909
5910proto_item *
5911proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5912 unsigned start, unsigned length, double value,
5913 const char *format, ...)
5914{
5915 proto_item *pi;
5916 va_list ap;
5917
5918 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5919 if (pi != tree) {
5920 va_start(ap, format)__builtin_va_start(ap, format);
5921 proto_tree_set_representation_value(pi, format, ap);
5922 va_end(ap)__builtin_va_end(ap);
5923 }
5924
5925 return pi;
5926}
5927
5928proto_item *
5929proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5930 unsigned start, unsigned length, double value,
5931 const char *format, ...)
5932{
5933 proto_item *pi;
5934 va_list ap;
5935
5936 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5937 if (pi != tree) {
5938 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5938, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5939
5940 va_start(ap, format)__builtin_va_start(ap, format);
5941 proto_tree_set_representation(pi, format, ap);
5942 va_end(ap)__builtin_va_end(ap);
5943 }
5944
5945 return pi;
5946}
5947
5948/* Set the FT_DOUBLE value */
5949static void
5950proto_tree_set_double(field_info *fi, double value)
5951{
5952 fvalue_set_floating(fi->value, value);
5953}
5954
5955/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5956proto_item *
5957proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5958 unsigned length, uint32_t value)
5959{
5960 proto_item *pi = NULL((void*)0);
5961 header_field_info *hfinfo;
5962
5963 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5964
5965 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", 5965
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5965, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5965, "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", 5965, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5966
5967 switch (hfinfo->type) {
5968 case FT_CHAR:
5969 case FT_UINT8:
5970 case FT_UINT16:
5971 case FT_UINT24:
5972 case FT_UINT32:
5973 case FT_FRAMENUM:
5974 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5975 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5976 break;
5977
5978 default:
5979 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)
5980 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)
;
5981 }
5982
5983 return pi;
5984}
5985
5986proto_item *
5987proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5988 unsigned start, unsigned length, uint32_t value,
5989 const char *format, ...)
5990{
5991 proto_item *pi;
5992 va_list ap;
5993
5994 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5995 if (pi != tree) {
5996 va_start(ap, format)__builtin_va_start(ap, format);
5997 proto_tree_set_representation_value(pi, format, ap);
5998 va_end(ap)__builtin_va_end(ap);
5999 }
6000
6001 return pi;
6002}
6003
6004proto_item *
6005proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6006 unsigned start, unsigned length, uint32_t value,
6007 const char *format, ...)
6008{
6009 proto_item *pi;
6010 va_list ap;
6011
6012 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6013 if (pi != tree) {
6014 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6014, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6015
6016 va_start(ap, format)__builtin_va_start(ap, format);
6017 proto_tree_set_representation(pi, format, ap);
6018 va_end(ap)__builtin_va_end(ap);
6019 }
6020
6021 return pi;
6022}
6023
6024/* Set the FT_UINT{8,16,24,32} value */
6025static void
6026proto_tree_set_uint(field_info *fi, uint32_t value)
6027{
6028 const header_field_info *hfinfo;
6029 uint32_t integer;
6030
6031 hfinfo = fi->hfinfo;
6032 integer = value;
6033
6034 if (hfinfo->bitmask) {
6035 /* Mask out irrelevant portions */
6036 integer &= (uint32_t)(hfinfo->bitmask);
6037
6038 /* Shift bits */
6039 integer >>= hfinfo_bitshift(hfinfo);
6040
6041 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6042 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)
;
6043 }
6044
6045 fvalue_set_uinteger(fi->value, integer);
6046}
6047
6048/* Add FT_UINT{40,48,56,64} to a proto_tree */
6049proto_item *
6050proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6051 unsigned length, uint64_t value)
6052{
6053 proto_item *pi = NULL((void*)0);
6054 header_field_info *hfinfo;
6055
6056 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6057
6058 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", 6058
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6058, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6058, "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", 6058, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6059
6060 switch (hfinfo->type) {
6061 case FT_UINT40:
6062 case FT_UINT48:
6063 case FT_UINT56:
6064 case FT_UINT64:
6065 case FT_FRAMENUM:
6066 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6067 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6068 break;
6069
6070 default:
6071 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)
6072 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)
;
6073 }
6074
6075 return pi;
6076}
6077
6078proto_item *
6079proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6080 unsigned start, unsigned length, uint64_t value,
6081 const char *format, ...)
6082{
6083 proto_item *pi;
6084 va_list ap;
6085
6086 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6087 if (pi != tree) {
6088 va_start(ap, format)__builtin_va_start(ap, format);
6089 proto_tree_set_representation_value(pi, format, ap);
6090 va_end(ap)__builtin_va_end(ap);
6091 }
6092
6093 return pi;
6094}
6095
6096proto_item *
6097proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6098 unsigned start, unsigned length, uint64_t value,
6099 const char *format, ...)
6100{
6101 proto_item *pi;
6102 va_list ap;
6103
6104 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6105 if (pi != tree) {
6106 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6106, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6107
6108 va_start(ap, format)__builtin_va_start(ap, format);
6109 proto_tree_set_representation(pi, format, ap);
6110 va_end(ap)__builtin_va_end(ap);
6111 }
6112
6113 return pi;
6114}
6115
6116/* Set the FT_UINT{40,48,56,64} value */
6117static void
6118proto_tree_set_uint64(field_info *fi, uint64_t value)
6119{
6120 const header_field_info *hfinfo;
6121 uint64_t integer;
6122
6123 hfinfo = fi->hfinfo;
6124 integer = value;
6125
6126 if (hfinfo->bitmask) {
6127 /* Mask out irrelevant portions */
6128 integer &= hfinfo->bitmask;
6129
6130 /* Shift bits */
6131 integer >>= hfinfo_bitshift(hfinfo);
6132
6133 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6134 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)
;
6135 }
6136
6137 fvalue_set_uinteger64(fi->value, integer);
6138}
6139
6140/* Add FT_INT{8,16,24,32} to a proto_tree */
6141proto_item *
6142proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6143 unsigned length, int32_t value)
6144{
6145 proto_item *pi = NULL((void*)0);
6146 header_field_info *hfinfo;
6147
6148 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6149
6150 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", 6150
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6150, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6150, "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", 6150, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6151
6152 switch (hfinfo->type) {
6153 case FT_INT8:
6154 case FT_INT16:
6155 case FT_INT24:
6156 case FT_INT32:
6157 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6158 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6159 break;
6160
6161 default:
6162 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)
6163 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6164 }
6165
6166 return pi;
6167}
6168
6169proto_item *
6170proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6171 unsigned start, unsigned length, int32_t value,
6172 const char *format, ...)
6173{
6174 proto_item *pi;
6175 va_list ap;
6176
6177 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6178 if (pi != tree) {
6179 va_start(ap, format)__builtin_va_start(ap, format);
6180 proto_tree_set_representation_value(pi, format, ap);
6181 va_end(ap)__builtin_va_end(ap);
6182 }
6183
6184 return pi;
6185}
6186
6187proto_item *
6188proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6189 unsigned start, unsigned length, int32_t value,
6190 const char *format, ...)
6191{
6192 proto_item *pi;
6193 va_list ap;
6194
6195 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6196 if (pi != tree) {
6197 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6197, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6198
6199 va_start(ap, format)__builtin_va_start(ap, format);
6200 proto_tree_set_representation(pi, format, ap);
6201 va_end(ap)__builtin_va_end(ap);
6202 }
6203
6204 return pi;
6205}
6206
6207/* Set the FT_INT{8,16,24,32} value */
6208static void
6209proto_tree_set_int(field_info *fi, int32_t value)
6210{
6211 const header_field_info *hfinfo;
6212 uint32_t integer;
6213 int no_of_bits;
6214
6215 hfinfo = fi->hfinfo;
6216 integer = (uint32_t) value;
6217
6218 if (hfinfo->bitmask) {
6219 /* Mask out irrelevant portions */
6220 integer &= (uint32_t)(hfinfo->bitmask);
6221
6222 /* Shift bits */
6223 integer >>= hfinfo_bitshift(hfinfo);
6224
6225 no_of_bits = ws_count_ones(hfinfo->bitmask);
6226 integer = ws_sign_ext32(integer, no_of_bits);
6227
6228 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6229 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)
;
6230 }
6231
6232 fvalue_set_sinteger(fi->value, integer);
6233}
6234
6235/* Add FT_INT{40,48,56,64} to a proto_tree */
6236proto_item *
6237proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6238 unsigned length, int64_t value)
6239{
6240 proto_item *pi = NULL((void*)0);
6241 header_field_info *hfinfo;
6242
6243 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6244
6245 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", 6245
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6245, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6245, "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", 6245, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6246
6247 switch (hfinfo->type) {
6248 case FT_INT40:
6249 case FT_INT48:
6250 case FT_INT56:
6251 case FT_INT64:
6252 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6253 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6254 break;
6255
6256 default:
6257 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)
6258 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6259 }
6260
6261 return pi;
6262}
6263
6264proto_item *
6265proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6266 unsigned start, unsigned length, int64_t value,
6267 const char *format, ...)
6268{
6269 proto_item *pi;
6270 va_list ap;
6271
6272 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6273 if (pi != tree) {
6274 va_start(ap, format)__builtin_va_start(ap, format);
6275 proto_tree_set_representation_value(pi, format, ap);
6276 va_end(ap)__builtin_va_end(ap);
6277 }
6278
6279 return pi;
6280}
6281
6282/* Set the FT_INT{40,48,56,64} value */
6283static void
6284proto_tree_set_int64(field_info *fi, int64_t value)
6285{
6286 const header_field_info *hfinfo;
6287 uint64_t integer;
6288 int no_of_bits;
6289
6290 hfinfo = fi->hfinfo;
6291 integer = value;
6292
6293 if (hfinfo->bitmask) {
6294 /* Mask out irrelevant portions */
6295 integer &= hfinfo->bitmask;
6296
6297 /* Shift bits */
6298 integer >>= hfinfo_bitshift(hfinfo);
6299
6300 no_of_bits = ws_count_ones(hfinfo->bitmask);
6301 integer = ws_sign_ext64(integer, no_of_bits);
6302
6303 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6304 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)
;
6305 }
6306
6307 fvalue_set_sinteger64(fi->value, integer);
6308}
6309
6310proto_item *
6311proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6312 unsigned start, unsigned length, int64_t value,
6313 const char *format, ...)
6314{
6315 proto_item *pi;
6316 va_list ap;
6317
6318 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6319 if (pi != tree) {
6320 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6320, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6321
6322 va_start(ap, format)__builtin_va_start(ap, format);
6323 proto_tree_set_representation(pi, format, ap);
6324 va_end(ap)__builtin_va_end(ap);
6325 }
6326
6327 return pi;
6328}
6329
6330/* Add a FT_EUI64 to a proto_tree */
6331proto_item *
6332proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6333 unsigned length, const uint64_t value)
6334{
6335 proto_item *pi;
6336 header_field_info *hfinfo;
6337
6338 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6339
6340 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", 6340
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6340, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6340, "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", 6340, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6341
6342 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",
6342, ((hfinfo))->abbrev))))
;
6343
6344 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6345 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6346
6347 return pi;
6348}
6349
6350proto_item *
6351proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6352 unsigned start, unsigned length, const uint64_t value,
6353 const char *format, ...)
6354{
6355 proto_item *pi;
6356 va_list ap;
6357
6358 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6359 if (pi != tree) {
6360 va_start(ap, format)__builtin_va_start(ap, format);
6361 proto_tree_set_representation_value(pi, format, ap);
6362 va_end(ap)__builtin_va_end(ap);
6363 }
6364
6365 return pi;
6366}
6367
6368proto_item *
6369proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6370 unsigned start, unsigned length, const uint64_t value,
6371 const char *format, ...)
6372{
6373 proto_item *pi;
6374 va_list ap;
6375
6376 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6377 if (pi != tree) {
6378 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6378, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6379
6380 va_start(ap, format)__builtin_va_start(ap, format);
6381 proto_tree_set_representation(pi, format, ap);
6382 va_end(ap)__builtin_va_end(ap);
6383 }
6384
6385 return pi;
6386}
6387
6388/* Set the FT_EUI64 value */
6389static void
6390proto_tree_set_eui64(field_info *fi, const uint64_t value)
6391{
6392 uint8_t v[FT_EUI64_LEN8];
6393 phtonu64(v, value);
6394 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6395}
6396
6397static void
6398proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6399{
6400 if (encoding)
6401 {
6402 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6403 } else {
6404 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6405 }
6406}
6407
6408proto_item *
6409proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6410 const mac_hf_list_t *list_generic,
6411 int idx, tvbuff_t *tvb,
6412 proto_tree *tree, unsigned offset)
6413{
6414 uint8_t addr[6];
6415 const char *addr_name = NULL((void*)0);
6416 const char *oui_name = NULL((void*)0);
6417 proto_item *addr_item = NULL((void*)0);
6418 proto_tree *addr_tree = NULL((void*)0);
6419 proto_item *ret_val = NULL((void*)0);
6420
6421 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6422 return NULL((void*)0);
6423 }
6424
6425 /* Resolve what we can of the address */
6426 tvb_memcpy(tvb, addr, offset, sizeof addr);
6427 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6428 addr_name = get_ether_name(addr);
6429 }
6430 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6431 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6432 }
6433
6434 /* Add the item for the specific address type */
6435 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6436 if (idx >= 0) {
6437 addr_tree = proto_item_add_subtree(ret_val, idx);
6438 }
6439 else {
6440 addr_tree = tree;
6441 }
6442
6443 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6444 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6445 tvb, offset, 6, addr_name);
6446 proto_item_set_generated(addr_item);
6447 proto_item_set_hidden(addr_item);
6448 }
6449
6450 if (list_specific->hf_oui != NULL((void*)0)) {
6451 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6452 proto_item_set_generated(addr_item);
6453 proto_item_set_hidden(addr_item);
6454
6455 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6456 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6457 proto_item_set_generated(addr_item);
6458 proto_item_set_hidden(addr_item);
6459 }
6460 }
6461
6462 if (list_specific->hf_lg != NULL((void*)0)) {
6463 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6464 }
6465 if (list_specific->hf_ig != NULL((void*)0)) {
6466 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6467 }
6468
6469 /* Were we given a list for generic address fields? If not, stop here */
6470 if (list_generic == NULL((void*)0)) {
6471 return ret_val;
6472 }
6473
6474 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6475 proto_item_set_hidden(addr_item);
6476
6477 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6478 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6479 tvb, offset, 6, addr_name);
6480 proto_item_set_generated(addr_item);
6481 proto_item_set_hidden(addr_item);
6482 }
6483
6484 if (list_generic->hf_oui != NULL((void*)0)) {
6485 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6486 proto_item_set_generated(addr_item);
6487 proto_item_set_hidden(addr_item);
6488
6489 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6490 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6491 proto_item_set_generated(addr_item);
6492 proto_item_set_hidden(addr_item);
6493 }
6494 }
6495
6496 if (list_generic->hf_lg != NULL((void*)0)) {
6497 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6498 proto_item_set_hidden(addr_item);
6499 }
6500 if (list_generic->hf_ig != NULL((void*)0)) {
6501 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6502 proto_item_set_hidden(addr_item);
6503 }
6504 return ret_val;
6505}
6506
6507static proto_item *
6508proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6509{
6510 proto_node *pnode, *tnode, *sibling;
6511 field_info *tfi;
6512 unsigned depth = 1;
6513
6514 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6514, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6515
6516 /*
6517 * Restrict our depth. proto_tree_traverse_pre_order and
6518 * proto_tree_traverse_post_order (and possibly others) are recursive
6519 * so we need to be mindful of our stack size.
6520 */
6521 if (tree->first_child == NULL((void*)0)) {
6522 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6523 depth++;
6524 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6525 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__)), 6528)))
6526 "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__)), 6528)))
6527 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__)), 6528)))
6528 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__)), 6528)))
;
6529 }
6530 }
6531 }
6532
6533 /*
6534 * Make sure "tree" is ready to have subtrees under it, by
6535 * checking whether it's been given an ett_ value.
6536 *
6537 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6538 * node of the protocol tree. That node is not displayed,
6539 * so it doesn't need an ett_ value to remember whether it
6540 * was expanded.
6541 */
6542 tnode = tree;
6543 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6544 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6545 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"
, 6546)
6546 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"
, 6546)
;
6547 /* XXX - is it safe to continue here? */
6548 }
6549
6550 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6551 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6552 pnode->parent = tnode;
6553 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6554 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6555 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6556
6557 if (tnode->last_child != NULL((void*)0)) {
6558 sibling = tnode->last_child;
6559 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6559, "sibling->next == ((void*)0)"
))))
;
6560 sibling->next = pnode;
6561 } else
6562 tnode->first_child = pnode;
6563 tnode->last_child = pnode;
6564
6565 /* We should not be adding a fake node for an interesting field */
6566 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", 6566, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6567
6568 /* XXX - Should the proto_item have a header_field_info member, at least
6569 * for faked items, to know what hfi was faked? (Some dissectors look at
6570 * the tree items directly.)
6571 */
6572 return (proto_item *)pnode;
6573}
6574
6575/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6576static proto_item *
6577proto_tree_add_node(proto_tree *tree, field_info *fi)
6578{
6579 proto_node *pnode, *tnode, *sibling;
6580 field_info *tfi;
6581 unsigned depth = 1;
6582
6583 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6583, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6584
6585 /*
6586 * Restrict our depth. proto_tree_traverse_pre_order and
6587 * proto_tree_traverse_post_order (and possibly others) are recursive
6588 * so we need to be mindful of our stack size.
6589 */
6590 if (tree->first_child == NULL((void*)0)) {
6591 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6592 depth++;
6593 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6594 fvalue_free(fi->value);
6595 fi->value = NULL((void*)0);
6596 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__)), 6599)))
6597 "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__)), 6599)))
6598 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__)), 6599)))
6599 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__)), 6599)))
;
6600 }
6601 }
6602 }
6603
6604 /*
6605 * Make sure "tree" is ready to have subtrees under it, by
6606 * checking whether it's been given an ett_ value.
6607 *
6608 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6609 * node of the protocol tree. That node is not displayed,
6610 * so it doesn't need an ett_ value to remember whether it
6611 * was expanded.
6612 */
6613 tnode = tree;
6614 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6615 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6616 /* Since we are not adding fi to a node, its fvalue won't get
6617 * freed by proto_tree_free_node(), so free it now.
6618 */
6619 fvalue_free(fi->value);
6620 fi->value = NULL((void*)0);
6621 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", 6622)
6622 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", 6622)
;
6623 /* XXX - is it safe to continue here? */
6624 }
6625
6626 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6627 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6628 pnode->parent = tnode;
6629 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6630 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6631 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6632
6633 if (tnode->last_child != NULL((void*)0)) {
6634 sibling = tnode->last_child;
6635 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6635, "sibling->next == ((void*)0)"
))))
;
6636 sibling->next = pnode;
6637 } else
6638 tnode->first_child = pnode;
6639 tnode->last_child = pnode;
6640
6641 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6642
6643 return (proto_item *)pnode;
6644}
6645
6646
6647/* Generic way to allocate field_info and add to proto_tree.
6648 * Sets *pfi to address of newly-allocated field_info struct */
6649static proto_item *
6650proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6651 int *length)
6652{
6653 proto_item *pi;
6654 field_info *fi;
6655 int item_length;
6656
6657 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6658 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6659 pi = proto_tree_add_node(tree, fi);
6660
6661 return pi;
6662}
6663
6664/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6665 * Eventually this should replace the other function.
6666 * Sets *pfi to address of newly-allocated field_info struct */
6667static proto_item *
6668proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6669 unsigned *length)
6670{
6671 proto_item *pi;
6672 field_info *fi;
6673 unsigned item_length;
6674
6675 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6676 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6677 pi = proto_tree_add_node(tree, fi);
6678
6679 return pi;
6680}
6681
6682static void
6683get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6684 int *item_length, const unsigned encoding)
6685{
6686 int length_remaining;
6687
6688 /*
6689 * We only allow a null tvbuff if the item has a zero length,
6690 * i.e. if there's no data backing it.
6691 */
6692 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", 6692, "tvb != ((void*)0) || *length == 0"
))))
;
6693
6694 /*
6695 * XXX - in some protocols, there are 32-bit unsigned length
6696 * fields, so lengths in protocol tree and tvbuff routines
6697 * should really be unsigned. We should have, for those
6698 * field types for which "to the end of the tvbuff" makes sense,
6699 * additional routines that take no length argument and
6700 * add fields that run to the end of the tvbuff.
6701 */
6702 if (*length == -1) {
6703 /*
6704 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6705 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6706 * of -1 means "set the length to what remains in the
6707 * tvbuff".
6708 *
6709 * The assumption is either that
6710 *
6711 * 1) the length of the item can only be determined
6712 * by dissection (typically true of items with
6713 * subitems, which are probably FT_NONE or
6714 * FT_PROTOCOL)
6715 *
6716 * or
6717 *
6718 * 2) if the tvbuff is "short" (either due to a short
6719 * snapshot length or due to lack of reassembly of
6720 * fragments/segments/whatever), we want to display
6721 * what's available in the field (probably FT_BYTES
6722 * or FT_STRING) and then throw an exception later
6723 *
6724 * or
6725 *
6726 * 3) the field is defined to be "what's left in the
6727 * packet"
6728 *
6729 * so we set the length to what remains in the tvbuff so
6730 * that, if we throw an exception while dissecting, it
6731 * has what is probably the right value.
6732 *
6733 * For FT_STRINGZ, it means "the string is null-terminated,
6734 * not null-padded; set the length to the actual length
6735 * of the string", and if the tvbuff if short, we just
6736 * throw an exception.
6737 *
6738 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6739 * it means "find the end of the string",
6740 * and if the tvbuff if short, we just throw an exception.
6741 *
6742 * It's not valid for any other type of field. For those
6743 * fields, we treat -1 the same way we treat other
6744 * negative values - we assume the length is a Really
6745 * Big Positive Number, and throw a ReportedBoundsError
6746 * exception, under the assumption that the Really Big
6747 * Length would run past the end of the packet.
6748 */
6749 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
))
)) {
6750 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6751 /*
6752 * Leave the length as -1, so our caller knows
6753 * it was -1.
6754 */
6755 *item_length = *length;
6756 return;
6757 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6758 switch (tvb_get_uint8(tvb, start) >> 6)
6759 {
6760 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6761 *item_length = 1;
6762 break;
6763 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6764 *item_length = 2;
6765 break;
6766 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6767 *item_length = 4;
6768 break;
6769 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6770 *item_length = 8;
6771 break;
6772 }
6773 }
6774 }
6775
6776 switch (hfinfo->type) {
6777
6778 case FT_PROTOCOL:
6779 case FT_NONE:
6780 case FT_BYTES:
6781 case FT_STRING:
6782 case FT_STRINGZPAD:
6783 case FT_STRINGZTRUNC:
6784 /*
6785 * We allow FT_PROTOCOLs to be zero-length -
6786 * for example, an ONC RPC NULL procedure has
6787 * neither arguments nor reply, so the
6788 * payload for that protocol is empty.
6789 *
6790 * We also allow the others to be zero-length -
6791 * because that's the way the code has been for a
6792 * long, long time.
6793 *
6794 * However, we want to ensure that the start
6795 * offset is not *past* the byte past the end
6796 * of the tvbuff: we throw an exception in that
6797 * case.
6798 */
6799 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6800 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6800, "*length >= 0"
))))
;
6801 break;
6802
6803 case FT_STRINGZ:
6804 /*
6805 * Leave the length as -1, so our caller knows
6806 * it was -1.
6807 */
6808 break;
6809
6810 default:
6811 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6812 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6812))
;
6813 }
6814 *item_length = *length;
6815 } else {
6816 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6817 /*
6818 * These types are for interior nodes of the
6819 * tree, and don't have data associated with
6820 * them; if the length is negative (XXX - see
6821 * above) or goes past the end of the tvbuff,
6822 * cut it short at the end of the tvbuff.
6823 * That way, if this field is selected in
6824 * Wireshark, we don't highlight stuff past
6825 * the end of the data.
6826 *
6827 * If we don't have a tvb, then length must be zero,
6828 * per the DISSECTOR_ASSERT() above.
6829 *
6830 * If we do have a tvb, and the length requested is
6831 * nonzero, we want to ensure that the start offset
6832 * is not *past* the byte past the end of the tvbuff
6833 * data: we throw an exception in that case as above.
6834 */
6835 if (tvb && *length) {
6836 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6837 if (*length < 0 ||
6838 (*length > 0 &&
6839 (length_remaining < *length)))
6840 *length = length_remaining;
6841 }
6842 }
6843 *item_length = *length;
6844 if (*item_length < 0) {
6845 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6846 }
6847 }
6848}
6849
6850static void
6851get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6852 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6853{
6854 unsigned length_remaining;
6855
6856 /*
6857 * We only allow a null tvbuff if the item has a zero length,
6858 * i.e. if there's no data backing it.
6859 */
6860 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", 6860, "tvb != ((void*)0) || *length == 0"
))))
;
6861
6862
6863 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6864 /*
6865 * These types are for interior nodes of the
6866 * tree, and don't have data associated with
6867 * them; if the length is negative (XXX - see
6868 * above) or goes past the end of the tvbuff,
6869 * cut it short at the end of the tvbuff.
6870 * That way, if this field is selected in
6871 * Wireshark, we don't highlight stuff past
6872 * the end of the data.
6873 *
6874 * If we don't have a tvb, then length must be zero,
6875 * per the DISSECTOR_ASSERT() above.
6876 *
6877 * If we do have a tvb, and the length requested is
6878 * nonzero, we want to ensure that the start offset
6879 * is not *past* the byte past the end of the tvbuff
6880 * data: we throw an exception in that case as above.
6881 * (If the length requested is zero, then it's quite
6882 * likely that the start offset is the byte past the
6883 * end, but that's ok.)
6884 */
6885 if (tvb && *length) {
6886 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6887 if (length_remaining < *length) {
6888 *length = length_remaining;
6889 }
6890 }
6891 }
6892 *item_length = *length;
6893}
6894
6895static int
6896get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6897 int length, unsigned item_length, const int encoding)
6898{
6899 uint32_t n;
6900
6901 /*
6902 * We need to get the correct item length here.
6903 * That's normally done by proto_tree_new_item(),
6904 * but we won't be calling it.
6905 */
6906 switch (hfinfo->type) {
6907
6908 case FT_NONE:
6909 case FT_PROTOCOL:
6910 case FT_BYTES:
6911 /*
6912 * The length is the specified length.
6913 */
6914 break;
6915
6916 case FT_UINT_BYTES:
6917 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6918 item_length += n;
6919 if ((int)item_length < length) {
6920 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6921 }
6922 break;
6923
6924 /* XXX - make these just FT_UINT? */
6925 case FT_UINT8:
6926 case FT_UINT16:
6927 case FT_UINT24:
6928 case FT_UINT32:
6929 case FT_UINT40:
6930 case FT_UINT48:
6931 case FT_UINT56:
6932 case FT_UINT64:
6933 /* XXX - make these just FT_INT? */
6934 case FT_INT8:
6935 case FT_INT16:
6936 case FT_INT24:
6937 case FT_INT32:
6938 case FT_INT40:
6939 case FT_INT48:
6940 case FT_INT56:
6941 case FT_INT64:
6942 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6943 if (length < -1) {
6944 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6945 }
6946 if (length == -1) {
6947 uint64_t dummy;
6948 /* This can throw an exception */
6949 /* XXX - do this without fetching the varint? */
6950 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6951 if (length == 0) {
6952 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6953 }
6954 }
6955 item_length = length;
6956 break;
6957 }
6958
6959 /*
6960 * The length is the specified length.
6961 */
6962 break;
6963
6964 case FT_BOOLEAN:
6965 case FT_CHAR:
6966 case FT_IPv4:
6967 case FT_IPXNET:
6968 case FT_IPv6:
6969 case FT_FCWWN:
6970 case FT_AX25:
6971 case FT_VINES:
6972 case FT_ETHER:
6973 case FT_EUI64:
6974 case FT_GUID:
6975 case FT_OID:
6976 case FT_REL_OID:
6977 case FT_SYSTEM_ID:
6978 case FT_FLOAT:
6979 case FT_DOUBLE:
6980 case FT_STRING:
6981 /*
6982 * The length is the specified length.
6983 */
6984 break;
6985
6986 case FT_STRINGZ:
6987 if (length < -1) {
6988 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6989 }
6990 if (length == -1) {
6991 /* This can throw an exception */
6992 item_length = tvb_strsize_enc(tvb, start, encoding);
6993 }
6994 break;
6995
6996 case FT_UINT_STRING:
6997 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6998 item_length += n;
6999 if ((int)item_length < length) {
7000 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7001 }
7002 break;
7003
7004 case FT_STRINGZPAD:
7005 case FT_STRINGZTRUNC:
7006 case FT_ABSOLUTE_TIME:
7007 case FT_RELATIVE_TIME:
7008 case FT_IEEE_11073_SFLOAT:
7009 case FT_IEEE_11073_FLOAT:
7010 /*
7011 * The length is the specified length.
7012 */
7013 break;
7014
7015 default:
7016 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
))
7017 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
))
7018 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
))
7019 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
))
;
7020 break;
7021 }
7022 return item_length;
7023}
7024
7025// This was arbitrarily chosen, but if you're adding 50K items to the tree
7026// without advancing the offset you should probably take a long, hard look
7027// at what you're doing.
7028// We *could* make this a configurable option, but I (Gerald) would like to
7029// avoid adding yet another nerd knob.
7030# define PROTO_TREE_MAX_IDLE50000 50000
7031static field_info *
7032new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7033 const unsigned start, const int item_length)
7034{
7035 field_info *fi;
7036
7037 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7038
7039 fi->hfinfo = hfinfo;
7040 fi->start = start;
7041 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7042 /* add the data source tvbuff */
7043 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7044
7045 // If our start offset hasn't advanced after adding many items it probably
7046 // means we're in a large or infinite loop.
7047 if (fi->start > 0) {
7048 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7049 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7050 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7051 if (wireshark_abort_on_too_many_items) {
7052 ws_error("Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7053
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7053 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7053
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7054 }
7055 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7056 * but if not, we should hit the max item error earlier,
7057 * so we shouldn't need to reset the tree count to
7058 * ensure that the exception handler can add the item. */
7059 THROW_MESSAGE(DissectorError,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7060 wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7061 "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
7062 hfinfo->abbrev, PROTO_TREE_MAX_IDLE))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)))
;
7063 }
7064 } else {
7065 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7066 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7067 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7068 }
7069 }
7070 fi->length = item_length;
7071 fi->tree_type = -1;
7072 fi->flags = 0;
7073 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7074 /* If the tree is not visible, set the item hidden, unless we
7075 * need the representation or length and can't fake them.
7076 */
7077 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7078 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7079 }
7080 }
7081 fi->value = fvalue_new(fi->hfinfo->type);
7082 fi->rep = NULL((void*)0);
7083
7084 fi->appendix_start = 0;
7085 fi->appendix_length = 0;
7086
7087 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7088 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7089
7090 return fi;
7091}
7092
7093static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7094{
7095 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7096 return 0;
7097 }
7098
7099 /* Search for field name */
7100 char *ptr = strstr(representation, hfinfo->name);
7101 if (!ptr) {
7102 return 0;
7103 }
7104
7105 /* Check if field name ends with the ": " delimiter */
7106 ptr += strlen(hfinfo->name);
7107 if (strncmp(ptr, ": ", 2) == 0) {
7108 ptr += 2;
7109 }
7110
7111 /* Return offset to after field name */
7112 return ptr - representation;
7113}
7114
7115static size_t label_find_name_pos(const item_label_t *rep)
7116{
7117 size_t name_pos = 0;
7118
7119 /* If the value_pos is too small or too large, we can't find the expected format */
7120 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7121 return 0;
7122 }
7123
7124 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7125 if (rep->representation[rep->value_pos-2] == ':') {
7126 name_pos = rep->value_pos - 2;
7127 }
7128
7129 return name_pos;
7130}
7131
7132/* If the protocol tree is to be visible, set the representation of a
7133 proto_tree entry with the name of the field for the item and with
7134 the value formatted with the supplied printf-style format and
7135 argument list. */
7136static void
7137proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7138{
7139 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7139, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7140
7141 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7142 * items string representation */
7143 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7144 size_t name_pos, ret = 0;
7145 char *str;
7146 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7147 const header_field_info *hf;
7148
7149 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7149, "fi"))))
;
7150
7151 hf = fi->hfinfo;
7152
7153 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;
;
7154 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))
)) {
7155 uint64_t val;
7156 char *p;
7157
7158 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)
)
7159 val = fvalue_get_uinteger(fi->value);
7160 else
7161 val = fvalue_get_uinteger64(fi->value);
7162
7163 val <<= hfinfo_bitshift(hf);
7164
7165 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7166 ret = (p - fi->rep->representation);
7167 }
7168
7169 /* put in the hf name */
7170 name_pos = ret = label_concat(fi->rep->representation, ret, (const uint8_t*)hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)hf->name, 0)
;
7171
7172 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7173 /* If possible, Put in the value of the string */
7174 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7175 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"
, 7175, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7176 fi->rep->value_pos = ret;
7177 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7178 if (ret >= ITEM_LABEL_LENGTH240) {
7179 /* Uh oh, we don't have enough room. Tell the user
7180 * that the field is truncated.
7181 */
7182 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7183 }
7184 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7185 }
7186}
7187
7188/* If the protocol tree is to be visible, set the representation of a
7189 proto_tree entry with the representation formatted with the supplied
7190 printf-style format and argument list. */
7191static void
7192proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7193{
7194 size_t ret; /*tmp return value */
7195 char *str;
7196 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7197
7198 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7198, "fi"))))
;
7199
7200 if (!proto_item_is_hidden(pi)) {
7201 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;
;
7202
7203 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7204 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"
, 7204, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7205 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7206 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7207 if (ret >= ITEM_LABEL_LENGTH240) {
7208 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7209 size_t name_pos = label_find_name_pos(fi->rep);
7210 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7211 }
7212 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7213 }
7214}
7215
7216static int
7217proto_strlcpy(char *dest, const char *src, size_t dest_size)
7218{
7219 if (dest_size == 0) return 0;
7220
7221 size_t res = g_strlcpy(dest, src, dest_size);
7222
7223 /* At most dest_size - 1 characters will be copied
7224 * (unless dest_size is 0). */
7225 if (res >= dest_size)
7226 res = dest_size - 1;
7227 return (int) res;
7228}
7229
7230static header_field_info *
7231hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7232{
7233 header_field_info *dup_hfinfo;
7234
7235 if (hfinfo->same_name_prev_id == -1)
7236 return NULL((void*)0);
7237 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", 7237
, __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", 7237, "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", 7237,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7238 return dup_hfinfo;
7239}
7240
7241static void
7242hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7243{
7244 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
7245 last_field_name = NULL((void*)0);
7246
7247 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7248 /* No hfinfo with the same name */
7249 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7250 return;
7251 }
7252
7253 if (hfinfo->same_name_next) {
7254 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7255 }
7256
7257 if (hfinfo->same_name_prev_id != -1) {
7258 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7259 same_name_prev->same_name_next = hfinfo->same_name_next;
7260 if (!hfinfo->same_name_next) {
7261 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7262 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7263 }
7264 }
7265}
7266
7267int
7268proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7269{
7270 const header_field_info *hfinfo = finfo->hfinfo;
7271 int label_len = 0;
7272 char *tmp_str;
7273 const char *str;
7274 const uint8_t *bytes;
7275 uint32_t number;
7276 uint64_t number64;
7277 const char *hf_str_val;
7278 char number_buf[NUMBER_LABEL_LENGTH80];
7279 const char *number_out;
7280 address addr;
7281 const ipv4_addr_and_mask *ipv4;
7282 const ipv6_addr_and_prefix *ipv6;
7283
7284 switch (hfinfo->type) {
7285
7286 case FT_NONE:
7287 case FT_PROTOCOL:
7288 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7289
7290 case FT_UINT_BYTES:
7291 case FT_BYTES:
7292 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7293 hfinfo,
7294 fvalue_get_bytes_data(finfo->value),
7295 (unsigned)fvalue_length2(finfo->value),
7296 label_str_size);
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_ABSOLUTE_TIME:
7302 {
7303 const nstime_t *value = fvalue_get_time(finfo->value);
7304 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7305 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7306 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7307 }
7308 if (hfinfo->strings) {
7309 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7310 if (time_string != NULL((void*)0)) {
7311 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7312 break;
7313 }
7314 }
7315 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7316 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7317 wmem_free(NULL((void*)0), tmp_str);
7318 break;
7319 }
7320
7321 case FT_RELATIVE_TIME:
7322 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
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_BOOLEAN:
7328 number64 = fvalue_get_uinteger64(finfo->value);
7329 label_len = proto_strlcpy(display_label_str,
7330 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7331 break;
7332
7333 case FT_CHAR:
7334 number = fvalue_get_uinteger(finfo->value);
7335
7336 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7337 char tmp[ITEM_LABEL_LENGTH240];
7338 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7339
7340 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7340, "fmtfunc"))))
;
7341 fmtfunc(tmp, number);
7342
7343 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7344
7345 } else if (hfinfo->strings) {
7346 number_out = hf_try_val_to_str(number, hfinfo);
7347
7348 if (!number_out) {
7349 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7350 }
7351
7352 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7353
7354 } else {
7355 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7356
7357 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7358 }
7359
7360 break;
7361
7362 /* XXX - make these just FT_NUMBER? */
7363 case FT_INT8:
7364 case FT_INT16:
7365 case FT_INT24:
7366 case FT_INT32:
7367 case FT_UINT8:
7368 case FT_UINT16:
7369 case FT_UINT24:
7370 case FT_UINT32:
7371 case FT_FRAMENUM:
7372 hf_str_val = NULL((void*)0);
7373 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
))
?
7374 (uint32_t) fvalue_get_sinteger(finfo->value) :
7375 fvalue_get_uinteger(finfo->value);
7376
7377 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7378 char tmp[ITEM_LABEL_LENGTH240];
7379 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7380
7381 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7381, "fmtfunc"))))
;
7382 fmtfunc(tmp, number);
7383
7384 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7385
7386 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7387 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7388 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7389 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7390 hf_str_val = hf_try_val_to_str(number, hfinfo);
7391 if (hf_str_val)
7392 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7393 } else {
7394 number_out = hf_try_val_to_str(number, hfinfo);
7395
7396 if (!number_out) {
7397 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7398 }
7399
7400 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7401 }
7402 } else {
7403 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7404
7405 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7406 }
7407
7408 break;
7409
7410 case FT_INT40:
7411 case FT_INT48:
7412 case FT_INT56:
7413 case FT_INT64:
7414 case FT_UINT40:
7415 case FT_UINT48:
7416 case FT_UINT56:
7417 case FT_UINT64:
7418 hf_str_val = NULL((void*)0);
7419 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
))
?
7420 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7421 fvalue_get_uinteger64(finfo->value);
7422
7423 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7424 char tmp[ITEM_LABEL_LENGTH240];
7425 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7426
7427 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7427, "fmtfunc64"
))))
;
7428 fmtfunc64(tmp, number64);
7429
7430 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7431 } else if (hfinfo->strings) {
7432 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7433 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7434 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7435 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7436 if (hf_str_val)
7437 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7438 } else {
7439 number_out = hf_try_val64_to_str(number64, hfinfo);
7440
7441 if (!number_out)
7442 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7443
7444 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7445 }
7446 } else {
7447 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7448
7449 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7450 }
7451
7452 break;
7453
7454 case FT_EUI64:
7455 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7456 tmp_str = address_to_display(NULL((void*)0), &addr);
7457 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7458 wmem_free(NULL((void*)0), tmp_str);
7459 break;
7460
7461 case FT_IPv4:
7462 ipv4 = fvalue_get_ipv4(finfo->value);
7463 //XXX: Should we ignore the mask?
7464 set_address_ipv4(&addr, ipv4);
7465 tmp_str = address_to_display(NULL((void*)0), &addr);
7466 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7467 wmem_free(NULL((void*)0), tmp_str);
7468 free_address(&addr);
7469 break;
7470
7471 case FT_IPv6:
7472 ipv6 = fvalue_get_ipv6(finfo->value);
7473 set_address_ipv6(&addr, ipv6);
7474 tmp_str = address_to_display(NULL((void*)0), &addr);
7475 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7476 wmem_free(NULL((void*)0), tmp_str);
7477 free_address(&addr);
7478 break;
7479
7480 case FT_FCWWN:
7481 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7482 tmp_str = address_to_display(NULL((void*)0), &addr);
7483 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7484 wmem_free(NULL((void*)0), tmp_str);
7485 break;
7486
7487 case FT_ETHER:
7488 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7489 tmp_str = address_to_display(NULL((void*)0), &addr);
7490 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7491 wmem_free(NULL((void*)0), tmp_str);
7492 break;
7493
7494 case FT_GUID:
7495 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7496 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7497 wmem_free(NULL((void*)0), tmp_str);
7498 break;
7499
7500 case FT_REL_OID:
7501 bytes = fvalue_get_bytes_data(finfo->value);
7502 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7503 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7504 wmem_free(NULL((void*)0), tmp_str);
7505 break;
7506
7507 case FT_OID:
7508 bytes = fvalue_get_bytes_data(finfo->value);
7509 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7510 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7511 wmem_free(NULL((void*)0), tmp_str);
7512 break;
7513
7514 case FT_SYSTEM_ID:
7515 bytes = fvalue_get_bytes_data(finfo->value);
7516 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7517 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7518 wmem_free(NULL((void*)0), tmp_str);
7519 break;
7520
7521 case FT_FLOAT:
7522 case FT_DOUBLE:
7523 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7524 break;
7525
7526 case FT_IEEE_11073_SFLOAT:
7527 case FT_IEEE_11073_FLOAT:
7528 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7529 break;
7530
7531 case FT_STRING:
7532 case FT_STRINGZ:
7533 case FT_UINT_STRING:
7534 case FT_STRINGZPAD:
7535 case FT_STRINGZTRUNC:
7536 str = fvalue_get_string(finfo->value);
7537 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7538 if (label_len >= label_str_size) {
7539 /* Truncation occurred. Get the real length
7540 * copied (not including '\0') */
7541 label_len = label_str_size ? label_str_size - 1 : 0;
7542 }
7543 break;
7544
7545 default:
7546 /* First try ftype string representation */
7547 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7548 if (!tmp_str) {
7549 /* Default to show as bytes */
7550 bytes = fvalue_get_bytes_data(finfo->value);
7551 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7552 }
7553 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7554 wmem_free(NULL((void*)0), tmp_str);
7555 break;
7556 }
7557 return label_len;
7558}
7559
7560const char *
7561proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7562 char *result, char *expr, const int size)
7563{
7564 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7565 GPtrArray *finfos;
7566 field_info *finfo = NULL((void*)0);
7567 header_field_info* hfinfo;
7568 const char *abbrev = NULL((void*)0);
7569
7570 char *str;
7571 col_custom_t *field_idx;
7572 int field_id;
7573 int ii = 0;
7574
7575 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7575, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7576 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7577 field_id = field_idx->field_id;
7578 if (field_id == 0) {
7579 GPtrArray *fvals = NULL((void*)0);
7580 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7581 if (fvals != NULL((void*)0)) {
7582
7583 // XXX - Handling occurrences is unusual when more
7584 // than one field is involved, e.g. there's four
7585 // results for tcp.port + tcp.port. We may really
7586 // want to apply it to the operands, not the output.
7587 // Note that occurrences are not quite the same as
7588 // the layer operator (should the grammar support
7589 // both?)
7590 /* Calculate single index or set outer boundaries */
7591 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7592 if (occurrence < 0) {
7593 i = occurrence + len;
7594 last = i;
7595 } else if (occurrence > 0) {
7596 i = occurrence - 1;
7597 last = i;
7598 } else {
7599 i = 0;
7600 last = len - 1;
7601 }
7602 if (i < 0 || i >= len) {
7603 g_ptr_array_unref(fvals);
7604 continue;
7605 }
7606 for (; i <= last; i++) {
7607 /* XXX - We could have a "resolved" result
7608 * for types where the value depends only
7609 * on the type, e.g. FT_IPv4, and not on
7610 * hfinfo->strings. Supporting the latter
7611 * requires knowing which hfinfo matched
7612 * if there are multiple with the same
7613 * abbreviation. In any case, we need to
7614 * know the expected return type of the
7615 * field expression.
7616 */
7617 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7618 if (offset_r && (offset_r < (size - 1)))
7619 result[offset_r++] = ',';
7620 if (offset_e && (offset_e < (size - 1)))
7621 expr[offset_e++] = ',';
7622 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7623 // col_{add,append,set}_* calls ws_label_strcpy
7624 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7625
7626 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7627 }
7628 g_ptr_array_unref(fvals);
7629 } else if (passed) {
7630 // XXX - Occurrence doesn't make sense for a test
7631 // output, it should be applied to the operands.
7632 if (offset_r && (offset_r < (size - 1)))
7633 result[offset_r++] = ',';
7634 if (offset_e && (offset_e < (size - 1)))
7635 expr[offset_e++] = ',';
7636 /* Prevent multiple check marks */
7637 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7638 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7639 } else {
7640 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7641 }
7642 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7643 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7644 } else {
7645 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7646 }
7647 }
7648 continue;
7649 }
7650 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", 7650
, __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", 7650,
"(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", 7650,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7651
7652 /* do we need to rewind ? */
7653 if (!hfinfo)
7654 return "";
7655
7656 if (occurrence < 0) {
7657 /* Search other direction */
7658 while (hfinfo->same_name_prev_id != -1) {
7659 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", 7659
, __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", 7659, "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", 7659,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7660 }
7661 }
7662
7663 prev_len = 0; /* Reset handled occurrences */
7664
7665 while (hfinfo) {
7666 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7667
7668 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7669 if (occurrence < 0) {
7670 hfinfo = hfinfo->same_name_next;
7671 } else {
7672 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7673 }
7674 continue;
7675 }
7676
7677 /* Are there enough occurrences of the field? */
7678 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7679 if (occurrence < 0) {
7680 hfinfo = hfinfo->same_name_next;
7681 } else {
7682 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7683 }
7684 prev_len += len;
7685 continue;
7686 }
7687
7688 /* Calculate single index or set outer boundaries */
7689 if (occurrence < 0) {
7690 i = occurrence + len + prev_len;
7691 last = i;
7692 } else if (occurrence > 0) {
7693 i = occurrence - 1 - prev_len;
7694 last = i;
7695 } else {
7696 i = 0;
7697 last = len - 1;
7698 }
7699
7700 prev_len += len; /* Count handled occurrences */
7701
7702 while (i <= last) {
7703 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7704
7705 if (offset_r && (offset_r < (size - 1)))
7706 result[offset_r++] = ',';
7707
7708 if (display_details) {
7709 char representation[ITEM_LABEL_LENGTH240];
7710 size_t offset = 0;
7711
7712 if (finfo->rep && finfo->rep->value_len) {
7713 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7714 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7715 } else {
7716 proto_item_fill_label(finfo, representation, &offset);
7717 }
7718 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7719 } else {
7720 switch (hfinfo->type) {
7721
7722 case FT_NONE:
7723 case FT_PROTOCOL:
7724 /* Prevent multiple check marks */
7725 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7726 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7727 } else {
7728 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7729 }
7730 break;
7731
7732 default:
7733 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7734 break;
7735 }
7736 }
7737
7738 if (offset_e && (offset_e < (size - 1)))
7739 expr[offset_e++] = ',';
7740
7741 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
))
)) {
7742 const char *hf_str_val;
7743 /* Integer types with BASE_NONE never get the numeric value. */
7744 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7745 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7746 } 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
)
) {
7747 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7748 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7749 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7750 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7751 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7752 }
7753 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7754 offset_e = (int)strlen(expr);
7755 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7756 /* Prevent multiple check marks */
7757 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7758 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7759 } else {
7760 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7761 }
7762 } else {
7763 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7764 // col_{add,append,set}_* calls ws_label_strcpy
7765 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7766 wmem_free(NULL((void*)0), str);
7767 }
7768 i++;
7769 }
7770
7771 /* XXX: Why is only the first abbreviation returned for a multifield
7772 * custom column? */
7773 if (!abbrev) {
7774 /* Store abbrev for return value */
7775 abbrev = hfinfo->abbrev;
7776 }
7777
7778 if (occurrence == 0) {
7779 /* Fetch next hfinfo with same name (abbrev) */
7780 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7781 } else {
7782 hfinfo = NULL((void*)0);
7783 }
7784 }
7785 }
7786
7787 if (offset_r >= (size - 1)) {
7788 mark_truncated(result, 0, size, NULL((void*)0));
7789 }
7790 if (offset_e >= (size - 1)) {
7791 mark_truncated(expr, 0, size, NULL((void*)0));
7792 }
7793 return abbrev ? abbrev : "";
7794}
7795
7796char *
7797proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7798{
7799 int len, prev_len, last, i;
7800 GPtrArray *finfos;
7801 field_info *finfo = NULL((void*)0);
7802 header_field_info* hfinfo;
7803
7804 char *filter = NULL((void*)0);
7805 GPtrArray *filter_array;
7806
7807 col_custom_t *col_custom;
7808 int field_id;
7809
7810 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7810, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7811 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7812 for (GSList *iter = field_ids; iter; iter = iter->next) {
7813 col_custom = (col_custom_t*)iter->data;
7814 field_id = col_custom->field_id;
7815 if (field_id == 0) {
7816 GPtrArray *fvals = NULL((void*)0);
7817 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7818 if (fvals != NULL((void*)0)) {
7819 // XXX - Handling occurrences is unusual when more
7820 // than one field is involved, e.g. there's four
7821 // results for tcp.port + tcp.port. We really
7822 // want to apply it to the operands, not the output.
7823 /* Calculate single index or set outer boundaries */
7824 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7825 if (occurrence < 0) {
7826 i = occurrence + len;
7827 last = i;
7828 } else if (occurrence > 0) {
7829 i = occurrence - 1;
7830 last = i;
7831 } else {
7832 i = 0;
7833 last = len - 1;
7834 }
7835 if (i < 0 || i >= len) {
7836 g_ptr_array_unref(fvals);
7837 continue;
7838 }
7839 for (; i <= last; i++) {
7840 /* XXX - Should multiple values for one
7841 * field use set membership to reduce
7842 * verbosity, here and below? */
7843 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7844 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7845 wmem_free(NULL((void*)0), str);
7846 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7847 g_ptr_array_add(filter_array, filter);
7848 }
7849 }
7850 g_ptr_array_unref(fvals);
7851 } else if (passed) {
7852 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7853 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7854 g_ptr_array_add(filter_array, filter);
7855 }
7856 } else {
7857 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7858 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7859 g_ptr_array_add(filter_array, filter);
7860 }
7861 }
7862 continue;
7863 }
7864
7865 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", 7865
, __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", 7865,
"(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", 7865,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7866
7867 /* do we need to rewind ? */
7868 if (!hfinfo)
7869 return NULL((void*)0);
7870
7871 if (occurrence < 0) {
7872 /* Search other direction */
7873 while (hfinfo->same_name_prev_id != -1) {
7874 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", 7874
, __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", 7874, "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", 7874,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7875 }
7876 }
7877
7878 prev_len = 0; /* Reset handled occurrences */
7879
7880 while (hfinfo) {
7881 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7882
7883 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7884 if (occurrence < 0) {
7885 hfinfo = hfinfo->same_name_next;
7886 } else {
7887 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7888 }
7889 continue;
7890 }
7891
7892 /* Are there enough occurrences of the field? */
7893 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7894 if (occurrence < 0) {
7895 hfinfo = hfinfo->same_name_next;
7896 } else {
7897 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7898 }
7899 prev_len += len;
7900 continue;
7901 }
7902
7903 /* Calculate single index or set outer boundaries */
7904 if (occurrence < 0) {
7905 i = occurrence + len + prev_len;
7906 last = i;
7907 } else if (occurrence > 0) {
7908 i = occurrence - 1 - prev_len;
7909 last = i;
7910 } else {
7911 i = 0;
7912 last = len - 1;
7913 }
7914
7915 prev_len += len; /* Count handled occurrences */
7916
7917 while (i <= last) {
7918 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7919
7920 filter = proto_construct_match_selected_string(finfo, edt);
7921 if (filter) {
7922 /* Only add the same expression once (especially for FT_PROTOCOL).
7923 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7924 */
7925 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7926 g_ptr_array_add(filter_array, filter);
7927 }
7928 }
7929 i++;
7930 }
7931
7932 if (occurrence == 0) {
7933 /* Fetch next hfinfo with same name (abbrev) */
7934 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7935 } else {
7936 hfinfo = NULL((void*)0);
7937 }
7938 }
7939 }
7940
7941 g_ptr_array_add(filter_array, NULL((void*)0));
7942
7943 /* XXX: Should this be || or && ? */
7944 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7945
7946 g_ptr_array_free(filter_array, true1);
7947
7948 return output;
7949}
7950
7951/* Set text of proto_item after having already been created. */
7952void
7953proto_item_set_text(proto_item *pi, const char *format, ...)
7954{
7955 field_info *fi = NULL((void*)0);
7956 va_list ap;
7957
7958 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7959
7960 fi = PITEM_FINFO(pi)((pi)->finfo);
7961 if (fi == NULL((void*)0))
7962 return;
7963
7964 if (fi->rep) {
7965 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7966 fi->rep = NULL((void*)0);
7967 }
7968
7969 va_start(ap, format)__builtin_va_start(ap, format);
7970 proto_tree_set_representation(pi, format, ap);
7971 va_end(ap)__builtin_va_end(ap);
7972}
7973
7974/* Append to text of proto_item after having already been created. */
7975void
7976proto_item_append_text(proto_item *pi, const char *format, ...)
7977{
7978 field_info *fi = NULL((void*)0);
7979 size_t curlen;
7980 char *str;
7981 va_list ap;
7982
7983 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7984
7985 fi = PITEM_FINFO(pi)((pi)->finfo);
7986 if (fi == NULL((void*)0)) {
7987 return;
7988 }
7989
7990 if (!proto_item_is_hidden(pi)) {
7991 /*
7992 * If we don't already have a representation,
7993 * generate the default representation.
7994 */
7995 if (fi->rep == NULL((void*)0)) {
7996 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;
;
7997 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7998 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7999 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8000 (strncmp(format, ": ", 2) == 0)) {
8001 fi->rep->value_pos += 2;
8002 }
8003 }
8004 if (fi->rep) {
8005 curlen = strlen(fi->rep->representation);
8006 /* curlen doesn't include the \0 byte.
8007 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8008 * the representation has already been truncated (of an up
8009 * to 4 byte UTF-8 character) or is just at the maximum length
8010 * unless we search for " [truncated]" (which may not be
8011 * at the start.)
8012 * It's safer to do nothing.
8013 */
8014 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8015 va_start(ap, format)__builtin_va_start(ap, format);
8016 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8017 va_end(ap)__builtin_va_end(ap);
8018 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"
, 8018, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8019 /* Keep fi->rep->value_pos */
8020 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8021 if (curlen >= ITEM_LABEL_LENGTH240) {
8022 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8023 size_t name_pos = label_find_name_pos(fi->rep);
8024 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8025 }
8026 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8027 }
8028 }
8029 }
8030}
8031
8032/* Prepend to text of proto_item after having already been created. */
8033void
8034proto_item_prepend_text(proto_item *pi, const char *format, ...)
8035{
8036 field_info *fi = NULL((void*)0);
8037 size_t pos;
8038 char representation[ITEM_LABEL_LENGTH240];
8039 char *str;
8040 va_list ap;
8041
8042 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8043
8044 fi = PITEM_FINFO(pi)((pi)->finfo);
8045 if (fi == NULL((void*)0)) {
8046 return;
8047 }
8048
8049 if (!proto_item_is_hidden(pi)) {
8050 /*
8051 * If we don't already have a representation,
8052 * generate the default representation.
8053 */
8054 if (fi->rep == NULL((void*)0)) {
8055 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;
;
8056 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8057 } else
8058 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8059
8060 va_start(ap, format)__builtin_va_start(ap, format);
8061 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8062 va_end(ap)__builtin_va_end(ap);
8063 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"
, 8063, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8064 fi->rep->value_pos += strlen(str);
8065 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8066 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8067 /* XXX: As above, if the old representation is close to the label
8068 * length, it might already be marked as truncated. */
8069 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8070 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8071 size_t name_pos = label_find_name_pos(fi->rep);
8072 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8073 }
8074 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8075 }
8076}
8077
8078static void
8079finfo_set_len(field_info *fi, const unsigned length)
8080{
8081 unsigned length_remaining;
8082
8083 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8084 if (length > length_remaining)
8085 fi->length = length_remaining;
8086 else
8087 fi->length = length;
8088
8089 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8090 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8091 fvalue_set_protocol_length(fi->value, fi->length);
8092 }
8093
8094 /*
8095 * You cannot just make the "len" field of a GByteArray
8096 * larger, if there's no data to back that length;
8097 * you can only make it smaller.
8098 */
8099 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8100 GBytes *bytes = fvalue_get_bytes(fi->value);
8101 size_t size;
8102 const void *data = g_bytes_get_data(bytes, &size);
8103 if ((size_t)fi->length <= size) {
8104 fvalue_set_bytes_data(fi->value, data, fi->length);
8105 }
8106 g_bytes_unref(bytes);
8107 }
8108}
8109
8110void
8111proto_item_set_len(proto_item *pi, const unsigned length)
8112{
8113 field_info *fi;
8114
8115 if (pi == NULL((void*)0))
8116 return;
8117
8118 fi = PITEM_FINFO(pi)((pi)->finfo);
8119 if (fi == NULL((void*)0))
8120 return;
8121
8122 finfo_set_len(fi, length);
8123}
8124
8125/*
8126 * Sets the length of the item based on its start and on the specified
8127 * offset, which is the offset past the end of the item; as the start
8128 * in the item is relative to the beginning of the data source tvbuff,
8129 * we need to pass in a tvbuff - the end offset is relative to the beginning
8130 * of that tvbuff.
8131 */
8132void
8133proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8134{
8135 field_info *fi;
8136 unsigned length;
8137
8138 if (pi == NULL((void*)0))
8139 return;
8140
8141 fi = PITEM_FINFO(pi)((pi)->finfo);
8142 if (fi == NULL((void*)0))
8143 return;
8144
8145 if (G_LIKELY(tvb)(tvb)) {
8146 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8146, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8147 end += tvb_raw_offset(tvb);
8148 } else {
8149 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8149, "((void*)0) == fi->ds_tvb"
))))
;
8150 }
8151 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8151, "end >= fi->start"
))))
;
8152 length = end - fi->start;
8153
8154 finfo_set_len(fi, length);
8155}
8156
8157unsigned
8158proto_item_get_len(const proto_item *pi)
8159{
8160 /* XXX - The only use case where this is really guaranteed to work is
8161 * increasing the length of an item (which has no effect if the item
8162 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8163 *
8164 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8165 *
8166 * Should there be a macro or function to do that, and possibly this
8167 * be deprecated? As a bonus, we could handle overflow.
8168 */
8169 field_info *fi;
8170
8171 if (!pi)
8172 return 0;
8173 fi = PITEM_FINFO(pi)((pi)->finfo);
8174 if (fi) {
8175 return fi->length;
8176 }
8177 return 0;
8178}
8179
8180void
8181proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8182 if (!ti) {
8183 return;
8184 }
8185 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)
;
8186 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)
;
8187}
8188
8189char *
8190proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8191{
8192 field_info *fi;
8193
8194 if (!pi)
8195 return wmem_strdup(scope, "");
8196 fi = PITEM_FINFO(pi)((pi)->finfo);
8197 if (!fi)
8198 return wmem_strdup(scope, "");
8199 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8199, "fi->hfinfo != ((void*)0)"
))))
;
8200 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8201}
8202
8203proto_tree *
8204proto_tree_create_root(packet_info *pinfo)
8205{
8206 proto_node *pnode;
8207
8208 /* Initialize the proto_node */
8209 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8210 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8211 pnode->parent = NULL((void*)0);
8212 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8213 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc ((sizeof (tree_data_t) > 0 ?
sizeof (tree_data_t) : 1)))
;
8214
8215 /* Make sure we can access pinfo everywhere */
8216 pnode->tree_data->pinfo = pinfo;
8217
8218 /* Don't initialize the tree_data_t. Wait until we know we need it */
8219 pnode->tree_data->interesting_hfids = NULL((void*)0);
8220
8221 /* Set the default to false so it's easier to
8222 * find errors; if we expect to see the protocol tree
8223 * but for some reason the default 'visible' is not
8224 * changed, then we'll find out very quickly. */
8225 pnode->tree_data->visible = false0;
8226
8227 /* Make sure that we fake protocols (if possible) */
8228 pnode->tree_data->fake_protocols = true1;
8229
8230 /* Keep track of the number of children */
8231 pnode->tree_data->count = 0;
8232
8233 /* Initialize our loop checks */
8234 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8235 pnode->tree_data->max_start = 0;
8236 pnode->tree_data->start_idle_count = 0;
8237
8238 return (proto_tree *)pnode;
8239}
8240
8241
8242/* "prime" a proto_tree with a single hfid that a dfilter
8243 * is interested in. */
8244void
8245proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8246{
8247 header_field_info *hfinfo;
8248
8249 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", 8249, __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", 8249, "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", 8249, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8250 /* this field is referenced by a filter so increase the refcount.
8251 also increase the refcount for the parent, i.e the protocol.
8252 Don't increase the refcount if we're already printing the
8253 type, as that is a superset of direct reference.
8254 */
8255 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8256 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8257 }
8258 /* only increase the refcount if there is a parent.
8259 if this is a protocol and not a field then parent will be -1
8260 and there is no parent to add any refcounting for.
8261 */
8262 if (hfinfo->parent != -1) {
8263 header_field_info *parent_hfinfo;
8264 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", 8264
, __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", 8264,
"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", 8264,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8265
8266 /* Mark parent as indirectly referenced unless it is already directly
8267 * referenced, i.e. the user has specified the parent in a filter.
8268 */
8269 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8270 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8271 }
8272}
8273
8274/* "prime" a proto_tree with a single hfid that a dfilter
8275 * is interested in. */
8276void
8277proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8278{
8279 header_field_info *hfinfo;
8280
8281 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", 8281, __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", 8281, "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", 8281, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8282 /* this field is referenced by an (output) filter so increase the refcount.
8283 also increase the refcount for the parent, i.e the protocol.
8284 */
8285 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8286 /* only increase the refcount if there is a parent.
8287 if this is a protocol and not a field then parent will be -1
8288 and there is no parent to add any refcounting for.
8289 */
8290 if (hfinfo->parent != -1) {
8291 header_field_info *parent_hfinfo;
8292 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", 8292
, __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", 8292,
"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", 8292,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8293
8294 /* Mark parent as indirectly referenced unless it is already directly
8295 * referenced, i.e. the user has specified the parent in a filter.
8296 */
8297 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8298 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8299 }
8300}
8301
8302proto_tree *
8303proto_item_add_subtree(proto_item *pi, const int idx) {
8304 field_info *fi;
8305
8306 if (!pi)
8307 return NULL((void*)0);
8308
8309 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", 8309, "idx >= 0 && idx < num_tree_types"
))))
;
8310
8311 fi = PITEM_FINFO(pi)((pi)->finfo);
8312 if (!fi)
8313 return (proto_tree *)pi;
8314
8315 fi->tree_type = idx;
8316
8317 return (proto_tree *)pi;
8318}
8319
8320proto_tree *
8321proto_item_get_subtree(proto_item *pi) {
8322 field_info *fi;
8323
8324 if (!pi)
8325 return NULL((void*)0);
8326 fi = PITEM_FINFO(pi)((pi)->finfo);
8327 if ( (fi) && (fi->tree_type == -1) )
8328 return NULL((void*)0);
8329 return (proto_tree *)pi;
8330}
8331
8332proto_item *
8333proto_item_get_parent(const proto_item *ti) {
8334 if (!ti)
8335 return NULL((void*)0);
8336 return ti->parent;
8337}
8338
8339proto_item *
8340proto_item_get_parent_nth(proto_item *ti, int gen) {
8341 if (!ti)
8342 return NULL((void*)0);
8343 while (gen--) {
8344 ti = ti->parent;
8345 if (!ti)
8346 return NULL((void*)0);
8347 }
8348 return ti;
8349}
8350
8351
8352proto_item *
8353proto_tree_get_parent(proto_tree *tree) {
8354 if (!tree)
8355 return NULL((void*)0);
8356 return (proto_item *)tree;
8357}
8358
8359proto_tree *
8360proto_tree_get_parent_tree(proto_tree *tree) {
8361 if (!tree)
8362 return NULL((void*)0);
8363
8364 /* we're the root tree, there's no parent
8365 return ourselves so the caller has at least a tree to attach to */
8366 if (!tree->parent)
8367 return tree;
8368
8369 return (proto_tree *)tree->parent;
8370}
8371
8372proto_tree *
8373proto_tree_get_root(proto_tree *tree) {
8374 if (!tree)
8375 return NULL((void*)0);
8376 while (tree->parent) {
8377 tree = tree->parent;
8378 }
8379 return tree;
8380}
8381
8382void
8383proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8384 proto_item *item_to_move)
8385{
8386 /* This function doesn't generate any values. It only reorganizes the protocol tree
8387 * so we can bail out immediately if it isn't visible. */
8388 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8389 return;
8390
8391 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", 8391, "item_to_move->parent == tree"
))))
;
8392 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", 8392, "fixed_item->parent == tree"
))))
;
8393
8394 /*** cut item_to_move out ***/
8395
8396 /* is item_to_move the first? */
8397 if (tree->first_child == item_to_move) {
8398 /* simply change first child to next */
8399 tree->first_child = item_to_move->next;
8400
8401 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", 8401, "tree->last_child != item_to_move"
))))
;
8402 } else {
8403 proto_item *curr_item;
8404 /* find previous and change it's next */
8405 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8406 if (curr_item->next == item_to_move) {
8407 break;
8408 }
8409 }
8410
8411 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8411, "curr_item"
))))
;
8412
8413 curr_item->next = item_to_move->next;
8414
8415 /* fix last_child if required */
8416 if (tree->last_child == item_to_move) {
8417 tree->last_child = curr_item;
8418 }
8419 }
8420
8421 /*** insert to_move after fixed ***/
8422 item_to_move->next = fixed_item->next;
8423 fixed_item->next = item_to_move;
8424 if (tree->last_child == fixed_item) {
8425 tree->last_child = item_to_move;
8426 }
8427}
8428
8429void
8430proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8431 const unsigned length)
8432{
8433 field_info *fi;
8434
8435 if (tree == NULL((void*)0))
8436 return;
8437
8438 fi = PTREE_FINFO(tree)((tree)->finfo);
8439 if (fi == NULL((void*)0))
8440 return;
8441
8442 /* We don't store a separate data source tvb for the appendix, so
8443 * it must be from the same data source. (XXX - Are there any
8444 * situations where it makes sense to have an appendix from a
8445 * different data source?) */
8446 if (G_LIKELY(tvb)(tvb)) {
8447 DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 8447, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8448 start += tvb_raw_offset(tvb);
8449 } else {
8450 DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8450, "((void*)0) == fi->ds_tvb"
))))
;
8451 }
8452
8453 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8454 * main body? */
8455
8456 fi->appendix_start = start;
8457 fi->appendix_length = length;
8458}
8459
8460static void
8461check_protocol_filter_name_or_fail(const char *filter_name)
8462{
8463 /* Require at least two characters. */
8464 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8465 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)
;
8466 }
8467
8468 if (proto_check_field_name(filter_name) != '\0') {
8469 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)
8470 " 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)
8471 " 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)
;
8472 }
8473
8474 /* Check that it doesn't match some very common numeric forms. */
8475 if (filter_name[0] == '0' &&
8476 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8477 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8478 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])
8479 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])
;
8480 }
8481
8482 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8483
8484 /* Check that it contains at least one letter. */
8485 bool_Bool have_letter = false0;
8486 for (const char *s = filter_name; *s != '\0'; s++) {
8487 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8488 have_letter = true1;
8489 break;
8490 }
8491 }
8492 if (!have_letter) {
8493 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)
8494 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8495 }
8496
8497 /* Check for reserved keywords. */
8498 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8499 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)
8500 " 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)
;
8501 }
8502}
8503
8504int
8505proto_register_protocol(const char *name, const char *short_name,
8506 const char *filter_name)
8507{
8508 protocol_t *protocol;
8509 header_field_info *hfinfo;
8510
8511 check_protocol_filter_name_or_fail(filter_name);
8512
8513 /*
8514 * Add this protocol to the list of known protocols;
8515 * the list is sorted by protocol short name.
8516 */
8517 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8518 protocol->name = name;
8519 protocol->short_name = short_name;
8520 protocol->filter_name = filter_name;
8521 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8522 protocol->is_enabled = true1; /* protocol is enabled by default */
8523 protocol->enabled_by_default = true1; /* see previous comment */
8524 protocol->can_toggle = true1;
8525 protocol->parent_proto_id = -1;
8526 protocol->heur_list = NULL((void*)0);
8527
8528 /* List will be sorted later by name, when all protocols completed registering */
8529 protocols = g_list_prepend(protocols, protocol);
8530 /*
8531 * Make sure there's not already a protocol with any of those
8532 * names. Crash if there is, as that's an error in the code
8533 * or an inappropriate plugin.
8534 * This situation has to be fixed to not register more than one
8535 * protocol with the same name.
8536 */
8537 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8538 /* ws_error will terminate the program */
8539 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)
8540 " 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)
;
8541 }
8542 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8543 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)
8544 " 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)
;
8545 }
8546 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8547 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)
8548 " 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)
;
8549 }
8550
8551 /* Here we allocate a new header_field_info struct */
8552 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8553 hfinfo->name = name;
8554 hfinfo->abbrev = filter_name;
8555 hfinfo->type = FT_PROTOCOL;
8556 hfinfo->display = BASE_NONE;
8557 hfinfo->strings = protocol;
8558 hfinfo->bitmask = 0;
8559 hfinfo->ref_type = HF_REF_TYPE_NONE;
8560 hfinfo->blurb = NULL((void*)0);
8561 hfinfo->parent = -1; /* This field differentiates protos and fields */
8562
8563 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8564 return protocol->proto_id;
8565}
8566
8567int
8568proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8569{
8570 protocol_t *protocol;
8571 header_field_info *hfinfo;
8572
8573 /*
8574 * Helper protocols don't need the strict rules as a "regular" protocol
8575 * Just register it in a list and make a hf_ field from it
8576 */
8577 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8578 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)
;
8579 }
8580
8581 if (parent_proto <= 0) {
8582 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)
8583 " 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)
;
8584 }
8585
8586 check_protocol_filter_name_or_fail(filter_name);
8587
8588 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8589 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8590 protocol->name = name;
8591 protocol->short_name = short_name;
8592 protocol->filter_name = filter_name;
8593 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8594
8595 /* Enabling and toggling is really determined by parent protocol,
8596 but provide default values here */
8597 protocol->is_enabled = true1;
8598 protocol->enabled_by_default = true1;
8599 protocol->can_toggle = true1;
8600
8601 protocol->parent_proto_id = parent_proto;
8602 protocol->heur_list = NULL((void*)0);
8603
8604 /* List will be sorted later by name, when all protocols completed registering */
8605 protocols = g_list_prepend(protocols, protocol);
8606
8607 /* Here we allocate a new header_field_info struct */
8608 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8609 hfinfo->name = name;
8610 hfinfo->abbrev = filter_name;
8611 hfinfo->type = field_type;
8612 hfinfo->display = BASE_NONE;
8613 if (field_type == FT_BYTES) {
8614 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8615 }
8616 hfinfo->strings = protocol;
8617 hfinfo->bitmask = 0;
8618 hfinfo->ref_type = HF_REF_TYPE_NONE;
8619 hfinfo->blurb = NULL((void*)0);
8620 hfinfo->parent = -1; /* This field differentiates protos and fields */
8621
8622 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8623 return protocol->proto_id;
8624}
8625
8626bool_Bool
8627proto_deregister_protocol(const char *short_name)
8628{
8629 protocol_t *protocol;
8630 header_field_info *hfinfo;
8631 int proto_id;
8632 unsigned i;
8633
8634 proto_id = proto_get_id_by_short_name(short_name);
8635 protocol = find_protocol_by_id(proto_id);
8636 if (protocol == NULL((void*)0))
8637 return false0;
8638
8639 g_hash_table_remove(proto_names, protocol->name);
8640 g_hash_table_remove(proto_short_names, (void *)short_name);
8641 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8642
8643 if (protocol->fields) {
8644 for (i = 0; i < protocol->fields->len; i++) {
8645 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8646 hfinfo_remove_from_gpa_name_map(hfinfo);
8647 expert_deregister_expertinfo(hfinfo->abbrev);
8648 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8649 }
8650 g_ptr_array_free(protocol->fields, true1);
8651 protocol->fields = NULL((void*)0);
8652 }
8653
8654 g_list_free(protocol->heur_list);
8655
8656 /* Remove this protocol from the list of known protocols */
8657 protocols = g_list_remove(protocols, protocol);
8658
8659 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8660 wmem_map_remove(gpa_name_map, protocol->filter_name);
8661
8662 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
8663 last_field_name = NULL((void*)0);
8664
8665 return true1;
8666}
8667
8668void
8669proto_register_alias(const int proto_id, const char *alias_name)
8670{
8671 protocol_t *protocol;
8672
8673 protocol = find_protocol_by_id(proto_id);
8674 if (alias_name && protocol) {
8675 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8676 }
8677}
8678
8679/*
8680 * Routines to use to iterate over the protocols.
8681 * The argument passed to the iterator routines is an opaque cookie to
8682 * their callers; it's the GList pointer for the current element in
8683 * the list.
8684 * The ID of the protocol is returned, or -1 if there is no protocol.
8685 */
8686int
8687proto_get_first_protocol(void **cookie)
8688{
8689 protocol_t *protocol;
8690
8691 if (protocols == NULL((void*)0))
8692 return -1;
8693 *cookie = protocols;
8694 protocol = (protocol_t *)protocols->data;
8695 return protocol->proto_id;
8696}
8697
8698int
8699proto_get_data_protocol(void *cookie)
8700{
8701 GList *list_item = (GList *)cookie;
8702
8703 protocol_t *protocol = (protocol_t *)list_item->data;
8704 return protocol->proto_id;
8705}
8706
8707int
8708proto_get_next_protocol(void **cookie)
8709{
8710 GList *list_item = (GList *)*cookie;
8711 protocol_t *protocol;
8712
8713 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8714 if (list_item == NULL((void*)0))
8715 return -1;
8716 *cookie = list_item;
8717 protocol = (protocol_t *)list_item->data;
8718 return protocol->proto_id;
8719}
8720
8721header_field_info *
8722proto_get_first_protocol_field(const int proto_id, void **cookie)
8723{
8724 protocol_t *protocol = find_protocol_by_id(proto_id);
8725
8726 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8727 return NULL((void*)0);
8728
8729 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8730 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8731}
8732
8733header_field_info *
8734proto_get_next_protocol_field(const int proto_id, void **cookie)
8735{
8736 protocol_t *protocol = find_protocol_by_id(proto_id);
8737 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8738
8739 i++;
8740
8741 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8742 return NULL((void*)0);
8743
8744 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8745 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8746}
8747
8748protocol_t *
8749find_protocol_by_id(const int proto_id)
8750{
8751 header_field_info *hfinfo;
8752
8753 if (proto_id <= 0)
8754 return NULL((void*)0);
8755
8756 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", 8756, __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", 8756,
"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", 8756, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8757 if (hfinfo->type != FT_PROTOCOL) {
8758 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", 8758, "hfinfo->display & 0x00004000"
))))
;
8759 }
8760 return (protocol_t *)hfinfo->strings;
8761}
8762
8763int
8764proto_get_id(const protocol_t *protocol)
8765{
8766 return protocol->proto_id;
8767}
8768
8769bool_Bool
8770proto_name_already_registered(const char *name)
8771{
8772 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8772, "name", "No name present"))))
;
8773
8774 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8775 return true1;
8776 return false0;
8777}
8778
8779int
8780proto_get_id_by_filter_name(const char *filter_name)
8781{
8782 const protocol_t *protocol = NULL((void*)0);
8783
8784 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", 8784,
"filter_name", "No filter name present"))))
;
8785
8786 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8787
8788 if (protocol == NULL((void*)0))
8789 return -1;
8790 return protocol->proto_id;
8791}
8792
8793int
8794proto_get_id_by_short_name(const char *short_name)
8795{
8796 const protocol_t *protocol = NULL((void*)0);
8797
8798 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", 8798,
"short_name", "No short name present"))))
;
8799
8800 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8801
8802 if (protocol == NULL((void*)0))
8803 return -1;
8804 return protocol->proto_id;
8805}
8806
8807const char *
8808proto_get_protocol_name(const int proto_id)
8809{
8810 protocol_t *protocol;
8811
8812 protocol = find_protocol_by_id(proto_id);
8813
8814 if (protocol == NULL((void*)0))
8815 return NULL((void*)0);
8816 return protocol->name;
8817}
8818
8819const char *
8820proto_get_protocol_short_name(const protocol_t *protocol)
8821{
8822 if (protocol == NULL((void*)0))
8823 return "(none)";
8824 return protocol->short_name;
8825}
8826
8827const char *
8828proto_get_protocol_long_name(const protocol_t *protocol)
8829{
8830 if (protocol == NULL((void*)0))
8831 return "(none)";
8832 return protocol->name;
8833}
8834
8835const char *
8836proto_get_protocol_filter_name(const int proto_id)
8837{
8838 protocol_t *protocol;
8839
8840 protocol = find_protocol_by_id(proto_id);
8841 if (protocol == NULL((void*)0))
8842 return "(none)";
8843 return protocol->filter_name;
8844}
8845
8846void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8847{
8848 heur_dtbl_entry_t* heuristic_dissector;
8849
8850 if (protocol == NULL((void*)0))
8851 return;
8852
8853 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8854 if (heuristic_dissector != NULL((void*)0))
8855 {
8856 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8857 }
8858}
8859
8860void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8861{
8862 if (protocol == NULL((void*)0))
8863 return;
8864
8865 g_list_foreach(protocol->heur_list, func, user_data);
8866}
8867
8868void
8869proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8870 bool_Bool *is_tcp, bool_Bool *is_udp,
8871 bool_Bool *is_sctp, bool_Bool *is_tls,
8872 bool_Bool *is_rtp,
8873 bool_Bool *is_lte_rlc)
8874{
8875 wmem_list_frame_t *protos = wmem_list_head(layers);
8876 int proto_id;
8877 const char *proto_name;
8878
8879 /* Walk the list of a available protocols in the packet and
8880 attempt to find "major" ones. */
8881 /* It might make more sense to assemble and return a bitfield. */
8882 while (protos != NULL((void*)0))
8883 {
8884 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8885 proto_name = proto_get_protocol_filter_name(proto_id);
8886
8887 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8888 (!strcmp(proto_name, "ipv6")))) {
8889 *is_ip = true1;
8890 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8891 *is_tcp = true1;
8892 } else if (is_udp && !strcmp(proto_name, "udp")) {
8893 *is_udp = true1;
8894 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8895 *is_sctp = true1;
8896 } else if (is_tls && !strcmp(proto_name, "tls")) {
8897 *is_tls = true1;
8898 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8899 *is_rtp = true1;
8900 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8901 *is_lte_rlc = true1;
8902 }
8903
8904 protos = wmem_list_frame_next(protos);
8905 }
8906}
8907
8908bool_Bool
8909proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8910{
8911 wmem_list_frame_t *protos = wmem_list_head(layers);
8912 int proto_id;
8913 const char *name;
8914
8915 /* Walk the list of a available protocols in the packet and
8916 attempt to find the specified protocol. */
8917 while (protos != NULL((void*)0))
8918 {
8919 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8920 name = proto_get_protocol_filter_name(proto_id);
8921
8922 if (!strcmp(name, proto_name))
8923 {
8924 return true1;
8925 }
8926
8927 protos = wmem_list_frame_next(protos);
8928 }
8929
8930 return false0;
8931}
8932
8933char *
8934proto_list_layers(const packet_info *pinfo)
8935{
8936 wmem_strbuf_t *buf;
8937 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8938
8939 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8940
8941 /* Walk the list of layers in the packet and
8942 return a string of all entries. */
8943 while (layers != NULL((void*)0))
8944 {
8945 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8946
8947 layers = wmem_list_frame_next(layers);
8948 if (layers != NULL((void*)0)) {
8949 wmem_strbuf_append_c(buf, ':');
8950 }
8951 }
8952
8953 return wmem_strbuf_finalize(buf);
8954}
8955
8956uint8_t
8957proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8958{
8959 int *proto_layer_num_ptr;
8960
8961 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8962 if (proto_layer_num_ptr == NULL((void*)0)) {
8963 return 0;
8964 }
8965
8966 return (uint8_t)*proto_layer_num_ptr;
8967}
8968
8969bool_Bool
8970proto_is_pino(const protocol_t *protocol)
8971{
8972 return (protocol->parent_proto_id != -1);
8973}
8974
8975bool_Bool
8976// NOLINTNEXTLINE(misc-no-recursion)
8977proto_is_protocol_enabled(const protocol_t *protocol)
8978{
8979 if (protocol == NULL((void*)0))
8980 return false0;
8981
8982 //parent protocol determines enable/disable for helper dissectors
8983 if (proto_is_pino(protocol))
8984 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8985
8986 return protocol->is_enabled;
8987}
8988
8989bool_Bool
8990// NOLINTNEXTLINE(misc-no-recursion)
8991proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8992{
8993 //parent protocol determines enable/disable for helper dissectors
8994 if (proto_is_pino(protocol))
8995 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8996
8997 return protocol->enabled_by_default;
8998}
8999
9000bool_Bool
9001// NOLINTNEXTLINE(misc-no-recursion)
9002proto_can_toggle_protocol(const int proto_id)
9003{
9004 protocol_t *protocol;
9005
9006 protocol = find_protocol_by_id(proto_id);
9007 //parent protocol determines toggling for helper dissectors
9008 if (proto_is_pino(protocol))
9009 return proto_can_toggle_protocol(protocol->parent_proto_id);
9010
9011 return protocol->can_toggle;
9012}
9013
9014void
9015proto_disable_by_default(const int proto_id)
9016{
9017 protocol_t *protocol;
9018
9019 protocol = find_protocol_by_id(proto_id);
9020 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9020, "protocol->can_toggle"
))))
;
9021 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", 9021, "proto_is_pino(protocol) == 0"
))))
;
9022 protocol->is_enabled = false0;
9023 protocol->enabled_by_default = false0;
9024}
9025
9026void
9027proto_set_decoding(const int proto_id, const bool_Bool enabled)
9028{
9029 protocol_t *protocol;
9030
9031 protocol = find_protocol_by_id(proto_id);
9032 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9032, "protocol->can_toggle"
))))
;
9033 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", 9033, "proto_is_pino(protocol) == 0"
))))
;
9034 protocol->is_enabled = enabled;
9035}
9036
9037void
9038proto_disable_all(void)
9039{
9040 /* This doesn't explicitly disable heuristic protocols,
9041 * but the heuristic doesn't get called if the parent
9042 * protocol isn't enabled.
9043 */
9044 protocol_t *protocol;
9045 GList *list_item = protocols;
9046
9047 if (protocols == NULL((void*)0))
9048 return;
9049
9050 while (list_item) {
9051 protocol = (protocol_t *)list_item->data;
9052 if (protocol->can_toggle) {
9053 protocol->is_enabled = false0;
9054 }
9055 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9056 }
9057}
9058
9059static void
9060heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9061{
9062 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9063
9064 heur->enabled = heur->enabled_by_default;
9065}
9066
9067void
9068proto_reenable_all(void)
9069{
9070 protocol_t *protocol;
9071 GList *list_item = protocols;
9072
9073 if (protocols == NULL((void*)0))
9074 return;
9075
9076 while (list_item) {
9077 protocol = (protocol_t *)list_item->data;
9078 if (protocol->can_toggle)
9079 protocol->is_enabled = protocol->enabled_by_default;
9080 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9081 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9082 }
9083}
9084
9085void
9086proto_set_cant_toggle(const int proto_id)
9087{
9088 protocol_t *protocol;
9089
9090 protocol = find_protocol_by_id(proto_id);
9091 protocol->can_toggle = false0;
9092}
9093
9094static int
9095proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9096{
9097 g_ptr_array_add(proto->fields, hfi);
9098
9099 return proto_register_field_init(hfi, parent);
9100}
9101
9102/* for use with static arrays only, since we don't allocate our own copies
9103of the header_field_info struct contained within the hf_register_info struct */
9104void
9105proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9106{
9107 hf_register_info *ptr = hf;
9108 protocol_t *proto;
9109 int i;
9110
9111 proto = find_protocol_by_id(parent);
9112
9113 /* if (proto == NULL) - error or return? */
9114
9115 if (proto->fields == NULL((void*)0)) {
9116 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9117 * GLib introduced g_ptr_array_new_from_array, which might have
9118 * given a reason to actually use it. (#17774)
9119 */
9120 proto->fields = g_ptr_array_sized_new(num_records);
9121 }
9122
9123 for (i = 0; i < num_records; i++, ptr++) {
9124 /*
9125 * Make sure we haven't registered this yet.
9126 * Most fields have variables associated with them that
9127 * are initialized to 0; some are initialized to -1 (which
9128 * was the standard before 4.4).
9129 *
9130 * XXX - Since this is called almost 300000 times at startup,
9131 * it might be nice to compare to only 0 and require
9132 * dissectors to pass in zero for unregistered fields.
9133 */
9134 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9135 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9136 "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)
9137 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9138 return;
9139 }
9140
9141 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9142 }
9143}
9144
9145/* deregister already registered fields */
9146void
9147proto_deregister_field (const int parent, int hf_id)
9148{
9149 header_field_info *hfi;
9150 protocol_t *proto;
9151 unsigned i;
9152
9153 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
9154 last_field_name = NULL((void*)0);
9155
9156 if (hf_id == -1 || hf_id == 0)
9157 return;
9158
9159 proto = find_protocol_by_id (parent);
9160 if (!proto || proto->fields == NULL((void*)0)) {
9161 return;
9162 }
9163
9164 for (i = 0; i < proto->fields->len; i++) {
9165 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9166 if (hfi->id == hf_id) {
9167 /* Found the hf_id in this protocol */
9168 wmem_map_remove(gpa_name_map, hfi->abbrev);
9169 g_ptr_array_remove_index_fast(proto->fields, i);
9170 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9171 return;
9172 }
9173 }
9174}
9175
9176/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9177void
9178proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9179{
9180 header_field_info *hfinfo;
9181 protocol_t *proto;
9182
9183 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
9184 last_field_name = NULL((void*)0);
9185
9186 proto = find_protocol_by_id(parent);
9187 if (proto && proto->fields && proto->fields->len > 0) {
9188 unsigned i = proto->fields->len;
9189 do {
9190 i--;
9191
9192 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9193 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) )
) {
9194 hfinfo_remove_from_gpa_name_map(hfinfo);
9195 expert_deregister_expertinfo(hfinfo->abbrev);
9196 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9197 g_ptr_array_remove_index_fast(proto->fields, i);
9198 }
9199 } while (i > 0);
9200 }
9201}
9202
9203void
9204proto_add_deregistered_data (void *data)
9205{
9206 g_ptr_array_add(deregistered_data, data);
9207}
9208
9209void
9210proto_add_deregistered_slice (size_t block_size, void *mem_block)
9211{
9212 struct g_slice_data *slice_data = g_slice_new(struct g_slice_data)((struct g_slice_data*) g_slice_alloc ((sizeof (struct g_slice_data
) > 0 ? sizeof (struct g_slice_data) : 1)))
;
9213
9214 slice_data->block_size = block_size;
9215 slice_data->mem_block = mem_block;
9216
9217 g_ptr_array_add(deregistered_slice, slice_data);
9218}
9219
9220void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9221{
9222 if (field_strings == NULL((void*)0)) {
9223 return;
9224 }
9225
9226 switch (field_type) {
9227 case FT_FRAMENUM:
9228 /* This is just an integer represented as a pointer */
9229 break;
9230 case FT_PROTOCOL: {
9231 protocol_t *protocol = (protocol_t *)field_strings;
9232 g_free((char *)protocol->short_name)(__builtin_object_size (((char *)protocol->short_name), 0)
!= ((size_t) - 1)) ? g_free_sized ((char *)protocol->short_name
, __builtin_object_size (((char *)protocol->short_name), 0
)) : (g_free) ((char *)protocol->short_name)
;
9233 break;
9234 }
9235 case FT_BOOLEAN: {
9236 true_false_string *tf = (true_false_string *)field_strings;
9237 g_free((char *)tf->true_string)(__builtin_object_size (((char *)tf->true_string), 0) != (
(size_t) - 1)) ? g_free_sized ((char *)tf->true_string, __builtin_object_size
(((char *)tf->true_string), 0)) : (g_free) ((char *)tf->
true_string)
;
9238 g_free((char *)tf->false_string)(__builtin_object_size (((char *)tf->false_string), 0) != (
(size_t) - 1)) ? g_free_sized ((char *)tf->false_string, __builtin_object_size
(((char *)tf->false_string), 0)) : (g_free) ((char *)tf->
false_string)
;
9239 break;
9240 }
9241 case FT_UINT40:
9242 case FT_INT40:
9243 case FT_UINT48:
9244 case FT_INT48:
9245 case FT_UINT56:
9246 case FT_INT56:
9247 case FT_UINT64:
9248 case FT_INT64: {
9249 if (field_display & BASE_UNIT_STRING0x00001000) {
9250 unit_name_string *unit = (unit_name_string *)field_strings;
9251 g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != ((
size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size
(((char *)unit->singular), 0)) : (g_free) ((char *)unit->
singular)
;
9252 g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size
(((char *)unit->plural), 0)) : (g_free) ((char *)unit->
plural)
;
9253 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9254 range_string *rs = (range_string *)field_strings;
9255 while (rs->strptr) {
9256 g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size
(((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr
)
;
9257 rs++;
9258 }
9259 } else if (field_display & BASE_EXT_STRING0x00000200) {
9260 val64_string_ext *vse = (val64_string_ext *)field_strings;
9261 val64_string *vs = (val64_string *)vse->_vs_p;
9262 while (vs->strptr) {
9263 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9264 vs++;
9265 }
9266 val64_string_ext_free(vse);
9267 field_strings = NULL((void*)0);
9268 } else if (field_display == BASE_CUSTOM) {
9269 /* this will be a pointer to a function, don't free that */
9270 field_strings = NULL((void*)0);
9271 } else {
9272 val64_string *vs64 = (val64_string *)field_strings;
9273 while (vs64->strptr) {
9274 g_free((char *)vs64->strptr)(__builtin_object_size (((char *)vs64->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs64->strptr, __builtin_object_size
(((char *)vs64->strptr), 0)) : (g_free) ((char *)vs64->
strptr)
;
9275 vs64++;
9276 }
9277 }
9278 break;
9279 }
9280 case FT_CHAR:
9281 case FT_UINT8:
9282 case FT_INT8:
9283 case FT_UINT16:
9284 case FT_INT16:
9285 case FT_UINT24:
9286 case FT_INT24:
9287 case FT_UINT32:
9288 case FT_INT32:
9289 case FT_FLOAT:
9290 case FT_DOUBLE: {
9291 if (field_display & BASE_UNIT_STRING0x00001000) {
9292 unit_name_string *unit = (unit_name_string *)field_strings;
9293 g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != ((
size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size
(((char *)unit->singular), 0)) : (g_free) ((char *)unit->
singular)
;
9294 g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size
(((char *)unit->plural), 0)) : (g_free) ((char *)unit->
plural)
;
9295 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9296 range_string *rs = (range_string *)field_strings;
9297 while (rs->strptr) {
9298 g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size
(((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr
)
;
9299 rs++;
9300 }
9301 } else if (field_display & BASE_EXT_STRING0x00000200) {
9302 value_string_ext *vse = (value_string_ext *)field_strings;
9303 value_string *vs = (value_string *)vse->_vs_p;
9304 while (vs->strptr) {
9305 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9306 vs++;
9307 }
9308 value_string_ext_free(vse);
9309 field_strings = NULL((void*)0);
9310 } else if (field_display == BASE_CUSTOM) {
9311 /* this will be a pointer to a function, don't free that */
9312 field_strings = NULL((void*)0);
9313 } else {
9314 value_string *vs = (value_string *)field_strings;
9315 while (vs->strptr) {
9316 g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size
(((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr
)
;
9317 vs++;
9318 }
9319 }
9320 break;
9321 default:
9322 break;
9323 }
9324 }
9325
9326 if (field_type != FT_FRAMENUM) {
9327 g_free((void *)field_strings)(__builtin_object_size (((void *)field_strings), 0) != ((size_t
) - 1)) ? g_free_sized ((void *)field_strings, __builtin_object_size
(((void *)field_strings), 0)) : (g_free) ((void *)field_strings
)
;
9328 }
9329}
9330
9331static void
9332free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9333{
9334 header_field_info *hfi = (header_field_info *) data;
9335 int hf_id = hfi->id;
9336
9337 g_free((char *)hfi->name)(__builtin_object_size (((char *)hfi->name), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->name, __builtin_object_size
(((char *)hfi->name), 0)) : (g_free) ((char *)hfi->name
)
;
9338 g_free((char *)hfi->abbrev)(__builtin_object_size (((char *)hfi->abbrev), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->abbrev, __builtin_object_size
(((char *)hfi->abbrev), 0)) : (g_free) ((char *)hfi->abbrev
)
;
9339 g_free((char *)hfi->blurb)(__builtin_object_size (((char *)hfi->blurb), 0) != ((size_t
) - 1)) ? g_free_sized ((char *)hfi->blurb, __builtin_object_size
(((char *)hfi->blurb), 0)) : (g_free) ((char *)hfi->blurb
)
;
9340
9341 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9342
9343 if (hfi->parent == -1)
9344 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)
;
9345
9346 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9347}
9348
9349static void
9350free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9351{
9352 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9353}
9354
9355static void
9356free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9357{
9358 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9359
9360 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9361 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)
;
9362}
9363
9364/* free deregistered fields and data */
9365void
9366proto_free_deregistered_fields (void)
9367{
9368 expert_free_deregistered_expertinfos();
9369
9370 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9371 g_ptr_array_free(deregistered_fields, true1);
9372 deregistered_fields = g_ptr_array_new();
9373
9374 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9375 g_ptr_array_free(deregistered_data, true1);
9376 deregistered_data = g_ptr_array_new();
9377
9378 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9379 g_ptr_array_free(deregistered_slice, true1);
9380 deregistered_slice = g_ptr_array_new();
9381}
9382
9383static const value_string hf_display[] = {
9384 { BASE_NONE, "BASE_NONE" },
9385 { BASE_DEC, "BASE_DEC" },
9386 { BASE_HEX, "BASE_HEX" },
9387 { BASE_OCT, "BASE_OCT" },
9388 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9389 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9390 { BASE_CUSTOM, "BASE_CUSTOM" },
9391 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9392 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9393 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9394 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9395 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9396 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9397 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9398 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9399 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9400 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9401 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9402 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9403 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9404 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9405 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9406 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9407 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9408 { BASE_PT_UDP, "BASE_PT_UDP" },
9409 { BASE_PT_TCP, "BASE_PT_TCP" },
9410 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9411 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9412 { BASE_OUI, "BASE_OUI" },
9413 { 0, NULL((void*)0) } };
9414
9415const char* proto_field_display_to_string(int field_display)
9416{
9417 return val_to_str_const(field_display, hf_display, "Unknown");
9418}
9419
9420static inline port_type
9421display_to_port_type(field_display_e e)
9422{
9423 switch (e) {
9424 case BASE_PT_UDP:
9425 return PT_UDP;
9426 case BASE_PT_TCP:
9427 return PT_TCP;
9428 case BASE_PT_DCCP:
9429 return PT_DCCP;
9430 case BASE_PT_SCTP:
9431 return PT_SCTP;
9432 default:
9433 break;
9434 }
9435 return PT_NONE;
9436}
9437
9438/* temporary function containing assert part for easier profiling */
9439static void
9440tmp_fld_check_assert(header_field_info *hfinfo)
9441{
9442 char* tmp_str;
9443
9444 /* The field must have a name (with length > 0) */
9445 if (!hfinfo->name || !hfinfo->name[0]) {
9446 if (hfinfo->abbrev)
9447 /* Try to identify the field */
9448 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)
9449 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9450 else
9451 /* Hum, no luck */
9452 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)"
)
;
9453 }
9454
9455 /* fields with an empty string for an abbreviation aren't filterable */
9456 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9457 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)
;
9458
9459 /* TODO: This check is a significant percentage of startup time (~10%),
9460 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9461 It might be nice to have a way to disable this check when, e.g.,
9462 running TShark many times with the same configuration. */
9463 /* Check that the filter name (abbreviation) is legal;
9464 * it must contain only alphanumerics, '-', "_", and ".". */
9465 unsigned char c;
9466 c = module_check_valid_name(hfinfo->abbrev, false0);
9467 if (c) {
9468 if (c == '.') {
9469 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)
;
9470 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9471 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)
;
9472 } else {
9473 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)
;
9474 }
9475 }
9476
9477 /* These types of fields are allowed to have value_strings,
9478 * true_false_strings or a protocol_t struct
9479 */
9480 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9481 switch (hfinfo->type) {
9482
9483 /*
9484 * These types are allowed to support display value_strings,
9485 * value64_strings, the extended versions of the previous
9486 * two, range strings, or unit strings.
9487 */
9488 case FT_CHAR:
9489 case FT_UINT8:
9490 case FT_UINT16:
9491 case FT_UINT24:
9492 case FT_UINT32:
9493 case FT_UINT40:
9494 case FT_UINT48:
9495 case FT_UINT56:
9496 case FT_UINT64:
9497 case FT_INT8:
9498 case FT_INT16:
9499 case FT_INT24:
9500 case FT_INT32:
9501 case FT_INT40:
9502 case FT_INT48:
9503 case FT_INT56:
9504 case FT_INT64:
9505 case FT_BOOLEAN:
9506 case FT_PROTOCOL:
9507 break;
9508
9509 /*
9510 * This is allowed to have a value of type
9511 * enum ft_framenum_type to indicate what relationship
9512 * the frame in question has to the frame in which
9513 * the field is put.
9514 */
9515 case FT_FRAMENUM:
9516 break;
9517
9518 /*
9519 * These types are allowed to support only unit strings.
9520 */
9521 case FT_FLOAT:
9522 case FT_DOUBLE:
9523 case FT_IEEE_11073_SFLOAT:
9524 case FT_IEEE_11073_FLOAT:
9525 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9526 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))
9527 " (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))
9528 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))
;
9529 }
9530 break;
9531
9532 /*
9533 * These types are allowed to support display
9534 * time_value_strings.
9535 */
9536 case FT_ABSOLUTE_TIME:
9537 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9538 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9539 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9540 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9541 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))
9542 " (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))
9543 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))
;
9544 }
9545 break;
9546
9547 /*
9548 * This type is only allowed to support a string if it's
9549 * a protocol (for pinos).
9550 */
9551 case FT_BYTES:
9552 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9553 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))
9554 " (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))
9555 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))
;
9556 }
9557 break;
9558
9559 default:
9560 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))
9561 " (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))
9562 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))
;
9563 }
9564 }
9565
9566 /* TODO: This check may slow down startup, and output quite a few warnings.
9567 It would be good to be able to enable this (and possibly other checks?)
9568 in non-release builds. */
9569#ifdef ENABLE_CHECK_FILTER
9570 /* Check for duplicate value_string values.
9571 There are lots that have the same value *and* string, so for now only
9572 report those that have same value but different string. */
9573 if ((hfinfo->strings != NULL((void*)0)) &&
9574 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9575 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9576 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9577 (
9578 (hfinfo->type == FT_CHAR) ||
9579 (hfinfo->type == FT_UINT8) ||
9580 (hfinfo->type == FT_UINT16) ||
9581 (hfinfo->type == FT_UINT24) ||
9582 (hfinfo->type == FT_UINT32) ||
9583 (hfinfo->type == FT_INT8) ||
9584 (hfinfo->type == FT_INT16) ||
9585 (hfinfo->type == FT_INT24) ||
9586 (hfinfo->type == FT_INT32) )) {
9587
9588 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9589 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9590 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9591 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9592 } else {
9593 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9594 CHECK_HF_VALUE(value_string, "u", start_values);
9595 }
9596 } else {
9597 const value_string *start_values = (const value_string*)hfinfo->strings;
9598 CHECK_HF_VALUE(value_string, "u", start_values);
9599 }
9600 }
9601
9602 if (hfinfo->type == FT_BOOLEAN) {
9603 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9604 if (tfs) {
9605 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9606 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9608
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9607 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9608
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9608 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9608
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9609 }
9610 }
9611 }
9612
9613 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9614 const range_string *rs = (const range_string*)(hfinfo->strings);
9615 if (rs) {
9616 const range_string *this_it = rs;
9617
9618 do {
9619 if (this_it->value_max < this_it->value_min) {
9620 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"
, 9624, __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)
9621 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9624, __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)
9622 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9624, __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)
9623 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9624, __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)
9624 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9624, __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)
;
9625 ++this_it;
9626 continue;
9627 }
9628
9629 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9630 /* Not OK if this one is completely hidden by an earlier one! */
9631 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9632 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"
, 9638, __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)
9633 "(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"
, 9638, __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)
9634 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9638, __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)
9635 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9638, __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)
9636 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9638, __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)
9637 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9638, __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)
9638 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9638, __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)
;
9639 }
9640 }
9641 ++this_it;
9642 } while (this_it->strptr);
9643 }
9644 }
9645#endif
9646
9647 switch (hfinfo->type) {
9648
9649 case FT_CHAR:
9650 /* Require the char type to have BASE_HEX, BASE_OCT,
9651 * BASE_CUSTOM, or BASE_NONE as its base.
9652 *
9653 * If the display value is BASE_NONE and there is a
9654 * strings conversion then the dissector writer is
9655 * telling us that the field's numerical value is
9656 * meaningless; we'll avoid showing the value to the
9657 * user.
9658 */
9659 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9660 case BASE_HEX:
9661 case BASE_OCT:
9662 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9663 break;
9664 case BASE_NONE:
9665 if (hfinfo->strings == NULL((void*)0))
9666 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
))
9667 " 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
))
9668 " 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
))
9669 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
))
9670 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
))
;
9671 break;
9672 default:
9673 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9674 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)
9675 " 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)
9676 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)
9677 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)
;
9678 //wmem_free(NULL, tmp_str);
9679 }
9680 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9681 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
))
9682 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
))
9683 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
))
;
9684 }
9685 break;
9686 case FT_INT8:
9687 case FT_INT16:
9688 case FT_INT24:
9689 case FT_INT32:
9690 case FT_INT40:
9691 case FT_INT48:
9692 case FT_INT56:
9693 case FT_INT64:
9694 /* Hexadecimal and octal are, in printf() and everywhere
9695 * else, unsigned so don't allow dissectors to register a
9696 * signed field to be displayed unsigned. (Else how would
9697 * we display negative values?)
9698 */
9699 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9700 case BASE_HEX:
9701 case BASE_OCT:
9702 case BASE_DEC_HEX:
9703 case BASE_HEX_DEC:
9704 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9705 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)
9706 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)
9707 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)
;
9708 //wmem_free(NULL, tmp_str);
9709 }
9710 /* FALL THROUGH */
9711 case FT_UINT8:
9712 case FT_UINT16:
9713 case FT_UINT24:
9714 case FT_UINT32:
9715 case FT_UINT40:
9716 case FT_UINT48:
9717 case FT_UINT56:
9718 case FT_UINT64:
9719 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
))
) {
9720 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9721 if (hfinfo->type != FT_UINT16) {
9722 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))
9723 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))
9724 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))
;
9725 }
9726 if (hfinfo->strings != NULL((void*)0)) {
9727 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)
9728 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)
9729 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)
;
9730 }
9731 if (hfinfo->bitmask != 0) {
9732 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)
9733 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)
9734 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)
;
9735 }
9736 wmem_free(NULL((void*)0), tmp_str);
9737 break;
9738 }
9739
9740 if (hfinfo->display == BASE_OUI) {
9741 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9742 if (!FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| ftype_wire_size(hfinfo->type) < 3) {
9743 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))
9744 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))
9745 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))
;
9746 }
9747 if (hfinfo->strings != NULL((void*)0)) {
9748 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)
9749 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)
9750 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)
;
9751 }
9752 /* It can be a FT_UINT24 with a 0 bitmask, or
9753 * larger with a bitmask with 24 bits set. */
9754 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9755 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)
9756 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)
9757 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)
;
9758 }
9759 wmem_free(NULL((void*)0), tmp_str);
9760 break;
9761 }
9762
9763 /* Require integral types (other than frame number,
9764 * which is always displayed in decimal) to have a
9765 * number base.
9766 *
9767 * If the display value is BASE_NONE and there is a
9768 * strings conversion then the dissector writer is
9769 * telling us that the field's numerical value is
9770 * meaningless; we'll avoid showing the value to the
9771 * user.
9772 */
9773 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9774 case BASE_DEC:
9775 case BASE_HEX:
9776 case BASE_OCT:
9777 case BASE_DEC_HEX:
9778 case BASE_HEX_DEC:
9779 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9780 break;
9781 case BASE_NONE:
9782 if (hfinfo->strings == NULL((void*)0)) {
9783 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
))
9784 " 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
))
9785 " 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
))
9786 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
))
9787 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
))
;
9788 }
9789 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9790 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
))
9791 " 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
))
9792 " 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
))
9793 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
))
9794 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
))
;
9795 }
9796 break;
9797
9798 default:
9799 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9800 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)
9801 " 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)
9802 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)
9803 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)
;
9804 //wmem_free(NULL, tmp_str);
9805 }
9806 break;
9807 case FT_BYTES:
9808 case FT_UINT_BYTES:
9809 /* Require bytes to have a "display type" that could
9810 * add a character between displayed bytes.
9811 */
9812 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9813 case BASE_NONE:
9814 case SEP_DOT:
9815 case SEP_DASH:
9816 case SEP_COLON:
9817 case SEP_SPACE:
9818 break;
9819 default:
9820 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9821 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)
9822 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)
;
9823 //wmem_free(NULL, tmp_str);
9824 }
9825 if (hfinfo->bitmask != 0)
9826 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
))
9827 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
))
9828 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
))
;
9829 //allowed to support string if its a protocol (for pinos)
9830 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9831 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9832 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9833 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9834 break;
9835
9836 case FT_PROTOCOL:
9837 case FT_FRAMENUM:
9838 if (hfinfo->display != BASE_NONE) {
9839 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9840 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)
9841 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)
9842 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)
;
9843 //wmem_free(NULL, tmp_str);
9844 }
9845 if (hfinfo->bitmask != 0)
9846 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9847 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9848 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9849 break;
9850
9851 case FT_BOOLEAN:
9852 break;
9853
9854 case FT_ABSOLUTE_TIME:
9855 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9856 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9857 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)
9858 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)
;
9859 //wmem_free(NULL, tmp_str);
9860 }
9861 if (hfinfo->bitmask != 0)
9862 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9863 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9864 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9865 break;
9866
9867 case FT_STRING:
9868 case FT_STRINGZ:
9869 case FT_UINT_STRING:
9870 case FT_STRINGZPAD:
9871 case FT_STRINGZTRUNC:
9872 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9873 case BASE_NONE:
9874 case BASE_STR_WSP:
9875 break;
9876
9877 default:
9878 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9879 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)
9880 " 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)
9881 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)
9882 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)
;
9883 //wmem_free(NULL, tmp_str);
9884 }
9885
9886 if (hfinfo->bitmask != 0)
9887 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
))
9888 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
))
9889 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
))
;
9890 if (hfinfo->strings != NULL((void*)0))
9891 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
))
9892 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
))
9893 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
))
;
9894 break;
9895
9896 case FT_IPv4:
9897 switch (hfinfo->display) {
9898 case BASE_NONE:
9899 case BASE_NETMASK:
9900 break;
9901
9902 default:
9903 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9904 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)
9905 " 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)
9906 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)
9907 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)
;
9908 //wmem_free(NULL, tmp_str);
9909 break;
9910 }
9911 break;
9912 case FT_FLOAT:
9913 case FT_DOUBLE:
9914 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9915 case BASE_NONE:
9916 case BASE_DEC:
9917 case BASE_HEX:
9918 case BASE_EXP:
9919 case BASE_CUSTOM:
9920 break;
9921 default:
9922 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9923 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)
9924 " 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)
9925 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)
9926 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)
;
9927 //wmem_free(NULL, tmp_str);
9928 }
9929 if (hfinfo->bitmask != 0)
9930 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
))
9931 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
))
9932 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
))
;
9933 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9934 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
))
9935 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
))
9936 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
))
;
9937 break;
9938 case FT_IEEE_11073_SFLOAT:
9939 case FT_IEEE_11073_FLOAT:
9940 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9941 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9942 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)
9943 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)
9944 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)
9945 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)
;
9946 //wmem_free(NULL, tmp_str);
9947 }
9948 if (hfinfo->bitmask != 0)
9949 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
))
9950 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
))
9951 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
))
;
9952 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9953 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
))
9954 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
))
9955 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
))
;
9956 break;
9957 default:
9958 if (hfinfo->display != BASE_NONE) {
9959 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9960 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)
9961 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)
9962 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)
9963 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)
;
9964 //wmem_free(NULL, tmp_str);
9965 }
9966 if (hfinfo->bitmask != 0)
9967 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
))
9968 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
))
9969 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
))
;
9970 if (hfinfo->strings != NULL((void*)0))
9971 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
))
9972 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
))
9973 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
))
;
9974 break;
9975 }
9976}
9977
9978static void
9979register_type_length_mismatch(void)
9980{
9981 static ei_register_info ei[] = {
9982 { &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)}}
}},
9983 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch_warn", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
9984 };
9985
9986 expert_module_t* expert_type_length_mismatch;
9987
9988 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9989
9990 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9991 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9992
9993 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9994 disabling them makes no sense. */
9995 proto_set_cant_toggle(proto_type_length_mismatch);
9996}
9997
9998static void
9999register_byte_array_string_decodinws_error(void)
10000{
10001 static ei_register_info ei[] = {
10002 { &ei_byte_array_string_decoding_failed_error,
10003 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10004 "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)}}
10005 }
10006 },
10007 };
10008
10009 expert_module_t* expert_byte_array_string_decoding_error;
10010
10011 proto_byte_array_string_decoding_error =
10012 proto_register_protocol("Byte Array-String Decoding Error",
10013 "Byte Array-string decoding error",
10014 "_ws.byte_array_string.decoding_error");
10015
10016 expert_byte_array_string_decoding_error =
10017 expert_register_protocol(proto_byte_array_string_decoding_error);
10018 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10019
10020 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10021 disabling them makes no sense. */
10022 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10023}
10024
10025static void
10026register_date_time_string_decodinws_error(void)
10027{
10028 static ei_register_info ei[] = {
10029 { &ei_date_time_string_decoding_failed_error,
10030 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10031 "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)}}
10032 }
10033 },
10034 };
10035
10036 expert_module_t* expert_date_time_string_decoding_error;
10037
10038 proto_date_time_string_decoding_error =
10039 proto_register_protocol("Date and Time-String Decoding Error",
10040 "Date and Time-string decoding error",
10041 "_ws.date_time_string.decoding_error");
10042
10043 expert_date_time_string_decoding_error =
10044 expert_register_protocol(proto_date_time_string_decoding_error);
10045 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10046
10047 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10048 disabling them makes no sense. */
10049 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10050}
10051
10052static void
10053register_string_errors(void)
10054{
10055 static ei_register_info ei[] = {
10056 { &ei_string_trailing_characters,
10057 { "_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)}}
}
10058 },
10059 };
10060
10061 expert_module_t* expert_string_errors;
10062
10063 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10064
10065 expert_string_errors = expert_register_protocol(proto_string_errors);
10066 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10067
10068 /* "String Errors" isn't really a protocol, it's an error indication;
10069 disabling them makes no sense. */
10070 proto_set_cant_toggle(proto_string_errors);
10071}
10072
10073static int
10074proto_register_field_init(header_field_info *hfinfo, const int parent)
10075{
10076
10077 tmp_fld_check_assert(hfinfo);
10078
10079 hfinfo->parent = parent;
10080 hfinfo->same_name_next = NULL((void*)0);
10081 hfinfo->same_name_prev_id = -1;
10082
10083 /* if we always add and never delete, then id == len - 1 is correct */
10084 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10085 if (!gpa_hfinfo.hfi) {
10086 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10087 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10088 /* The entry with index 0 is not used. */
10089 gpa_hfinfo.hfi[0] = NULL((void*)0);
10090 gpa_hfinfo.len = 1;
10091 } else {
10092 gpa_hfinfo.allocated_len += 1000;
10093 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10094 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10095 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10096 }
10097 }
10098 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10099 gpa_hfinfo.len++;
10100 hfinfo->id = gpa_hfinfo.len - 1;
10101
10102 /* if we have real names, enter this field in the name tree */
10103 /* Already checked in tmp_fld_check_assert */
10104 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10105 {
10106
10107 header_field_info *same_name_next_hfinfo;
10108
10109 /* We allow multiple hfinfo's to be registered under the same
10110 * abbreviation. This was done for X.25, as, depending
10111 * on whether it's modulo-8 or modulo-128 operation,
10112 * some bitfield fields may be in different bits of
10113 * a byte, and we want to be able to refer to that field
10114 * with one name regardless of whether the packets
10115 * are modulo-8 or modulo-128 packets. */
10116
10117 /* wmem_map_insert - if key is already present the previous
10118 * hfinfo with the same key/name is returned, otherwise NULL */
10119 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10120 if (same_name_hfinfo) {
10121 /* There's already a field with this name.
10122 * Put the current field *before* that field
10123 * in the list of fields with this name, Thus,
10124 * we end up with an effectively
10125 * doubly-linked-list of same-named hfinfo's,
10126 * with the head of the list (stored in the
10127 * hash) being the last seen hfinfo.
10128 */
10129 same_name_next_hfinfo =
10130 same_name_hfinfo->same_name_next;
10131
10132 hfinfo->same_name_next = same_name_next_hfinfo;
10133 if (same_name_next_hfinfo)
10134 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10135
10136 same_name_hfinfo->same_name_next = hfinfo;
10137 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10138#ifdef ENABLE_CHECK_FILTER
10139 while (same_name_hfinfo) {
10140 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10141 ws_error("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10141
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10142 same_name_hfinfo = same_name_hfinfo->same_name_next;
10143 }
10144#endif
10145 }
10146 }
10147
10148 return hfinfo->id;
10149}
10150
10151void
10152proto_register_subtree_array(int * const *indices, const int num_indices)
10153{
10154 int i;
10155 int *const *ptr = indices;
10156
10157 /*
10158 * If we've already allocated the array of tree types, expand
10159 * it; this lets plugins such as mate add tree types after
10160 * the initial startup. (If we haven't already allocated it,
10161 * we don't allocate it; on the first pass, we just assign
10162 * ett values and keep track of how many we've assigned, and
10163 * when we're finished registering all dissectors we allocate
10164 * the array, so that we do only one allocation rather than
10165 * wasting CPU time and memory by growing the array for each
10166 * dissector that registers ett values.)
10167 */
10168 if (tree_is_expanded != NULL((void*)0)) {
10169 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10170
10171 /* set new items to 0 */
10172 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10173 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10174 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10175 }
10176
10177 /*
10178 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10179 * returning the indices through the pointers in the array whose
10180 * first element is pointed to by "indices", and update
10181 * "num_tree_types" appropriately.
10182 */
10183 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10184 if (**ptr != -1 && **ptr != 0) {
10185 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.")
10186 " 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.")
10187 " 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.")
10188 " 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.")
;
10189 }
10190 **ptr = num_tree_types;
10191 }
10192}
10193
10194static void
10195mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10196{
10197 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10198 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10199 char *last_char;
10200
10201 /* ..... field_name: dataaaaaaaaaaaaa
10202 * |
10203 * ^^^^^ name_pos
10204 *
10205 * ..... field_name […]: dataaaaaaaaaaaaa
10206 *
10207 * name_pos==0 means that we have only data or only a field_name
10208 */
10209
10210 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10210, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10211
10212 if (name_pos >= size - trunc_len) {
10213 /* No room for trunc_str after the field_name, put it first. */
10214 name_pos = 0;
10215 }
10216
10217 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10218 if (name_pos == 0) {
10219 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10220 memcpy(label_str, trunc_str + 1, trunc_len);
10221 } else {
10222 memcpy(label_str + name_pos, trunc_str, trunc_len);
10223 }
10224 /* in general, label_str is UTF-8
10225 we can truncate it only at the beginning of a new character
10226 we go backwards from the byte right after our buffer and
10227 find the next starting byte of a UTF-8 character, this is
10228 where we cut
10229 there's no need to use g_utf8_find_prev_char(), the search
10230 will always succeed since we copied trunc_str into the
10231 buffer */
10232 /* g_utf8_prev_char does not deference the memory address
10233 * passed in (until after decrementing it, so it is perfectly
10234 * legal to pass in a pointer one past the last element.
10235 */
10236 last_char = g_utf8_prev_char(label_str + size);
10237 *last_char = '\0';
10238 /* This is unnecessary (above always terminates), but try to
10239 * convince Coverity to avoid dozens of false positives. */
10240 label_str[size - 1] = '\0';
10241
10242 if (value_pos && *value_pos > 0) {
10243 if (name_pos == 0) {
10244 *value_pos += trunc_len;
10245 } else {
10246 /* Move one back to include trunc_str in the value. */
10247 *value_pos -= 1;
10248 }
10249 }
10250
10251 /* Check if value_pos is past label_str. */
10252 if (value_pos && *value_pos >= size) {
10253 *value_pos = size - 1;
10254 }
10255}
10256
10257static void
10258label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10259{
10260 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10261}
10262
10263static size_t
10264label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10265{
10266 size_t name_pos;
10267
10268 /* "%s: %s", hfinfo->name, text */
10269 name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo->
name, 0)
;
10270 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10271 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10272 if (value_pos) {
10273 *value_pos = pos;
10274 }
10275 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10276 }
10277
10278 if (pos >= ITEM_LABEL_LENGTH240) {
10279 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10280 label_mark_truncated(label_str, name_pos, value_pos);
10281 }
10282
10283 return pos;
10284}
10285
10286static size_t
10287label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10288{
10289 size_t name_pos;
10290
10291 /* "%s: %s (%s)", hfinfo->name, text, descr */
10292 name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo->
name, 0)
;
10293 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10294 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10295 if (value_pos) {
10296 *value_pos = pos;
10297 }
10298 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10299 pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ?
descr : "(null)"), 0)
;
10300 pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text
: "(null)"), 0)
;
10301 } else {
10302 pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text
: "(null)"), 0)
;
10303 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10304 pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ?
descr : "(null)"), 0)
;
10305 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10306 }
10307 }
10308
10309 if (pos >= ITEM_LABEL_LENGTH240) {
10310 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10311 label_mark_truncated(label_str, name_pos, value_pos);
10312 }
10313
10314 return pos;
10315}
10316
10317void
10318proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10319{
10320 const header_field_info *hfinfo;
10321 const char *str;
10322 const uint8_t *bytes;
10323 uint32_t integer;
10324 const ipv4_addr_and_mask *ipv4;
10325 const ipv6_addr_and_prefix *ipv6;
10326 const e_guid_t *guid;
10327 char *name;
10328 address addr;
10329 char *addr_str;
10330 char *tmp;
10331
10332 if (!label_str) {
10333 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10333, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10334 return;
10335 }
10336
10337 label_str[0]= '\0';
10338
10339 if (!fi) {
10340 return;
10341 }
10342
10343 hfinfo = fi->hfinfo;
10344
10345 switch (hfinfo->type) {
10346 case FT_NONE:
10347 case FT_PROTOCOL:
10348 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10349 if (value_pos) {
10350 *value_pos = strlen(hfinfo->name);
10351 }
10352 break;
10353
10354 case FT_BOOLEAN:
10355 fill_label_boolean(fi, label_str, value_pos);
10356 break;
10357
10358 case FT_BYTES:
10359 case FT_UINT_BYTES:
10360 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10361 fvalue_get_bytes_data(fi->value),
10362 (unsigned)fvalue_length2(fi->value));
10363 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10364 wmem_free(NULL((void*)0), tmp);
10365 break;
10366
10367 case FT_CHAR:
10368 if (hfinfo->bitmask) {
10369 fill_label_bitfield_char(fi, label_str, value_pos);
10370 } else {
10371 fill_label_char(fi, label_str, value_pos);
10372 }
10373 break;
10374
10375 /* Four types of integers to take care of:
10376 * Bitfield, with val_string
10377 * Bitfield, w/o val_string
10378 * Non-bitfield, with val_string
10379 * Non-bitfield, w/o val_string
10380 */
10381 case FT_UINT8:
10382 case FT_UINT16:
10383 case FT_UINT24:
10384 case FT_UINT32:
10385 if (hfinfo->bitmask) {
10386 fill_label_bitfield(fi, label_str, value_pos, false0);
10387 } else {
10388 fill_label_number(fi, label_str, value_pos, false0);
10389 }
10390 break;
10391
10392 case FT_FRAMENUM:
10393 fill_label_number(fi, label_str, value_pos, false0);
10394 break;
10395
10396 case FT_UINT40:
10397 case FT_UINT48:
10398 case FT_UINT56:
10399 case FT_UINT64:
10400 if (hfinfo->bitmask) {
10401 fill_label_bitfield64(fi, label_str, value_pos, false0);
10402 } else {
10403 fill_label_number64(fi, label_str, value_pos, false0);
10404 }
10405 break;
10406
10407 case FT_INT8:
10408 case FT_INT16:
10409 case FT_INT24:
10410 case FT_INT32:
10411 if (hfinfo->bitmask) {
10412 fill_label_bitfield(fi, label_str, value_pos, true1);
10413 } else {
10414 fill_label_number(fi, label_str, value_pos, true1);
10415 }
10416 break;
10417
10418 case FT_INT40:
10419 case FT_INT48:
10420 case FT_INT56:
10421 case FT_INT64:
10422 if (hfinfo->bitmask) {
10423 fill_label_bitfield64(fi, label_str, value_pos, true1);
10424 } else {
10425 fill_label_number64(fi, label_str, value_pos, true1);
10426 }
10427 break;
10428
10429 case FT_FLOAT:
10430 case FT_DOUBLE:
10431 fill_label_float(fi, label_str, value_pos);
10432 break;
10433
10434 case FT_ABSOLUTE_TIME:
10435 {
10436 const nstime_t *value = fvalue_get_time(fi->value);
10437 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10438 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10439 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10440 }
10441 if (hfinfo->strings) {
10442 /*
10443 * Table of time valus to be displayed
10444 * specially.
10445 */
10446 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10447 if (time_string != NULL((void*)0)) {
10448 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10449 break;
10450 }
10451 }
10452 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10453 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10454 wmem_free(NULL((void*)0), tmp);
10455 break;
10456 }
10457 case FT_RELATIVE_TIME:
10458 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10459 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10460 wmem_free(NULL((void*)0), tmp);
10461 break;
10462
10463 case FT_IPXNET:
10464 integer = fvalue_get_uinteger(fi->value);
10465 tmp = get_ipxnet_name(NULL((void*)0), integer);
10466 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10467 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10468 wmem_free(NULL((void*)0), tmp);
10469 wmem_free(NULL((void*)0), addr_str);
10470 break;
10471
10472 case FT_VINES:
10473 addr.type = AT_VINES;
10474 addr.len = VINES_ADDR_LEN6;
10475 addr.data = fvalue_get_bytes_data(fi->value);
10476
10477 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10478 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10479 wmem_free(NULL((void*)0), addr_str);
10480 break;
10481
10482 case FT_ETHER:
10483 bytes = fvalue_get_bytes_data(fi->value);
10484
10485 addr.type = AT_ETHER;
10486 addr.len = 6;
10487 addr.data = bytes;
10488
10489 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10490 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10491 wmem_free(NULL((void*)0), addr_str);
10492 break;
10493
10494 case FT_IPv4:
10495 ipv4 = fvalue_get_ipv4(fi->value);
10496 set_address_ipv4(&addr, ipv4);
10497
10498 if (hfinfo->display == BASE_NETMASK) {
10499 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10500 } else {
10501 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10502 }
10503 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10504 wmem_free(NULL((void*)0), addr_str);
10505 free_address(&addr);
10506 break;
10507
10508 case FT_IPv6:
10509 ipv6 = fvalue_get_ipv6(fi->value);
10510 set_address_ipv6(&addr, ipv6);
10511
10512 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10513 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10514 wmem_free(NULL((void*)0), addr_str);
10515 free_address(&addr);
10516 break;
10517
10518 case FT_FCWWN:
10519 bytes = fvalue_get_bytes_data(fi->value);
10520 addr.type = AT_FCWWN;
10521 addr.len = FCWWN_ADDR_LEN8;
10522 addr.data = bytes;
10523
10524 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10525 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10526 wmem_free(NULL((void*)0), addr_str);
10527 break;
10528
10529 case FT_GUID:
10530 guid = fvalue_get_guid(fi->value);
10531 tmp = guid_to_str(NULL((void*)0), guid);
10532 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10533 wmem_free(NULL((void*)0), tmp);
10534 break;
10535
10536 case FT_OID:
10537 bytes = fvalue_get_bytes_data(fi->value);
10538 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10539 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10540 if (name) {
10541 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10542 wmem_free(NULL((void*)0), name);
10543 } else {
10544 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10545 }
10546 wmem_free(NULL((void*)0), tmp);
10547 break;
10548
10549 case FT_REL_OID:
10550 bytes = fvalue_get_bytes_data(fi->value);
10551 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10552 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10553 if (name) {
10554 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10555 wmem_free(NULL((void*)0), name);
10556 } else {
10557 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10558 }
10559 wmem_free(NULL((void*)0), tmp);
10560 break;
10561
10562 case FT_SYSTEM_ID:
10563 bytes = fvalue_get_bytes_data(fi->value);
10564 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10565 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10566 wmem_free(NULL((void*)0), tmp);
10567 break;
10568
10569 case FT_EUI64:
10570 bytes = fvalue_get_bytes_data(fi->value);
10571 addr.type = AT_EUI64;
10572 addr.len = EUI64_ADDR_LEN8;
10573 addr.data = bytes;
10574
10575 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10576 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10577 wmem_free(NULL((void*)0), addr_str);
10578 break;
10579 case FT_STRING:
10580 case FT_STRINGZ:
10581 case FT_UINT_STRING:
10582 case FT_STRINGZPAD:
10583 case FT_STRINGZTRUNC:
10584 case FT_AX25:
10585 str = fvalue_get_string(fi->value);
10586 label_fill(label_str, 0, hfinfo, str, value_pos);
10587 break;
10588
10589 case FT_IEEE_11073_SFLOAT:
10590 case FT_IEEE_11073_FLOAT:
10591 fill_label_ieee_11073_float(fi, label_str, value_pos);
10592 break;
10593
10594 default:
10595 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
))
10596 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
))
10597 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
))
10598 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
))
;
10599 break;
10600 }
10601}
10602
10603static void
10604fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10605{
10606 char *p;
10607 unsigned bitfield_byte_length = 0;
10608 int bitwidth;
10609 uint64_t unshifted_value;
10610 uint64_t value;
10611
10612 const header_field_info *hfinfo = fi->hfinfo;
10613
10614 value = fvalue_get_uinteger64(fi->value);
10615 if (hfinfo->bitmask) {
10616 /* Figure out the bit width */
10617 bitwidth = hfinfo_container_bitwidth(hfinfo);
10618
10619 /* Un-shift bits */
10620 unshifted_value = value;
10621 unshifted_value <<= hfinfo_bitshift(hfinfo);
10622
10623 /* Create the bitfield first */
10624 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10625 bitfield_byte_length = (unsigned) (p - label_str);
10626 }
10627
10628 /* Fill in the textual info */
10629 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10630}
10631
10632static const char *
10633hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10634{
10635 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10636 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10637
10638 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10639 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10640 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10641 else
10642 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10643 }
10644
10645 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10646 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10647
10648 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10649 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10650
10651 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10652}
10653
10654static const char *
10655hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10656{
10657 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10658 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10659 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10660 else
10661 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10662 }
10663
10664 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10665 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10666
10667 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10668 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10669
10670 /* If this is reached somebody registered a 64-bit field with a 32-bit
10671 * value-string, which isn't right. */
10672 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)
10673 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10674
10675 /* This is necessary to squelch MSVC errors; is there
10676 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10677 never returns? */
10678 return NULL((void*)0);
10679}
10680
10681static const char *
10682hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10683{
10684 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10685 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10686
10687 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)
;
10688
10689 /* This is necessary to squelch MSVC errors; is there
10690 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10691 never returns? */
10692 return NULL((void*)0);
10693}
10694
10695static const char *
10696hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10697{
10698 const char *str = hf_try_val_to_str(value, hfinfo);
10699
10700 return (str) ? str : unknown_str;
10701}
10702
10703static const char *
10704hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10705{
10706 const char *str = hf_try_val64_to_str(value, hfinfo);
10707
10708 return (str) ? str : unknown_str;
10709}
10710
10711/* Fills data for bitfield chars with val_strings */
10712static void
10713fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10714{
10715 char *p;
10716 unsigned bitfield_byte_length;
10717 int bitwidth;
10718 uint32_t unshifted_value;
10719 uint32_t value;
10720
10721 char buf[32];
10722 const char *out;
10723
10724 const header_field_info *hfinfo = fi->hfinfo;
10725
10726 /* Figure out the bit width */
10727 bitwidth = hfinfo_container_bitwidth(hfinfo);
10728
10729 /* Un-shift bits */
10730 value = fvalue_get_uinteger(fi->value);
10731
10732 unshifted_value = value;
10733 if (hfinfo->bitmask) {
10734 unshifted_value <<= hfinfo_bitshift(hfinfo);
10735 }
10736
10737 /* Create the bitfield first */
10738 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10739 bitfield_byte_length = (unsigned) (p - label_str);
10740
10741 /* Fill in the textual info using stored (shifted) value */
10742 if (hfinfo->display == BASE_CUSTOM) {
10743 char tmp[ITEM_LABEL_LENGTH240];
10744 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10745
10746 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10746, "fmtfunc"))))
;
10747 fmtfunc(tmp, value);
10748 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10749 }
10750 else if (hfinfo->strings) {
10751 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10752
10753 out = hfinfo_char_vals_format(hfinfo, buf, value);
10754 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10755 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10756 else
10757 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10758 }
10759 else {
10760 out = hfinfo_char_value_format(hfinfo, buf, value);
10761
10762 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10763 }
10764}
10765
10766/* Fills data for bitfield ints with val_strings */
10767static void
10768fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10769{
10770 char *p;
10771 unsigned bitfield_byte_length;
10772 int bitwidth;
10773 uint32_t value, unshifted_value;
10774 char buf[NUMBER_LABEL_LENGTH80];
10775 const char *out;
10776
10777 const header_field_info *hfinfo = fi->hfinfo;
10778
10779 /* Figure out the bit width */
10780 if (fi->flags & FI_VARINT0x00040000)
10781 bitwidth = fi->length*8;
10782 else
10783 bitwidth = hfinfo_container_bitwidth(hfinfo);
10784
10785 /* Un-shift bits */
10786 if (is_signed)
10787 value = fvalue_get_sinteger(fi->value);
10788 else
10789 value = fvalue_get_uinteger(fi->value);
10790
10791 unshifted_value = value;
10792 if (hfinfo->bitmask) {
10793 unshifted_value <<= hfinfo_bitshift(hfinfo);
10794 }
10795
10796 /* Create the bitfield first */
10797 if (fi->flags & FI_VARINT0x00040000)
10798 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10799 else
10800 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10801 bitfield_byte_length = (unsigned) (p - label_str);
10802
10803 /* Fill in the textual info using stored (shifted) value */
10804 if (hfinfo->display == BASE_CUSTOM) {
10805 char tmp[ITEM_LABEL_LENGTH240];
10806 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10807
10808 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10808, "fmtfunc"))))
;
10809 fmtfunc(tmp, value);
10810 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10811 }
10812 else if (hfinfo->strings) {
10813 const char *val_str = hf_try_val_to_str(value, hfinfo);
10814
10815 out = hfinfo_number_vals_format(hfinfo, buf, value);
10816 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10817 /*
10818 * Unique values only display value_string string
10819 * if there is a match. Otherwise it's just a number
10820 */
10821 if (val_str) {
10822 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10823 } else {
10824 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10825 }
10826 } else {
10827 if (val_str == NULL((void*)0))
10828 val_str = "Unknown";
10829
10830 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10831 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10832 else
10833 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10834 }
10835 }
10836 else {
10837 out = hfinfo_number_value_format(hfinfo, buf, value);
10838
10839 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10840 }
10841}
10842
10843static void
10844fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10845{
10846 char *p;
10847 unsigned bitfield_byte_length;
10848 int bitwidth;
10849 uint64_t value, unshifted_value;
10850 char buf[NUMBER_LABEL_LENGTH80];
10851 const char *out;
10852
10853 const header_field_info *hfinfo = fi->hfinfo;
10854
10855 /* Figure out the bit width */
10856 if (fi->flags & FI_VARINT0x00040000)
10857 bitwidth = fi->length*8;
10858 else
10859 bitwidth = hfinfo_container_bitwidth(hfinfo);
10860
10861 /* Un-shift bits */
10862 if (is_signed)
10863 value = fvalue_get_sinteger64(fi->value);
10864 else
10865 value = fvalue_get_uinteger64(fi->value);
10866
10867 unshifted_value = value;
10868 if (hfinfo->bitmask) {
10869 unshifted_value <<= hfinfo_bitshift(hfinfo);
10870 }
10871
10872 /* Create the bitfield first */
10873 if (fi->flags & FI_VARINT0x00040000)
10874 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10875 else
10876 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10877 bitfield_byte_length = (unsigned) (p - label_str);
10878
10879 /* Fill in the textual info using stored (shifted) value */
10880 if (hfinfo->display == BASE_CUSTOM) {
10881 char tmp[ITEM_LABEL_LENGTH240];
10882 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10883
10884 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10884, "fmtfunc64"
))))
;
10885 fmtfunc64(tmp, value);
10886 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10887 }
10888 else if (hfinfo->strings) {
10889 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10890
10891 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10892 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10893 /*
10894 * Unique values only display value_string string
10895 * if there is a match. Otherwise it's just a number
10896 */
10897 if (val_str) {
10898 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10899 } else {
10900 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10901 }
10902 } else {
10903 if (val_str == NULL((void*)0))
10904 val_str = "Unknown";
10905
10906 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10907 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10908 else
10909 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10910 }
10911 }
10912 else {
10913 out = hfinfo_number_value_format64(hfinfo, buf, value);
10914
10915 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10916 }
10917}
10918
10919static void
10920fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10921{
10922 const header_field_info *hfinfo = fi->hfinfo;
10923 uint32_t value;
10924
10925 char buf[32];
10926 const char *out;
10927
10928 value = fvalue_get_uinteger(fi->value);
10929
10930 /* Fill in the textual info */
10931 if (hfinfo->display == BASE_CUSTOM) {
10932 char tmp[ITEM_LABEL_LENGTH240];
10933 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10934
10935 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10935, "fmtfunc"))))
;
10936 fmtfunc(tmp, value);
10937 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10938 }
10939 else if (hfinfo->strings) {
10940 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10941
10942 out = hfinfo_char_vals_format(hfinfo, buf, value);
10943 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10944 }
10945 else {
10946 out = hfinfo_char_value_format(hfinfo, buf, value);
10947
10948 label_fill(label_str, 0, hfinfo, out, value_pos);
10949 }
10950}
10951
10952static void
10953fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10954{
10955 const header_field_info *hfinfo = fi->hfinfo;
10956 uint32_t value;
10957
10958 char buf[NUMBER_LABEL_LENGTH80];
10959 const char *out;
10960
10961 if (is_signed)
10962 value = fvalue_get_sinteger(fi->value);
10963 else
10964 value = fvalue_get_uinteger(fi->value);
10965
10966 /* Fill in the textual info */
10967 if (hfinfo->display == BASE_CUSTOM) {
10968 char tmp[ITEM_LABEL_LENGTH240];
10969 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10970
10971 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10971, "fmtfunc"))))
;
10972 fmtfunc(tmp, value);
10973 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10974 }
10975 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10976 /*
10977 * It makes no sense to have a value-string table for a
10978 * frame-number field - they're just integers giving
10979 * the ordinal frame number.
10980 */
10981 const char *val_str = hf_try_val_to_str(value, hfinfo);
10982
10983 out = hfinfo_number_vals_format(hfinfo, buf, value);
10984 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10985 /*
10986 * Unique values only display value_string string
10987 * if there is a match. Otherwise it's just a number
10988 */
10989 if (val_str) {
10990 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10991 } else {
10992 label_fill(label_str, 0, hfinfo, out, value_pos);
10993 }
10994 } else {
10995 if (val_str == NULL((void*)0))
10996 val_str = "Unknown";
10997
10998 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10999 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11000 else
11001 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11002 }
11003 }
11004 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
))
) {
11005 char tmp[ITEM_LABEL_LENGTH240];
11006
11007 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11008 display_to_port_type((field_display_e)hfinfo->display), value);
11009 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11010 }
11011 else {
11012 out = hfinfo_number_value_format(hfinfo, buf, value);
11013
11014 label_fill(label_str, 0, hfinfo, out, value_pos);
11015 }
11016}
11017
11018static void
11019fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11020{
11021 const header_field_info *hfinfo = fi->hfinfo;
11022 uint64_t value;
11023
11024 char buf[NUMBER_LABEL_LENGTH80];
11025 const char *out;
11026
11027 if (is_signed)
11028 value = fvalue_get_sinteger64(fi->value);
11029 else
11030 value = fvalue_get_uinteger64(fi->value);
11031
11032 /* Fill in the textual info */
11033 if (hfinfo->display == BASE_CUSTOM) {
11034 char tmp[ITEM_LABEL_LENGTH240];
11035 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11036
11037 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11037, "fmtfunc64"
))))
;
11038 fmtfunc64(tmp, value);
11039 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11040 }
11041 else if (hfinfo->strings) {
11042 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11043
11044 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11045 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11046 /*
11047 * Unique values only display value_string string
11048 * if there is a match. Otherwise it's just a number
11049 */
11050 if (val_str) {
11051 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11052 } else {
11053 label_fill(label_str, 0, hfinfo, out, value_pos);
11054 }
11055 } else {
11056 if (val_str == NULL((void*)0))
11057 val_str = "Unknown";
11058
11059 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11060 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11061 else
11062 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11063 }
11064 }
11065 else {
11066 out = hfinfo_number_value_format64(hfinfo, buf, value);
11067
11068 label_fill(label_str, 0, hfinfo, out, value_pos);
11069 }
11070}
11071
11072static size_t
11073fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11074{
11075 int display;
11076 int n;
11077 double value;
11078
11079 if (label_str_size < 12) {
11080 /* Not enough room to write an entire floating point value. */
11081 return 0;
11082 }
11083
11084 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11085 value = fvalue_get_floating(fi->value);
11086
11087 if (display == BASE_CUSTOM) {
11088 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11089 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11089, "fmtfunc"))))
;
11090 fmtfunc(label_str, value);
11091 return strlen(label_str);
11092 }
11093
11094 switch (display) {
11095 case BASE_NONE:
11096 if (fi->hfinfo->type == FT_FLOAT) {
11097 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11098 } else {
11099 n = (int)strlen(dtoa_g_fmt(label_str, value));
11100 }
11101 break;
11102 case BASE_DEC:
11103 n = snprintf(label_str, label_str_size, "%f", value);
11104 break;
11105 case BASE_HEX:
11106 n = snprintf(label_str, label_str_size, "%a", value);
11107 break;
11108 case BASE_EXP:
11109 n = snprintf(label_str, label_str_size, "%e", value);
11110 break;
11111 default:
11112 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11112
, __func__, "assertion \"not reached\" failed")
;
11113 }
11114 if (n < 0) {
11115 return 0; /* error */
11116 }
11117 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11118 const char *hf_str_val;
11119 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11120 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11121 }
11122 if (n > label_str_size) {
11123 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11123, __func__, "label length too small"); } } while (0)
;
11124 return strlen(label_str);
11125 }
11126
11127 return n;
11128}
11129
11130void
11131fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11132{
11133 char tmp[ITEM_LABEL_LENGTH240];
11134
11135 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11136 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11137}
11138
11139static size_t
11140fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11141{
11142 int display;
11143 size_t pos = 0;
11144 double value;
11145 char* tmp_str;
11146
11147 if (label_str_size < 12) {
11148 /* Not enough room to write an entire floating point value. */
11149 return 0;
11150 }
11151
11152 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11153 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11154 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11155 wmem_free(NULL((void*)0), tmp_str);
11156
11157 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11158 const char *hf_str_val;
11159 fvalue_to_double(fi->value, &value);
11160 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11161 pos = label_concat(label_str, pos, (const uint8_t*)hf_str_val)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hf_str_val
, 0)
;
11162 }
11163 if ((int)pos > label_str_size) {
11164 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11164, __func__, "label length too small"); } } while (0)
;
11165 return strlen(label_str);
11166 }
11167
11168 return pos;
11169}
11170
11171void
11172fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11173{
11174 char tmp[ITEM_LABEL_LENGTH240];
11175
11176 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11177 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11178}
11179
11180int
11181hfinfo_bitshift(const header_field_info *hfinfo)
11182{
11183 return ws_ctz(hfinfo->bitmask);
11184}
11185
11186
11187static int
11188hfinfo_bitoffset(const header_field_info *hfinfo)
11189{
11190 if (!hfinfo->bitmask) {
11191 return 0;
11192 }
11193
11194 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11195 * as the first bit */
11196 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11197}
11198
11199static int
11200hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11201{
11202 if (!hfinfo->bitmask) {
11203 return 0;
11204 }
11205
11206 /* ilog2 = first set bit, ctz = last set bit */
11207 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11208}
11209
11210static int
11211hfinfo_type_bitwidth(enum ftenum type)
11212{
11213 int bitwidth = 0;
11214
11215 switch (type) {
11216 case FT_CHAR:
11217 case FT_UINT8:
11218 case FT_INT8:
11219 bitwidth = 8;
11220 break;
11221 case FT_UINT16:
11222 case FT_INT16:
11223 bitwidth = 16;
11224 break;
11225 case FT_UINT24:
11226 case FT_INT24:
11227 bitwidth = 24;
11228 break;
11229 case FT_UINT32:
11230 case FT_INT32:
11231 bitwidth = 32;
11232 break;
11233 case FT_UINT40:
11234 case FT_INT40:
11235 bitwidth = 40;
11236 break;
11237 case FT_UINT48:
11238 case FT_INT48:
11239 bitwidth = 48;
11240 break;
11241 case FT_UINT56:
11242 case FT_INT56:
11243 bitwidth = 56;
11244 break;
11245 case FT_UINT64:
11246 case FT_INT64:
11247 bitwidth = 64;
11248 break;
11249 default:
11250 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11250))
;
11251 ;
11252 }
11253 return bitwidth;
11254}
11255
11256
11257static int
11258hfinfo_container_bitwidth(const header_field_info *hfinfo)
11259{
11260 if (!hfinfo->bitmask) {
11261 return 0;
11262 }
11263
11264 if (hfinfo->type == FT_BOOLEAN) {
11265 return hfinfo->display; /* hacky? :) */
11266 }
11267
11268 return hfinfo_type_bitwidth(hfinfo->type);
11269}
11270
11271static int
11272hfinfo_hex_digits(const header_field_info *hfinfo)
11273{
11274 int bitwidth;
11275
11276 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11277 * appropriate to determine the number of hex digits for the field.
11278 * So instead, we compute it from the bitmask.
11279 */
11280 if (hfinfo->bitmask != 0) {
11281 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11282 } else {
11283 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11284 }
11285
11286 /* Divide by 4, rounding up, to get number of hex digits. */
11287 return (bitwidth + 3) / 4;
11288}
11289
11290const char *
11291hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11292{
11293 char *ptr = &buf[6];
11294 static const char hex_digits[16] =
11295 { '0', '1', '2', '3', '4', '5', '6', '7',
11296 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11297
11298 *ptr = '\0';
11299 *(--ptr) = '\'';
11300 /* Properly format value */
11301 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11302 /*
11303 * Printable, so just show the character, and, if it needs
11304 * to be escaped, escape it.
11305 */
11306 *(--ptr) = value;
11307 if (value == '\\' || value == '\'')
11308 *(--ptr) = '\\';
11309 } else {
11310 /*
11311 * Non-printable; show it as an escape sequence.
11312 */
11313 switch (value) {
11314
11315 case '\0':
11316 /*
11317 * Show a NUL with only one digit.
11318 */
11319 *(--ptr) = '0';
11320 break;
11321
11322 case '\a':
11323 case '\b':
11324 case '\f':
11325 case '\n':
11326 case '\r':
11327 case '\t':
11328 case '\v':
11329 *(--ptr) = value - '\a' + 'a';
11330 break;
11331
11332 default:
11333 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11334
11335 case BASE_OCT:
11336 *(--ptr) = (value & 0x7) + '0';
11337 value >>= 3;
11338 *(--ptr) = (value & 0x7) + '0';
11339 value >>= 3;
11340 *(--ptr) = (value & 0x7) + '0';
11341 break;
11342
11343 case BASE_HEX:
11344 *(--ptr) = hex_digits[value & 0x0F];
11345 value >>= 4;
11346 *(--ptr) = hex_digits[value & 0x0F];
11347 *(--ptr) = 'x';
11348 break;
11349
11350 default:
11351 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11352 }
11353 }
11354 *(--ptr) = '\\';
11355 }
11356 *(--ptr) = '\'';
11357 return ptr;
11358}
11359
11360static const char *
11361hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11362{
11363 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11364 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
))
;
11365
11366 *ptr = '\0';
11367 /* Properly format value */
11368 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11369 case BASE_DEC:
11370 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11371
11372 case BASE_DEC_HEX:
11373 *(--ptr) = ')';
11374 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11375 *(--ptr) = '(';
11376 *(--ptr) = ' ';
11377 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11378 return ptr;
11379
11380 case BASE_OCT:
11381 return oct_to_str_back(ptr, value);
11382
11383 case BASE_HEX:
11384 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11385
11386 case BASE_HEX_DEC:
11387 *(--ptr) = ')';
11388 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11389 *(--ptr) = '(';
11390 *(--ptr) = ' ';
11391 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11392 return ptr;
11393
11394 case BASE_PT_UDP:
11395 case BASE_PT_TCP:
11396 case BASE_PT_DCCP:
11397 case BASE_PT_SCTP:
11398 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11399 display_to_port_type((field_display_e)display), value);
11400 return buf;
11401 case BASE_OUI:
11402 {
11403 uint8_t p_oui[3];
11404 const char *manuf_name;
11405
11406 p_oui[0] = value >> 16 & 0xFF;
11407 p_oui[1] = value >> 8 & 0xFF;
11408 p_oui[2] = value & 0xFF;
11409
11410 /* Attempt an OUI lookup. */
11411 manuf_name = uint_get_manuf_name_if_known(value);
11412 if (manuf_name == NULL((void*)0)) {
11413 /* Could not find an OUI. */
11414 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11415 }
11416 else {
11417 /* Found an address string. */
11418 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11419 }
11420 return buf;
11421 }
11422
11423 default:
11424 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11425 }
11426 return ptr;
11427}
11428
11429static const char *
11430hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11431{
11432 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11433 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
))
;
11434
11435 *ptr = '\0';
11436 /* Properly format value */
11437 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11438 case BASE_DEC:
11439 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11440
11441 case BASE_DEC_HEX:
11442 *(--ptr) = ')';
11443 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11444 *(--ptr) = '(';
11445 *(--ptr) = ' ';
11446 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11447 return ptr;
11448
11449 case BASE_OCT:
11450 return oct64_to_str_back(ptr, value);
11451
11452 case BASE_HEX:
11453 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11454
11455 case BASE_HEX_DEC:
11456 *(--ptr) = ')';
11457 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11458 *(--ptr) = '(';
11459 *(--ptr) = ' ';
11460 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11461 return ptr;
11462
11463 default:
11464 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11465 }
11466
11467 return ptr;
11468}
11469
11470static const char *
11471hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11472{
11473 int display = hfinfo->display;
11474
11475 if (hfinfo->type == FT_FRAMENUM) {
11476 /*
11477 * Frame numbers are always displayed in decimal.
11478 */
11479 display = BASE_DEC;
11480 }
11481
11482 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11483}
11484
11485static const char *
11486hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11487{
11488 int display = hfinfo->display;
11489
11490 if (hfinfo->type == FT_FRAMENUM) {
11491 /*
11492 * Frame numbers are always displayed in decimal.
11493 */
11494 display = BASE_DEC;
11495 }
11496
11497 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11498}
11499
11500static const char *
11501hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11502{
11503 /* Get the underlying BASE_ value */
11504 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11505
11506 return hfinfo_char_value_format_display(display, buf, value);
11507}
11508
11509static const char *
11510hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11511{
11512 /* Get the underlying BASE_ value */
11513 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11514
11515 if (hfinfo->type == FT_FRAMENUM) {
11516 /*
11517 * Frame numbers are always displayed in decimal.
11518 */
11519 display = BASE_DEC;
11520 }
11521
11522 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11523 display = BASE_DEC;
11524 } else if (display == BASE_OUI) {
11525 display = BASE_HEX;
11526 }
11527
11528 switch (display) {
11529 case BASE_NONE:
11530 /* case BASE_DEC: */
11531 case BASE_DEC_HEX:
11532 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11533 case BASE_CUSTOM:
11534 display = BASE_DEC;
11535 break;
11536
11537 /* case BASE_HEX: */
11538 case BASE_HEX_DEC:
11539 display = BASE_HEX;
11540 break;
11541 }
11542
11543 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11544}
11545
11546static const char *
11547hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11548{
11549 /* Get the underlying BASE_ value */
11550 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11551
11552 if (hfinfo->type == FT_FRAMENUM) {
11553 /*
11554 * Frame numbers are always displayed in decimal.
11555 */
11556 display = BASE_DEC;
11557 }
11558
11559 switch (display) {
11560 case BASE_NONE:
11561 /* case BASE_DEC: */
11562 case BASE_DEC_HEX:
11563 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11564 case BASE_CUSTOM:
11565 display = BASE_DEC;
11566 break;
11567
11568 /* case BASE_HEX: */
11569 case BASE_HEX_DEC:
11570 display = BASE_HEX;
11571 break;
11572 }
11573
11574 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11575}
11576
11577static const char *
11578hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11579{
11580 /* Get the underlying BASE_ value */
11581 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11582
11583 return hfinfo_char_value_format_display(display, buf, value);
11584}
11585
11586static const char *
11587hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11588{
11589 /* Get the underlying BASE_ value */
11590 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11591
11592 if (display == BASE_NONE)
11593 return NULL((void*)0);
11594
11595 if (display == BASE_DEC_HEX)
11596 display = BASE_DEC;
11597 if (display == BASE_HEX_DEC)
11598 display = BASE_HEX;
11599
11600 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11601}
11602
11603static const char *
11604hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11605{
11606 /* Get the underlying BASE_ value */
11607 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11608
11609 if (display == BASE_NONE)
11610 return NULL((void*)0);
11611
11612 if (display == BASE_DEC_HEX)
11613 display = BASE_DEC;
11614 if (display == BASE_HEX_DEC)
11615 display = BASE_HEX;
11616
11617 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11618}
11619
11620const char *
11621proto_registrar_get_name(const int n)
11622{
11623 header_field_info *hfinfo;
11624
11625 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", 11625
, __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", 11625
, "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", 11625, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11626 return hfinfo->name;
11627}
11628
11629const char *
11630proto_registrar_get_abbrev(const int n)
11631{
11632 header_field_info *hfinfo;
11633
11634 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", 11634
, __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", 11634
, "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", 11634, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11635 return hfinfo->abbrev;
11636}
11637
11638enum ftenum
11639proto_registrar_get_ftype(const int n)
11640{
11641 header_field_info *hfinfo;
11642
11643 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", 11643
, __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", 11643
, "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", 11643, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11644 return hfinfo->type;
11645}
11646
11647int
11648proto_registrar_get_parent(const int n)
11649{
11650 header_field_info *hfinfo;
11651
11652 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", 11652
, __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", 11652
, "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", 11652, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11653 return hfinfo->parent;
11654}
11655
11656bool_Bool
11657proto_registrar_is_protocol(const int n)
11658{
11659 header_field_info *hfinfo;
11660
11661 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", 11661
, __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", 11661
, "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", 11661, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11662 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11663}
11664
11665/* Returns length of field in packet (not necessarily the length
11666 * in our internal representation, as in the case of IPv4).
11667 * 0 means undeterminable at time of registration
11668 * -1 means the field is not registered. */
11669int
11670proto_registrar_get_length(const int n)
11671{
11672 header_field_info *hfinfo;
11673
11674 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", 11674
, __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", 11674
, "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", 11674, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11675 return ftype_wire_size(hfinfo->type);
11676}
11677
11678size_t
11679proto_registrar_get_count(struct proto_registrar_stats *stats)
11680{
11681 header_field_info *hfinfo;
11682
11683 // Index zero is not used. We have to skip it.
11684 size_t total_count = gpa_hfinfo.len - 1;
11685 if (stats == NULL((void*)0)) {
11686 return total_count;
11687 }
11688 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11689 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11690 stats->deregistered_count++;
11691 continue; /* This is a deregistered protocol or header field */
11692 }
11693
11694 PROTO_REGISTRAR_GET_NTH(id, hfinfo)if((id == 0 || (unsigned)id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11694
, __func__, "Unregistered hf! index=%d", id); ((void) ((id >
0 && (unsigned)id < gpa_hfinfo.len) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11694, "id > 0 && (unsigned)id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[id] != ((
void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11694, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11695
11696 if (proto_registrar_is_protocol(id))
11697 stats->protocol_count++;
11698
11699 if (hfinfo->same_name_prev_id != -1)
11700 stats->same_name_count++;
11701 }
11702
11703 return total_count;
11704}
11705
11706/* Looks for a protocol or a field in a proto_tree. Returns true if
11707 * it exists anywhere, or false if it exists nowhere. */
11708bool_Bool
11709proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11710{
11711 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11712
11713 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11714 return true1;
11715 }
11716 else {
11717 return false0;
11718 }
11719}
11720
11721/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11722 * This only works if the hfindex was "primed" before the dissection
11723 * took place, as we just pass back the already-created GPtrArray*.
11724 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11725 * handles that. */
11726GPtrArray *
11727proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11728{
11729 if (!tree)
11730 return NULL((void*)0);
11731
11732 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11733 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11734 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11735 else
11736 return NULL((void*)0);
11737}
11738
11739bool_Bool
11740proto_tracking_interesting_fields(const proto_tree *tree)
11741{
11742 GHashTable *interesting_hfids;
11743
11744 if (!tree)
11745 return false0;
11746
11747 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11748
11749 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11750}
11751
11752/* Helper struct for proto_find_info() and proto_all_finfos() */
11753typedef struct {
11754 GPtrArray *array;
11755 int id;
11756} ffdata_t;
11757
11758/* Helper function for proto_find_info() */
11759static bool_Bool
11760find_finfo(proto_node *node, void * data)
11761{
11762 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11763 if (fi && fi->hfinfo) {
11764 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11765 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11766 }
11767 }
11768
11769 /* Don't stop traversing. */
11770 return false0;
11771}
11772
11773/* Helper function for proto_find_first_info() */
11774static bool_Bool
11775find_first_finfo(proto_node *node, void *data)
11776{
11777 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11778 if (fi && fi->hfinfo) {
11779 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11780 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11781
11782 /* Stop traversing. */
11783 return true1;
11784 }
11785 }
11786
11787 /* Continue traversing. */
11788 return false0;
11789}
11790
11791/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11792* This works on any proto_tree, primed or unprimed, but actually searches
11793* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11794* The caller does need to free the returned GPtrArray with
11795* g_ptr_array_free(<array>, true).
11796*/
11797GPtrArray *
11798proto_find_finfo(proto_tree *tree, const int id)
11799{
11800 ffdata_t ffdata;
11801
11802 ffdata.array = g_ptr_array_new();
11803 ffdata.id = id;
11804
11805 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11806
11807 return ffdata.array;
11808}
11809
11810/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11811* This works on any proto_tree, primed or unprimed, but actually searches
11812* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11813* The caller does need to free the returned GPtrArray with
11814* g_ptr_array_free(<array>, true).
11815*/
11816GPtrArray *
11817proto_find_first_finfo(proto_tree *tree, const int id)
11818{
11819 ffdata_t ffdata;
11820
11821 ffdata.array = g_ptr_array_new();
11822 ffdata.id = id;
11823
11824 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11825
11826 return ffdata.array;
11827}
11828
11829/* Helper function for proto_all_finfos() */
11830static bool_Bool
11831every_finfo(proto_node *node, void * data)
11832{
11833 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11834 if (fi && fi->hfinfo) {
11835 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11836 }
11837
11838 /* Don't stop traversing. */
11839 return false0;
11840}
11841
11842/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11843 * The caller does need to free the returned GPtrArray with
11844 * g_ptr_array_free(<array>, true).
11845 */
11846GPtrArray *
11847proto_all_finfos(proto_tree *tree)
11848{
11849 ffdata_t ffdata;
11850
11851 /* Pre allocate enough space to hold all fields in most cases */
11852 ffdata.array = g_ptr_array_sized_new(512);
11853 ffdata.id = 0;
11854
11855 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11856
11857 return ffdata.array;
11858}
11859
11860
11861typedef struct {
11862 unsigned offset;
11863 field_info *finfo;
11864 tvbuff_t *tvb;
11865} offset_search_t;
11866
11867static bool_Bool
11868check_for_offset(proto_node *node, void * data)
11869{
11870 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11871 offset_search_t *offsearch = (offset_search_t *)data;
11872
11873 /* !fi == the top most container node which holds nothing */
11874 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11875 if (offsearch->offset >= (unsigned) fi->start &&
11876 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11877
11878 offsearch->finfo = fi;
11879 return false0; /* keep traversing */
11880 }
11881 }
11882 return false0; /* keep traversing */
11883}
11884
11885/* Search a proto_tree backwards (from leaves to root) looking for the field
11886 * whose start/length occupies 'offset' */
11887/* XXX - I couldn't find an easy way to search backwards, so I search
11888 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11889 * the one I want to return to the user. This algorithm is inefficient
11890 * and could be re-done, but I'd have to handle all the children and
11891 * siblings of each node myself. When I have more time I'll do that.
11892 * (yeah right) */
11893field_info *
11894proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11895{
11896 offset_search_t offsearch;
11897
11898 offsearch.offset = offset;
11899 offsearch.finfo = NULL((void*)0);
11900 offsearch.tvb = tvb;
11901
11902 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11903
11904 return offsearch.finfo;
11905}
11906
11907typedef struct {
11908 unsigned length;
11909 char *buf;
11910} decoded_data_t;
11911
11912static bool_Bool
11913check_for_undecoded(proto_node *node, void * data)
11914{
11915 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11916 decoded_data_t* decoded = (decoded_data_t*)data;
11917 unsigned i;
11918 unsigned byte;
11919 unsigned bit;
11920
11921 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11922 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11923 byte = i / 8;
11924 bit = i % 8;
11925 decoded->buf[byte] |= (1 << bit);
11926 }
11927 }
11928
11929 return false0;
11930}
11931
11932char*
11933proto_find_undecoded_data(proto_tree *tree, unsigned length)
11934{
11935 decoded_data_t decoded;
11936 decoded.length = length;
11937 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11938
11939 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11940 return decoded.buf;
11941}
11942
11943/* Dumps the protocols in the registration database to stdout. An independent
11944 * program can take this output and format it into nice tables or HTML or
11945 * whatever.
11946 *
11947 * There is one record per line. The fields are tab-delimited.
11948 *
11949 * Field 1 = protocol name
11950 * Field 2 = protocol short name
11951 * Field 3 = protocol filter name
11952 * Field 4 = protocol enabled
11953 * Field 5 = protocol enabled by default
11954 * Field 6 = protocol can toggle
11955 */
11956void
11957proto_registrar_dump_protocols(void)
11958{
11959 protocol_t *protocol;
11960 int i;
11961 void *cookie = NULL((void*)0);
11962
11963
11964 i = proto_get_first_protocol(&cookie);
11965 while (i != -1) {
11966 protocol = find_protocol_by_id(i);
11967 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11968 protocol->name,
11969 protocol->short_name,
11970 protocol->filter_name,
11971 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11972 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11973 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11974 i = proto_get_next_protocol(&cookie);
11975 }
11976}
11977
11978/* Dumps the value_strings, extended value string headers, range_strings
11979 * or true/false strings for fields that have them.
11980 * There is one record per line. Fields are tab-delimited.
11981 * There are four types of records: Value String, Extended Value String Header,
11982 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11983 * the type of record.
11984 *
11985 * Note that a record will be generated only if the value_string,... is referenced
11986 * in a registered hfinfo entry.
11987 *
11988 *
11989 * Value Strings
11990 * -------------
11991 * Field 1 = 'V'
11992 * Field 2 = Field abbreviation to which this value string corresponds
11993 * Field 3 = Integer value
11994 * Field 4 = String
11995 *
11996 * Extended Value String Headers
11997 * -----------------------------
11998 * Field 1 = 'E'
11999 * Field 2 = Field abbreviation to which this extended value string header corresponds
12000 * Field 3 = Extended Value String "Name"
12001 * Field 4 = Number of entries in the associated value_string array
12002 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12003 *
12004 * Range Strings
12005 * -------------
12006 * Field 1 = 'R'
12007 * Field 2 = Field abbreviation to which this range string corresponds
12008 * Field 3 = Integer value: lower bound
12009 * Field 4 = Integer value: upper bound
12010 * Field 5 = String
12011 *
12012 * True/False Strings
12013 * ------------------
12014 * Field 1 = 'T'
12015 * Field 2 = Field abbreviation to which this true/false string corresponds
12016 * Field 3 = True String
12017 * Field 4 = False String
12018 */
12019void
12020proto_registrar_dump_values(void)
12021{
12022 header_field_info *hfinfo;
12023 int i, len, vi;
12024 const value_string *vals;
12025 const val64_string *vals64;
12026 const range_string *range;
12027 const true_false_string *tfs;
12028 const unit_name_string *units;
12029
12030 len = gpa_hfinfo.len;
12031 for (i = 1; i < len ; i++) {
12032 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12033 continue; /* This is a deregistered protocol or field */
12034
12035 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", 12035
, __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", 12035
, "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", 12035, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12036
12037 if (hfinfo->id == hf_text_only) {
12038 continue;
12039 }
12040
12041 /* ignore protocols */
12042 if (proto_registrar_is_protocol(i)) {
12043 continue;
12044 }
12045 /* process header fields */
12046#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12047 /*
12048 * If this field isn't at the head of the list of
12049 * fields with this name, skip this field - all
12050 * fields with the same name are really just versions
12051 * of the same field stored in different bits, and
12052 * should have the same type/radix/value list, and
12053 * just differ in their bit masks. (If a field isn't
12054 * a bitfield, but can be, say, 1 or 2 bytes long,
12055 * it can just be made FT_UINT16, meaning the
12056 * *maximum* length is 2 bytes, and be used
12057 * for all lengths.)
12058 */
12059 if (hfinfo->same_name_prev_id != -1)
12060 continue;
12061#endif
12062 vals = NULL((void*)0);
12063 vals64 = NULL((void*)0);
12064 range = NULL((void*)0);
12065 tfs = NULL((void*)0);
12066 units = NULL((void*)0);
12067
12068 if (hfinfo->strings != NULL((void*)0)) {
12069 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12070 (hfinfo->type == FT_CHAR ||
12071 hfinfo->type == FT_UINT8 ||
12072 hfinfo->type == FT_UINT16 ||
12073 hfinfo->type == FT_UINT24 ||
12074 hfinfo->type == FT_UINT32 ||
12075 hfinfo->type == FT_UINT40 ||
12076 hfinfo->type == FT_UINT48 ||
12077 hfinfo->type == FT_UINT56 ||
12078 hfinfo->type == FT_UINT64 ||
12079 hfinfo->type == FT_INT8 ||
12080 hfinfo->type == FT_INT16 ||
12081 hfinfo->type == FT_INT24 ||
12082 hfinfo->type == FT_INT32 ||
12083 hfinfo->type == FT_INT40 ||
12084 hfinfo->type == FT_INT48 ||
12085 hfinfo->type == FT_INT56 ||
12086 hfinfo->type == FT_INT64 ||
12087 hfinfo->type == FT_FLOAT ||
12088 hfinfo->type == FT_DOUBLE)) {
12089
12090 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12091 range = (const range_string *)hfinfo->strings;
12092 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12093 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12094 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12095 } else {
12096 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12097 }
12098 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12099 vals64 = (const val64_string *)hfinfo->strings;
12100 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12101 units = (const unit_name_string *)hfinfo->strings;
12102 } else {
12103 vals = (const value_string *)hfinfo->strings;
12104 }
12105 }
12106 else if (hfinfo->type == FT_BOOLEAN) {
12107 tfs = (const struct true_false_string *)hfinfo->strings;
12108 }
12109 }
12110
12111 /* Print value strings? */
12112 if (vals) {
12113 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12114 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12115 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12116 if (!val64_string_ext_validate(vse_p)) {
12117 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12117, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12118 continue;
12119 }
12120 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12121 printf("E\t%s\t%u\t%s\t%s\n",
12122 hfinfo->abbrev,
12123 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12124 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12125 val64_string_ext_match_type_str(vse_p));
12126 } else {
12127 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12128 if (!value_string_ext_validate(vse_p)) {
12129 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12129, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12130 continue;
12131 }
12132 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12133 printf("E\t%s\t%u\t%s\t%s\n",
12134 hfinfo->abbrev,
12135 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12136 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12137 value_string_ext_match_type_str(vse_p));
12138 }
12139 }
12140 vi = 0;
12141 while (vals[vi].strptr) {
12142 /* Print in the proper base */
12143 if (hfinfo->type == FT_CHAR) {
12144 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12145 printf("V\t%s\t'%c'\t%s\n",
12146 hfinfo->abbrev,
12147 vals[vi].value,
12148 vals[vi].strptr);
12149 } else {
12150 if (hfinfo->display == BASE_HEX) {
12151 printf("V\t%s\t'\\x%02x'\t%s\n",
12152 hfinfo->abbrev,
12153 vals[vi].value,
12154 vals[vi].strptr);
12155 }
12156 else {
12157 printf("V\t%s\t'\\%03o'\t%s\n",
12158 hfinfo->abbrev,
12159 vals[vi].value,
12160 vals[vi].strptr);
12161 }
12162 }
12163 } else {
12164 if (hfinfo->display == BASE_HEX) {
12165 printf("V\t%s\t0x%x\t%s\n",
12166 hfinfo->abbrev,
12167 vals[vi].value,
12168 vals[vi].strptr);
12169 }
12170 else {
12171 printf("V\t%s\t%u\t%s\n",
12172 hfinfo->abbrev,
12173 vals[vi].value,
12174 vals[vi].strptr);
12175 }
12176 }
12177 vi++;
12178 }
12179 }
12180 else if (vals64) {
12181 vi = 0;
12182 while (vals64[vi].strptr) {
12183 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12184 hfinfo->abbrev,
12185 vals64[vi].value,
12186 vals64[vi].strptr);
12187 vi++;
12188 }
12189 }
12190
12191 /* print range strings? */
12192 else if (range) {
12193 vi = 0;
12194 while (range[vi].strptr) {
12195 /* Print in the proper base */
12196 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12197 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12198 hfinfo->abbrev,
12199 range[vi].value_min,
12200 range[vi].value_max,
12201 range[vi].strptr);
12202 }
12203 else {
12204 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12205 hfinfo->abbrev,
12206 range[vi].value_min,
12207 range[vi].value_max,
12208 range[vi].strptr);
12209 }
12210 vi++;
12211 }
12212 }
12213
12214 /* Print true/false strings? */
12215 else if (tfs) {
12216 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12217 tfs->true_string, tfs->false_string);
12218 }
12219 /* Print unit strings? */
12220 else if (units) {
12221 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12222 units->singular, units->plural ? units->plural : "(no plural)");
12223 }
12224 }
12225}
12226
12227/* Prints the number of registered fields.
12228 * Useful for determining an appropriate value for
12229 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12230 *
12231 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12232 * the number of fields, true otherwise.
12233 */
12234bool_Bool
12235proto_registrar_dump_fieldcount(void)
12236{
12237 struct proto_registrar_stats stats = {0, 0, 0};
12238 size_t total_count = proto_registrar_get_count(&stats);
12239
12240 printf("There are %zu header fields registered, of which:\n"
12241 "\t%zu are deregistered\n"
12242 "\t%zu are protocols\n"
12243 "\t%zu have the same name as another field\n\n",
12244 total_count, stats.deregistered_count, stats.protocol_count,
12245 stats.same_name_count);
12246
12247 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12248 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12249 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12250 "\n");
12251
12252 printf("The header field table consumes %u KiB of memory.\n",
12253 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12254 printf("The fields themselves consume %u KiB of memory.\n",
12255 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12256
12257 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12258}
12259
12260static void
12261elastic_add_base_mapping(json_dumper *dumper)
12262{
12263 json_dumper_set_member_name(dumper, "index_patterns");
12264 json_dumper_begin_array(dumper);
12265 // The index names from write_json_index() in print.c
12266 json_dumper_value_string(dumper, "packets-*");
12267 json_dumper_end_array(dumper);
12268
12269 json_dumper_set_member_name(dumper, "settings");
12270 json_dumper_begin_object(dumper);
12271 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12272 json_dumper_value_anyf(dumper, "%d", 1000000);
12273 json_dumper_end_object(dumper);
12274}
12275
12276static char*
12277ws_type_to_elastic(unsigned type)
12278{
12279 switch(type) {
12280 case FT_INT8:
12281 return "byte";
12282 case FT_UINT8:
12283 case FT_INT16:
12284 return "short";
12285 case FT_UINT16:
12286 case FT_INT32:
12287 case FT_UINT24:
12288 case FT_INT24:
12289 return "integer";
12290 case FT_FRAMENUM:
12291 case FT_UINT32:
12292 case FT_UINT40:
12293 case FT_UINT48:
12294 case FT_UINT56:
12295 case FT_INT40:
12296 case FT_INT48:
12297 case FT_INT56:
12298 case FT_INT64:
12299 return "long";
12300 case FT_UINT64:
12301 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12302 case FT_FLOAT:
12303 return "float";
12304 case FT_DOUBLE:
12305 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12306 return "double";
12307 case FT_IPv6:
12308 case FT_IPv4:
12309 return "ip";
12310 case FT_ABSOLUTE_TIME:
12311 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12312 case FT_BOOLEAN:
12313 return "boolean";
12314 default:
12315 return NULL((void*)0);
12316 }
12317}
12318
12319static char*
12320dot_to_underscore(char* str)
12321{
12322 unsigned i;
12323 for (i = 0; i < strlen(str); i++) {
12324 if (str[i] == '.')
12325 str[i] = '_';
12326 }
12327 return str;
12328}
12329
12330/* Dumps a mapping file for ElasticSearch
12331 * This is the v1 (legacy) _template API.
12332 * At some point it may need to be updated with the composable templates
12333 * introduced in Elasticsearch 7.8 (_index_template)
12334 */
12335void
12336proto_registrar_dump_elastic(const char* filter)
12337{
12338 header_field_info *hfinfo;
12339 header_field_info *parent_hfinfo;
12340 unsigned i;
12341 bool_Bool open_object = true1;
12342 const char* prev_proto = NULL((void*)0);
12343 char* str;
12344 char** protos = NULL((void*)0);
12345 char* proto;
12346 bool_Bool found;
12347 unsigned j;
12348 char* type;
12349 char* prev_item = NULL((void*)0);
12350
12351 /* We have filtering protocols. Extract them. */
12352 if (filter) {
12353 protos = g_strsplit(filter, ",", -1);
12354 }
12355
12356 /*
12357 * To help tracking down the json tree, objects have been appended with a comment:
12358 * n.label -> where n is the indentation level and label the name of the object
12359 */
12360
12361 json_dumper dumper = {
12362 .output_file = stdoutstdout,
12363 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12364 };
12365 json_dumper_begin_object(&dumper); // 1.root
12366 elastic_add_base_mapping(&dumper);
12367
12368 json_dumper_set_member_name(&dumper, "mappings");
12369 json_dumper_begin_object(&dumper); // 2.mappings
12370
12371 json_dumper_set_member_name(&dumper, "properties");
12372 json_dumper_begin_object(&dumper); // 3.properties
12373 json_dumper_set_member_name(&dumper, "timestamp");
12374 json_dumper_begin_object(&dumper); // 4.timestamp
12375 json_dumper_set_member_name(&dumper, "type");
12376 json_dumper_value_string(&dumper, "date");
12377 json_dumper_end_object(&dumper); // 4.timestamp
12378
12379 json_dumper_set_member_name(&dumper, "layers");
12380 json_dumper_begin_object(&dumper); // 4.layers
12381 json_dumper_set_member_name(&dumper, "properties");
12382 json_dumper_begin_object(&dumper); // 5.properties
12383
12384 for (i = 1; i < gpa_hfinfo.len; i++) {
12385 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12386 continue; /* This is a deregistered protocol or header field */
12387
12388 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", 12388
, __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", 12388
, "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", 12388, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12389
12390 /*
12391 * Skip the pseudo-field for "proto_tree_add_text()" since
12392 * we don't want it in the list of filterable protocols.
12393 */
12394 if (hfinfo->id == hf_text_only)
12395 continue;
12396
12397 if (!proto_registrar_is_protocol(i)) {
12398 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", 12398
, __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", 12398
, "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", 12398
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12399
12400 /*
12401 * Skip the field if filter protocols have been set and this one's
12402 * parent is not listed.
12403 */
12404 if (protos) {
12405 found = false0;
12406 j = 0;
12407 proto = protos[0];
12408 while(proto) {
12409 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12410 found = true1;
12411 break;
12412 }
12413 j++;
12414 proto = protos[j];
12415 }
12416 if (!found)
12417 continue;
12418 }
12419
12420 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12421 json_dumper_end_object(&dumper); // 7.properties
12422 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12423 open_object = true1;
12424 }
12425
12426 prev_proto = parent_hfinfo->abbrev;
12427
12428 if (open_object) {
12429 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12430 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12431 json_dumper_set_member_name(&dumper, "properties");
12432 json_dumper_begin_object(&dumper); // 7.properties
12433 open_object = false0;
12434 }
12435 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12436 type = ws_type_to_elastic(hfinfo->type);
12437 /* when type is NULL, we have the default mapping: string */
12438 if (type) {
12439 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12440 dot_to_underscore(str);
12441 if (g_strcmp0(prev_item, str)) {
12442 json_dumper_set_member_name(&dumper, str);
12443 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12444 json_dumper_set_member_name(&dumper, "type");
12445 json_dumper_value_string(&dumper, type);
12446 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12447 }
12448 g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized
(prev_item, __builtin_object_size ((prev_item), 0)) : (g_free
) (prev_item)
;
12449 prev_item = str;
12450 }
12451 }
12452 }
12453 g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized
(prev_item, __builtin_object_size ((prev_item), 0)) : (g_free
) (prev_item)
;
12454
12455 if (prev_proto) {
12456 json_dumper_end_object(&dumper); // 7.properties
12457 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12458 }
12459
12460 json_dumper_end_object(&dumper); // 5.properties
12461 json_dumper_end_object(&dumper); // 4.layers
12462 json_dumper_end_object(&dumper); // 3.properties
12463 json_dumper_end_object(&dumper); // 2.mappings
12464 json_dumper_end_object(&dumper); // 1.root
12465 bool_Bool ret = json_dumper_finish(&dumper);
12466 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12466, "ret"))))
;
12467
12468 g_strfreev(protos);
12469}
12470
12471/* Dumps the contents of the registration database to stdout. An independent
12472 * program can take this output and format it into nice tables or HTML or
12473 * whatever.
12474 *
12475 * There is one record per line. Each record is either a protocol or a header
12476 * field, differentiated by the first field. The fields are tab-delimited.
12477 *
12478 * Protocols
12479 * ---------
12480 * Field 1 = 'P'
12481 * Field 2 = descriptive protocol name
12482 * Field 3 = protocol abbreviation
12483 *
12484 * Header Fields
12485 * -------------
12486 * Field 1 = 'F'
12487 * Field 2 = descriptive field name
12488 * Field 3 = field abbreviation
12489 * Field 4 = type ( textual representation of the ftenum type )
12490 * Field 5 = parent protocol abbreviation
12491 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12492 * Field 7 = bitmask: format: hex: 0x....
12493 * Field 8 = blurb describing field
12494 */
12495void
12496proto_registrar_dump_fields(void)
12497{
12498 header_field_info *hfinfo, *parent_hfinfo;
12499 int i, len;
12500 const char *enum_name;
12501 const char *base_name;
12502 const char *blurb;
12503 char width[5];
12504
12505 len = gpa_hfinfo.len;
12506 for (i = 1; i < len ; i++) {
12507 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12508 continue; /* This is a deregistered protocol or header field */
12509
12510 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", 12510
, __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", 12510
, "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", 12510, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12511
12512 /*
12513 * Skip the pseudo-field for "proto_tree_add_text()" since
12514 * we don't want it in the list of filterable fields.
12515 */
12516 if (hfinfo->id == hf_text_only)
12517 continue;
12518
12519 /* format for protocols */
12520 if (proto_registrar_is_protocol(i)) {
12521 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12522 }
12523 /* format for header fields */
12524 else {
12525 /*
12526 * If this field isn't at the head of the list of
12527 * fields with this name, skip this field - all
12528 * fields with the same name are really just versions
12529 * of the same field stored in different bits, and
12530 * should have the same type/radix/value list, and
12531 * just differ in their bit masks. (If a field isn't
12532 * a bitfield, but can be, say, 1 or 2 bytes long,
12533 * it can just be made FT_UINT16, meaning the
12534 * *maximum* length is 2 bytes, and be used
12535 * for all lengths.)
12536 */
12537 if (hfinfo->same_name_prev_id != -1)
12538 continue;
12539
12540 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", 12540
, __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", 12540
, "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", 12540
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12541
12542 enum_name = ftype_name(hfinfo->type);
12543 base_name = "";
12544
12545 if (hfinfo->type == FT_CHAR ||
12546 hfinfo->type == FT_UINT8 ||
12547 hfinfo->type == FT_UINT16 ||
12548 hfinfo->type == FT_UINT24 ||
12549 hfinfo->type == FT_UINT32 ||
12550 hfinfo->type == FT_UINT40 ||
12551 hfinfo->type == FT_UINT48 ||
12552 hfinfo->type == FT_UINT56 ||
12553 hfinfo->type == FT_UINT64 ||
12554 hfinfo->type == FT_INT8 ||
12555 hfinfo->type == FT_INT16 ||
12556 hfinfo->type == FT_INT24 ||
12557 hfinfo->type == FT_INT32 ||
12558 hfinfo->type == FT_INT40 ||
12559 hfinfo->type == FT_INT48 ||
12560 hfinfo->type == FT_INT56 ||
12561 hfinfo->type == FT_INT64) {
12562
12563 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12564 case BASE_NONE:
12565 case BASE_DEC:
12566 case BASE_HEX:
12567 case BASE_OCT:
12568 case BASE_DEC_HEX:
12569 case BASE_HEX_DEC:
12570 case BASE_CUSTOM:
12571 case BASE_PT_UDP:
12572 case BASE_PT_TCP:
12573 case BASE_PT_DCCP:
12574 case BASE_PT_SCTP:
12575 case BASE_OUI:
12576 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12577 break;
12578 default:
12579 base_name = "????";
12580 break;
12581 }
12582 } else if (hfinfo->type == FT_BOOLEAN) {
12583 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12584 snprintf(width, sizeof(width), "%d", hfinfo->display);
12585 base_name = width;
12586 }
12587
12588 blurb = hfinfo->blurb;
12589 if (blurb == NULL((void*)0))
12590 blurb = "";
12591 else if (strlen(blurb) == 0)
12592 blurb = "\"\"";
12593
12594 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12595 hfinfo->name, hfinfo->abbrev, enum_name,
12596 parent_hfinfo->abbrev, base_name,
12597 hfinfo->bitmask, blurb);
12598 }
12599 }
12600}
12601
12602/* Dumps all abbreviated field and protocol completions of the given string to
12603 * stdout. An independent program may use this for command-line tab completion
12604 * of fields.
12605 */
12606bool_Bool
12607proto_registrar_dump_field_completions(const char *prefix)
12608{
12609 header_field_info *hfinfo;
12610 int i, len;
12611 size_t prefix_len;
12612 bool_Bool matched = false0;
12613
12614 prefix_len = strlen(prefix);
12615 len = gpa_hfinfo.len;
12616 for (i = 1; i < len ; i++) {
12617 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12618 continue; /* This is a deregistered protocol or header field */
12619
12620 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", 12620
, __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", 12620
, "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", 12620, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12621
12622 /*
12623 * Skip the pseudo-field for "proto_tree_add_text()" since
12624 * we don't want it in the list of filterable fields.
12625 */
12626 if (hfinfo->id == hf_text_only)
12627 continue;
12628
12629 /* format for protocols */
12630 if (proto_registrar_is_protocol(i)) {
12631 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12632 matched = true1;
12633 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12634 }
12635 }
12636 /* format for header fields */
12637 else {
12638 /*
12639 * If this field isn't at the head of the list of
12640 * fields with this name, skip this field - all
12641 * fields with the same name are really just versions
12642 * of the same field stored in different bits, and
12643 * should have the same type/radix/value list, and
12644 * just differ in their bit masks. (If a field isn't
12645 * a bitfield, but can be, say, 1 or 2 bytes long,
12646 * it can just be made FT_UINT16, meaning the
12647 * *maximum* length is 2 bytes, and be used
12648 * for all lengths.)
12649 */
12650 if (hfinfo->same_name_prev_id != -1)
12651 continue;
12652
12653 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12654 matched = true1;
12655 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12656 }
12657 }
12658 }
12659 return matched;
12660}
12661
12662/* Dumps field types and descriptive names to stdout. An independent
12663 * program can take this output and format it into nice tables or HTML or
12664 * whatever.
12665 *
12666 * There is one record per line. The fields are tab-delimited.
12667 *
12668 * Field 1 = field type name, e.g. FT_UINT8
12669 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12670 */
12671void
12672proto_registrar_dump_ftypes(void)
12673{
12674 int fte;
12675
12676 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12677 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12678 }
12679}
12680
12681/* This function indicates whether it's possible to construct a
12682 * "match selected" display filter string for the specified field,
12683 * returns an indication of whether it's possible, and, if it's
12684 * possible and "filter" is non-null, constructs the filter and
12685 * sets "*filter" to point to it.
12686 * You do not need to [g_]free() this string since it will be automatically
12687 * freed once the next packet is dissected.
12688 */
12689static bool_Bool
12690construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12691 char **filter)
12692{
12693 const header_field_info *hfinfo;
12694 int start, length, length_remaining;
12695
12696 if (!finfo)
12697 return false0;
12698
12699 hfinfo = finfo->hfinfo;
12700 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12700, "hfinfo"))))
;
12701
12702 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12703 * then "the numeric value ... is not used when preparing
12704 * filters for the field in question." If it's any other
12705 * base, we'll generate the filter normally (which will
12706 * be numeric, even though the human-readable string does
12707 * work for filtering.)
12708 *
12709 * XXX - It might be nice to use fvalue_to_string_repr() in
12710 * "proto_item_fill_label()" as well, although, there, you'd
12711 * have to deal with the base *and* with resolved values for
12712 * addresses.
12713 *
12714 * Perhaps in addition to taking the repr type (DISPLAY
12715 * or DFILTER) and the display (base), fvalue_to_string_repr()
12716 * should have the the "strings" values in the header_field_info
12717 * structure for the field as a parameter, so it can have
12718 * if the field is Boolean or an enumerated integer type,
12719 * the tables used to generate human-readable values.
12720 */
12721 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12722 const char *str = NULL((void*)0);
12723
12724 switch (hfinfo->type) {
12725
12726 case FT_INT8:
12727 case FT_INT16:
12728 case FT_INT24:
12729 case FT_INT32:
12730 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12731 break;
12732
12733 case FT_CHAR:
12734 case FT_UINT8:
12735 case FT_UINT16:
12736 case FT_UINT24:
12737 case FT_UINT32:
12738 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12739 break;
12740
12741 default:
12742 break;
12743 }
12744
12745 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12746 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12747 return true1;
12748 }
12749 }
12750
12751 switch (hfinfo->type) {
12752
12753 case FT_PROTOCOL:
12754 if (filter != NULL((void*)0))
12755 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12756 break;
12757
12758 case FT_NONE:
12759 /*
12760 * If the length is 0, just match the name of the
12761 * field.
12762 *
12763 * (Also check for negative values, just in case,
12764 * as we'll cast it to an unsigned value later.)
12765 */
12766 length = finfo->length;
12767 if (length == 0) {
12768 if (filter != NULL((void*)0))
12769 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12770 break;
12771 }
12772 if (length < 0)
12773 return false0;
12774
12775 /*
12776 * This doesn't have a value, so we'd match
12777 * on the raw bytes at this address.
12778 *
12779 * Should we be allowed to access to the raw bytes?
12780 * If "edt" is NULL, the answer is "no".
12781 */
12782 if (edt == NULL((void*)0))
12783 return false0;
12784
12785 /*
12786 * Is this field part of the raw frame tvbuff?
12787 * If not, we can't use "frame[N:M]" to match
12788 * it.
12789 *
12790 * XXX - should this be frame-relative, or
12791 * protocol-relative?
12792 *
12793 * XXX - does this fallback for non-registered
12794 * fields even make sense?
12795 */
12796 if (finfo->ds_tvb != edt->tvb)
12797 return false0; /* you lose */
12798
12799 /*
12800 * Don't go past the end of that tvbuff.
12801 */
12802 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12803 if (length > length_remaining)
12804 length = length_remaining;
12805 if (length <= 0)
12806 return false0;
12807
12808 if (filter != NULL((void*)0)) {
12809 start = finfo->start;
12810 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12811 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12812 wmem_free(NULL((void*)0), str);
12813 }
12814 break;
12815
12816 /* By default, use the fvalue's "to_string_repr" method. */
12817 default:
12818 if (filter != NULL((void*)0)) {
12819 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12820 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12821 wmem_free(NULL((void*)0), str);
12822 }
12823 break;
12824 }
12825
12826 return true1;
12827}
12828
12829/*
12830 * Returns true if we can do a "match selected" on the field, false
12831 * otherwise.
12832 */
12833bool_Bool
12834proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12835{
12836 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12837}
12838
12839/* This function attempts to construct a "match selected" display filter
12840 * string for the specified field; if it can do so, it returns a pointer
12841 * to the string, otherwise it returns NULL.
12842 *
12843 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12844 */
12845char *
12846proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12847{
12848 char *filter = NULL((void*)0);
12849
12850 if (!construct_match_selected_string(finfo, edt, &filter))
12851 {
12852 wmem_free(NULL((void*)0), filter);
12853 return NULL((void*)0);
12854 }
12855 return filter;
12856}
12857
12858/* This function is common code for all proto_tree_add_bitmask... functions.
12859 */
12860
12861static bool_Bool
12862proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12863 const unsigned len, const int ett, int * const *fields,
12864 const int flags, bool_Bool first,
12865 bool_Bool use_parent_tree,
12866 proto_tree* tree, uint64_t value)
12867{
12868 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12869 uint64_t bitmask = 0;
12870 uint64_t tmpval;
12871 header_field_info *hf;
12872 uint32_t integer32;
12873 int bit_offset;
12874 int no_of_bits;
12875
12876 if (!*fields)
12877 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"
)
;
12878
12879 if (len > 8)
12880 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12881 /**
12882 * packet-frame.c uses len=0 since the value is taken from the packet
12883 * metadata, not the packet bytes. In that case, assume that all bits
12884 * in the provided value are valid.
12885 */
12886 if (len > 0) {
12887 available_bits >>= (8 - len)*8;
12888 }
12889
12890 if (use_parent_tree == false0)
12891 tree = proto_item_add_subtree(item, ett);
12892
12893 while (*fields) {
12894 uint64_t present_bits;
12895 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", 12895, __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", 12895
, "**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", 12895, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12896 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", 12896
, "hf->bitmask != 0", hf->abbrev))))
;
12897
12898 bitmask |= hf->bitmask;
12899
12900 /* Skip fields that aren't fully present */
12901 present_bits = available_bits & hf->bitmask;
12902 if (present_bits != hf->bitmask) {
12903 fields++;
12904 continue;
12905 }
12906
12907 switch (hf->type) {
12908 case FT_CHAR:
12909 case FT_UINT8:
12910 case FT_UINT16:
12911 case FT_UINT24:
12912 case FT_UINT32:
12913 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12914 break;
12915
12916 case FT_INT8:
12917 case FT_INT16:
12918 case FT_INT24:
12919 case FT_INT32:
12920 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12921 break;
12922
12923 case FT_UINT40:
12924 case FT_UINT48:
12925 case FT_UINT56:
12926 case FT_UINT64:
12927 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12928 break;
12929
12930 case FT_INT40:
12931 case FT_INT48:
12932 case FT_INT56:
12933 case FT_INT64:
12934 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12935 break;
12936
12937 case FT_BOOLEAN:
12938 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12939 break;
12940
12941 default:
12942 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))
12943 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))
12944 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))
12945 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))
;
12946 break;
12947 }
12948 if (flags & BMT_NO_APPEND0x01) {
12949 fields++;
12950 continue;
12951 }
12952 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12953
12954 /* XXX: README.developer and the comments have always defined
12955 * BMT_NO_INT as "only boolean flags are added to the title /
12956 * don't add non-boolean (integral) fields", but the
12957 * implementation has always added BASE_CUSTOM and fields with
12958 * value_strings, though not fields with unit_strings.
12959 * Possibly this is because some dissectors use a FT_UINT8
12960 * with a value_string for fields that should be a FT_BOOLEAN.
12961 */
12962 switch (hf->type) {
12963 case FT_CHAR:
12964 if (hf->display == BASE_CUSTOM) {
12965 char lbl[ITEM_LABEL_LENGTH240];
12966 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12967
12968 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12968, "fmtfunc"))))
;
12969 fmtfunc(lbl, (uint32_t) tmpval);
12970 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12971 hf->name, lbl);
12972 first = false0;
12973 }
12974 else if (hf->strings) {
12975 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12976 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12977 first = false0;
12978 }
12979 else if (!(flags & BMT_NO_INT0x02)) {
12980 char buf[32];
12981 const char *out;
12982
12983 if (!first) {
12984 proto_item_append_text(item, ", ");
12985 }
12986
12987 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12988 proto_item_append_text(item, "%s: %s", hf->name, out);
12989 first = false0;
12990 }
12991
12992 break;
12993
12994 case FT_UINT8:
12995 case FT_UINT16:
12996 case FT_UINT24:
12997 case FT_UINT32:
12998 if (hf->display == BASE_CUSTOM) {
12999 char lbl[ITEM_LABEL_LENGTH240];
13000 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13001
13002 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13002, "fmtfunc"))))
;
13003 fmtfunc(lbl, (uint32_t) tmpval);
13004 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13005 hf->name, lbl);
13006 first = false0;
13007 }
13008 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13009 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13010 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13011 first = false0;
13012 }
13013 else if (!(flags & BMT_NO_INT0x02)) {
13014 char buf[NUMBER_LABEL_LENGTH80];
13015 const char *out = NULL((void*)0);
13016
13017 if (!first) {
13018 proto_item_append_text(item, ", ");
13019 }
13020
13021 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13022 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13023 }
13024 if (out == NULL((void*)0)) {
13025 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13026 }
13027 proto_item_append_text(item, "%s: %s", hf->name, out);
13028 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13029 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13030 }
13031 first = false0;
13032 }
13033
13034 break;
13035
13036 case FT_INT8:
13037 case FT_INT16:
13038 case FT_INT24:
13039 case FT_INT32:
13040 integer32 = (uint32_t) tmpval;
13041 if (hf->bitmask) {
13042 no_of_bits = ws_count_ones(hf->bitmask);
13043 integer32 = ws_sign_ext32(integer32, no_of_bits);
13044 }
13045 if (hf->display == BASE_CUSTOM) {
13046 char lbl[ITEM_LABEL_LENGTH240];
13047 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13048
13049 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13049, "fmtfunc"))))
;
13050 fmtfunc(lbl, (int32_t) integer32);
13051 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13052 hf->name, lbl);
13053 first = false0;
13054 }
13055 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13056 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13057 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13058 first = false0;
13059 }
13060 else if (!(flags & BMT_NO_INT0x02)) {
13061 char buf[NUMBER_LABEL_LENGTH80];
13062 const char *out = NULL((void*)0);
13063
13064 if (!first) {
13065 proto_item_append_text(item, ", ");
13066 }
13067
13068 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13069 out = hf_try_val_to_str((int32_t) integer32, hf);
13070 }
13071 if (out == NULL((void*)0)) {
13072 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13073 }
13074 proto_item_append_text(item, "%s: %s", hf->name, out);
13075 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13076 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13077 }
13078 first = false0;
13079 }
13080
13081 break;
13082
13083 case FT_UINT40:
13084 case FT_UINT48:
13085 case FT_UINT56:
13086 case FT_UINT64:
13087 if (hf->display == BASE_CUSTOM) {
13088 char lbl[ITEM_LABEL_LENGTH240];
13089 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13090
13091 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13091, "fmtfunc"))))
;
13092 fmtfunc(lbl, tmpval);
13093 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13094 hf->name, lbl);
13095 first = false0;
13096 }
13097 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13098 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13099 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13100 first = false0;
13101 }
13102 else if (!(flags & BMT_NO_INT0x02)) {
13103 char buf[NUMBER_LABEL_LENGTH80];
13104 const char *out = NULL((void*)0);
13105
13106 if (!first) {
13107 proto_item_append_text(item, ", ");
13108 }
13109
13110 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13111 out = hf_try_val64_to_str(tmpval, hf);
13112 }
13113 if (out == NULL((void*)0)) {
13114 out = hfinfo_number_value_format64(hf, buf, tmpval);
13115 }
13116 proto_item_append_text(item, "%s: %s", hf->name, out);
13117 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13118 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13119 }
13120 first = false0;
13121 }
13122
13123 break;
13124
13125 case FT_INT40:
13126 case FT_INT48:
13127 case FT_INT56:
13128 case FT_INT64:
13129 if (hf->bitmask) {
13130 no_of_bits = ws_count_ones(hf->bitmask);
13131 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13132 }
13133 if (hf->display == BASE_CUSTOM) {
13134 char lbl[ITEM_LABEL_LENGTH240];
13135 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13136
13137 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13137, "fmtfunc"))))
;
13138 fmtfunc(lbl, (int64_t) tmpval);
13139 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13140 hf->name, lbl);
13141 first = false0;
13142 }
13143 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13144 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13145 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13146 first = false0;
13147 }
13148 else if (!(flags & BMT_NO_INT0x02)) {
13149 char buf[NUMBER_LABEL_LENGTH80];
13150 const char *out = NULL((void*)0);
13151
13152 if (!first) {
13153 proto_item_append_text(item, ", ");
13154 }
13155
13156 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13157 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13158 }
13159 if (out == NULL((void*)0)) {
13160 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13161 }
13162 proto_item_append_text(item, "%s: %s", hf->name, out);
13163 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13164 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13165 }
13166 first = false0;
13167 }
13168
13169 break;
13170
13171 case FT_BOOLEAN:
13172 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13173 /* If we have true/false strings, emit full - otherwise messages
13174 might look weird */
13175 const struct true_false_string *tfs =
13176 (const struct true_false_string *)hf->strings;
13177
13178 if (tmpval) {
13179 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13180 hf->name, tfs->true_string);
13181 first = false0;
13182 } else if (!(flags & BMT_NO_FALSE0x04)) {
13183 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13184 hf->name, tfs->false_string);
13185 first = false0;
13186 }
13187 } else if (hf->bitmask & value) {
13188 /* If the flag is set, show the name */
13189 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13190 first = false0;
13191 }
13192 break;
13193 default:
13194 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))
13195 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))
13196 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))
13197 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))
;
13198 break;
13199 }
13200
13201 fields++;
13202 }
13203
13204 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13205 * but then again most dissectors don't set the bitmask field for
13206 * the higher level bitmask hfi, so calculate the bitmask from the
13207 * fields present. */
13208 if (item) {
13209 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13210 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13211 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)
;
13212 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)
;
13213 }
13214 return first;
13215}
13216
13217/* This function will dissect a sequence of bytes that describe a
13218 * bitmask and supply the value of that sequence through a pointer.
13219 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13220 * to be dissected.
13221 * This field will form an expansion under which the individual fields of the
13222 * bitmask is dissected and displayed.
13223 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13224 *
13225 * fields is an array of pointers to int that lists all the fields of the
13226 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13227 * or another integer of the same type/size as hf_hdr with a mask specified.
13228 * This array is terminated by a NULL entry.
13229 *
13230 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13231 * FT_integer fields that have a value_string attached will have the
13232 * matched string displayed on the expansion line.
13233 */
13234proto_item *
13235proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13236 const unsigned offset, const int hf_hdr,
13237 const int ett, int * const *fields,
13238 const unsigned encoding, uint64_t *retval)
13239{
13240 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);
13241}
13242
13243/* This function will dissect a sequence of bytes that describe a
13244 * bitmask.
13245 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13246 * to be dissected.
13247 * This field will form an expansion under which the individual fields of the
13248 * bitmask is dissected and displayed.
13249 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13250 *
13251 * fields is an array of pointers to int that lists all the fields of the
13252 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13253 * or another integer of the same type/size as hf_hdr with a mask specified.
13254 * This array is terminated by a NULL entry.
13255 *
13256 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13257 * FT_integer fields that have a value_string attached will have the
13258 * matched string displayed on the expansion line.
13259 */
13260proto_item *
13261proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13262 const unsigned offset, const int hf_hdr,
13263 const int ett, int * const *fields,
13264 const unsigned encoding)
13265{
13266 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13267}
13268
13269/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13270 * what data is appended to the header.
13271 */
13272proto_item *
13273proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13274 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13275 uint64_t *retval)
13276{
13277 proto_item *item = NULL((void*)0);
13278 header_field_info *hf;
13279 unsigned len;
13280 uint64_t value;
13281
13282 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", 13282, __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", 13282
, "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", 13282, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13283 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", 13283, (hf)->abbrev)))
;
13284 len = ftype_wire_size(hf->type);
13285 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13286
13287 if (parent_tree) {
13288 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13289 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13290 flags, false0, false0, NULL((void*)0), value);
13291 }
13292
13293 *retval = value;
13294 if (hf->bitmask) {
13295 /* Mask out irrelevant portions */
13296 *retval &= hf->bitmask;
13297 /* Shift bits */
13298 *retval >>= hfinfo_bitshift(hf);
13299 }
13300
13301 return item;
13302}
13303
13304/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13305 * what data is appended to the header.
13306 */
13307proto_item *
13308proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13309 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13310{
13311 proto_item *item = NULL((void*)0);
13312 header_field_info *hf;
13313 unsigned len;
13314 uint64_t value;
13315
13316 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", 13316, __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", 13316
, "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", 13316, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13317 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", 13317, (hf)->abbrev)))
;
13318
13319 if (parent_tree) {
13320 len = ftype_wire_size(hf->type);
13321 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13322 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13323 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13324 flags, false0, false0, NULL((void*)0), value);
13325 }
13326
13327 return item;
13328}
13329
13330/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13331 can't be retrieved directly from tvb) */
13332proto_item *
13333proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13334 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13335{
13336 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13337 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13338}
13339
13340/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13341WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13342proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13343 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13344{
13345 proto_item *item = NULL((void*)0);
13346 header_field_info *hf;
13347 unsigned len;
13348
13349 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", 13349, __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", 13349
, "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", 13349, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13350 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", 13350, (hf)->abbrev)))
;
13351 /* the proto_tree_add_uint/_uint64() calls below
13352 will fail if tvb==NULL and len!=0 */
13353 len = tvb ? ftype_wire_size(hf->type) : 0;
13354
13355 if (parent_tree) {
13356 if (len <= 4)
13357 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13358 else
13359 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13360
13361 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13362 flags, false0, false0, NULL((void*)0), value);
13363 }
13364
13365 return item;
13366}
13367
13368/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13369void
13370proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13371 const unsigned len, int * const *fields, const unsigned encoding)
13372{
13373 uint64_t value;
13374
13375 if (tree) {
13376 value = get_uint64_value(tree, tvb, offset, len, encoding);
13377 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13378 BMT_NO_APPEND0x01, false0, true1, tree, value);
13379 }
13380}
13381
13382WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13383proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13384 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13385{
13386 uint64_t value;
13387
13388 value = get_uint64_value(tree, tvb, offset, len, encoding);
13389 if (tree) {
13390 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13391 BMT_NO_APPEND0x01, false0, true1, tree, value);
13392 }
13393 if (retval) {
13394 *retval = value;
13395 }
13396}
13397
13398WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13399proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13400 const unsigned len, int * const *fields, const uint64_t value)
13401{
13402 if (tree) {
13403 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13404 BMT_NO_APPEND0x01, false0, true1, tree, value);
13405 }
13406}
13407
13408
13409/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13410 * This is intended to support bitmask fields whose lengths can vary, perhaps
13411 * as the underlying standard evolves over time.
13412 * With this API there is the possibility of being called to display more or
13413 * less data than the dissector was coded to support.
13414 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13415 * Thus when presented with "too much" or "too little" data, MSbits will be
13416 * ignored or MSfields sacrificed.
13417 *
13418 * Only fields for which all defined bits are available are displayed.
13419 */
13420proto_item *
13421proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13422 const unsigned offset, const unsigned len, const int hf_hdr,
13423 const int ett, int * const *fields, struct expert_field* exp,
13424 const unsigned encoding)
13425{
13426 proto_item *item = NULL((void*)0);
13427 header_field_info *hf;
13428 unsigned decodable_len;
13429 unsigned decodable_offset;
13430 uint32_t decodable_value;
13431 uint64_t value;
13432
13433 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", 13433, __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", 13433
, "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", 13433, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13434 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", 13434, (hf)->abbrev)))
;
13435
13436 decodable_offset = offset;
13437 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13438
13439 /* If we are ftype_wire_size-limited,
13440 * make sure we decode as many LSBs as possible.
13441 */
13442 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13443 decodable_offset += (len - decodable_len);
13444 }
13445
13446 if (parent_tree) {
13447 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13448 decodable_len, encoding);
13449
13450 /* The root item covers all the bytes even if we can't decode them all */
13451 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13452 decodable_value);
13453 }
13454
13455 if (decodable_len < len) {
13456 /* Dissector likely requires updating for new protocol revision */
13457 expert_add_info_format(NULL((void*)0), item, exp,
13458 "Only least-significant %d of %d bytes decoded",
13459 decodable_len, len);
13460 }
13461
13462 if (item) {
13463 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13464 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13465 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13466 }
13467
13468 return item;
13469}
13470
13471/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13472proto_item *
13473proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13474 const unsigned offset, const unsigned len,
13475 const char *name, const char *fallback,
13476 const int ett, int * const *fields,
13477 const unsigned encoding, const int flags)
13478{
13479 proto_item *item = NULL((void*)0);
13480 uint64_t value;
13481
13482 if (parent_tree) {
13483 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13484 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13485 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13486 flags, true1, false0, NULL((void*)0), value) && fallback) {
13487 /* Still at first item - append 'fallback' text if any */
13488 proto_item_append_text(item, "%s", fallback);
13489 }
13490 }
13491
13492 return item;
13493}
13494
13495proto_item *
13496proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13497 const unsigned bit_offset, const int no_of_bits,
13498 const unsigned encoding)
13499{
13500 header_field_info *hfinfo;
13501 int octet_length;
13502 unsigned octet_offset;
13503
13504 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", 13504, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13504
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13504, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13505
13506 if (no_of_bits < 0) {
13507 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13508 }
13509 octet_length = (no_of_bits + 7) >> 3;
13510 octet_offset = bit_offset >> 3;
13511 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13512
13513 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13514 * but only after doing a bunch more work (which we can, in the common
13515 * case, shortcut here).
13516 */
13517 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13518 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", 13518
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13518, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13518, "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", 13518, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13519
13520 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13521}
13522
13523/*
13524 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13525 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13526 * Offset should be given in bits from the start of the tvb.
13527 */
13528
13529static proto_item *
13530_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13531 const unsigned bit_offset, const int no_of_bits,
13532 uint64_t *return_value, const unsigned encoding)
13533{
13534 unsigned offset;
13535 unsigned length;
13536 uint8_t tot_no_bits;
13537 char *bf_str;
13538 char lbl_str[ITEM_LABEL_LENGTH240];
13539 uint64_t value = 0;
13540 uint8_t *bytes = NULL((void*)0);
13541 size_t bytes_length = 0;
13542
13543 proto_item *pi;
13544 header_field_info *hf_field;
13545
13546 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13547 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", 13547, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13547
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13547, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13548
13549 if (hf_field->bitmask != 0) {
13550 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)
13551 " 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)
13552 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)
;
13553 }
13554
13555 if (no_of_bits < 0) {
13556 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13557 } else if (no_of_bits == 0) {
13558 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)
13559 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)
;
13560 }
13561
13562 /* Byte align offset */
13563 offset = bit_offset>>3;
13564
13565 /*
13566 * Calculate the number of octets used to hold the bits
13567 */
13568 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13569 length = (tot_no_bits + 7) >> 3;
13570
13571 if (no_of_bits < 65) {
13572 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13573 } else if (hf_field->type != FT_BYTES) {
13574 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)
13575 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)
;
13576 return NULL((void*)0);
13577 }
13578
13579 /* Sign extend for signed types */
13580 switch (hf_field->type) {
13581 case FT_INT8:
13582 case FT_INT16:
13583 case FT_INT24:
13584 case FT_INT32:
13585 case FT_INT40:
13586 case FT_INT48:
13587 case FT_INT56:
13588 case FT_INT64:
13589 value = ws_sign_ext64(value, no_of_bits);
13590 break;
13591
13592 default:
13593 break;
13594 }
13595
13596 if (return_value) {
13597 *return_value = value;
13598 }
13599
13600 /* Coast clear. Try and fake it */
13601 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13602 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", 13602
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13602, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13602, "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", 13602, __func__, "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); } } }
;
13603
13604 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13605
13606 switch (hf_field->type) {
13607 case FT_BOOLEAN:
13608 /* Boolean field */
13609 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13610 "%s = %s: %s",
13611 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13612 break;
13613
13614 case FT_CHAR:
13615 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13616 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13617 break;
13618
13619 case FT_UINT8:
13620 case FT_UINT16:
13621 case FT_UINT24:
13622 case FT_UINT32:
13623 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13624 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13625 break;
13626
13627 case FT_INT8:
13628 case FT_INT16:
13629 case FT_INT24:
13630 case FT_INT32:
13631 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13632 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13633 break;
13634
13635 case FT_UINT40:
13636 case FT_UINT48:
13637 case FT_UINT56:
13638 case FT_UINT64:
13639 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13640 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13641 break;
13642
13643 case FT_INT40:
13644 case FT_INT48:
13645 case FT_INT56:
13646 case FT_INT64:
13647 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13648 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13649 break;
13650
13651 case FT_BYTES:
13652 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13653 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13654 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13655 proto_item_set_text(pi, "%s", lbl_str);
13656 return pi;
13657
13658 /* TODO: should handle FT_UINT_BYTES ? */
13659
13660 default:
13661 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))
13662 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))
13663 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))
13664 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))
;
13665 return NULL((void*)0);
13666 }
13667
13668 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13669 return pi;
13670}
13671
13672proto_item *
13673proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13674 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13675 uint64_t *return_value)
13676{
13677 proto_item *pi;
13678 int no_of_bits;
13679 unsigned octet_offset;
13680 unsigned mask_initial_bit_offset;
13681 unsigned mask_greatest_bit_offset;
13682 unsigned octet_length;
13683 uint8_t i;
13684 char bf_str[256];
13685 char lbl_str[ITEM_LABEL_LENGTH240];
13686 uint64_t value;
13687 uint64_t composite_bitmask;
13688 uint64_t composite_bitmap;
13689
13690 header_field_info *hf_field;
13691
13692 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13693 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", 13693, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13693
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13693, "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
13694
13695 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13696 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)
13697 " 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)
13698 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)
;
13699 }
13700
13701 mask_initial_bit_offset = bit_offset % 8;
13702
13703 no_of_bits = 0;
13704 value = 0;
13705 i = 0;
13706 mask_greatest_bit_offset = 0;
13707 composite_bitmask = 0;
13708 composite_bitmap = 0;
13709
13710 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
13711 uint64_t crumb_mask, crumb_value;
13712 uint8_t crumb_end_bit_offset;
13713
13714 crumb_value = tvb_get_bits64(tvb,
13715 bit_offset + crumb_spec[i].crumb_bit_offset,
13716 crumb_spec[i].crumb_bit_length,
13717 ENC_BIG_ENDIAN0x00000000);
13718 value += crumb_value;
13719 no_of_bits += crumb_spec[i].crumb_bit_length;
13720 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", 13720
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13721
13722 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13723 octet containing the initial offset.
13724 If the mask is beyond 32 bits, then give up on bit map display.
13725 This could be improved in future, probably showing a table
13726 of 32 or 64 bits per row */
13727 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13728 crumb_end_bit_offset = mask_initial_bit_offset
13729 + crumb_spec[i].crumb_bit_offset
13730 + crumb_spec[i].crumb_bit_length;
13731 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'
13732
13733 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13734 mask_greatest_bit_offset = crumb_end_bit_offset;
13735 }
13736 /* Currently the bitmap of the crumbs are only shown if
13737 * smaller than 32 bits. Do not bother calculating the
13738 * mask if it is larger than that. */
13739 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13740 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'
13741 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13742 }
13743 }
13744 /* Shift left for the next segment */
13745 value <<= crumb_spec[++i].crumb_bit_length;
13746 }
13747
13748 /* Sign extend for signed types */
13749 switch (hf_field->type) {
13750 case FT_INT8:
13751 case FT_INT16:
13752 case FT_INT24:
13753 case FT_INT32:
13754 case FT_INT40:
13755 case FT_INT48:
13756 case FT_INT56:
13757 case FT_INT64:
13758 value = ws_sign_ext64(value, no_of_bits);
13759 break;
13760 default:
13761 break;
13762 }
13763
13764 if (return_value) {
13765 *return_value = value;
13766 }
13767
13768 /* Coast clear. Try and fake it */
13769 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13770 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", 13770
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13770, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13770, "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", 13770, __func__, "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); } } }
;
13771
13772 /* initialise the format string */
13773 bf_str[0] = '\0';
13774
13775 octet_offset = bit_offset >> 3;
13776
13777 /* Round up mask length to nearest octet */
13778 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13779 mask_greatest_bit_offset = octet_length << 3;
13780
13781 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13782 It would be a useful enhancement to eliminate this restriction. */
13783 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13784 other_decode_bitfield_value(bf_str,
13785 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13786 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13787 mask_greatest_bit_offset);
13788 } else {
13789 /* If the bitmask is too large, try to describe its contents. */
13790 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13791 }
13792
13793 switch (hf_field->type) {
13794 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13795 /* Boolean field */
13796 return proto_tree_add_boolean_format(tree, hfindex,
13797 tvb, octet_offset, octet_length, value,
13798 "%s = %s: %s",
13799 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13800 break;
13801
13802 case FT_CHAR:
13803 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13804 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13805 break;
13806
13807 case FT_UINT8:
13808 case FT_UINT16:
13809 case FT_UINT24:
13810 case FT_UINT32:
13811 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13812 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13813 break;
13814
13815 case FT_INT8:
13816 case FT_INT16:
13817 case FT_INT24:
13818 case FT_INT32:
13819 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13820 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13821 break;
13822
13823 case FT_UINT40:
13824 case FT_UINT48:
13825 case FT_UINT56:
13826 case FT_UINT64:
13827 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13828 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13829 break;
13830
13831 case FT_INT40:
13832 case FT_INT48:
13833 case FT_INT56:
13834 case FT_INT64:
13835 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13836 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13837 break;
13838
13839 default:
13840 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))
13841 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))
13842 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))
13843 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))
;
13844 return NULL((void*)0);
13845 }
13846 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13847 return pi;
13848}
13849
13850void
13851proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13852 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13853{
13854 header_field_info *hfinfo;
13855 unsigned start = bit_offset >> 3;
13856 unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13857
13858 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13859 * so that we can use the tree's memory scope in calculating the string */
13860 tvb_ensure_bytes_exist(tvb, start, length);
13861 if (!tree) return;
13862
13863 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", 13863, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13863
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13863, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13864 proto_tree_add_text_internal(tree, tvb, start, length,
13865 "%s crumb %d of %s (decoded above)",
13866 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13867 tvb_get_bits32(tvb,
13868 bit_offset,
13869 crumb_spec[crumb_index].crumb_bit_length,
13870 ENC_BIG_ENDIAN0x00000000),
13871 ENC_BIG_ENDIAN0x00000000),
13872 crumb_index,
13873 hfinfo->name);
13874}
13875
13876proto_item *
13877proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13878 const unsigned bit_offset, const int no_of_bits,
13879 uint64_t *return_value, const unsigned encoding)
13880{
13881 proto_item *item;
13882
13883 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13884 bit_offset, no_of_bits,
13885 return_value, encoding))) {
13886 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)
;
13887 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)
;
13888 }
13889 return item;
13890}
13891
13892static proto_item *
13893_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13894 tvbuff_t *tvb, const unsigned bit_offset,
13895 const int no_of_bits, void *value_ptr,
13896 const unsigned encoding, char *value_str)
13897{
13898 unsigned offset;
13899 unsigned length;
13900 uint8_t tot_no_bits;
13901 char *str;
13902 uint64_t value = 0;
13903 header_field_info *hf_field;
13904
13905 /* We do not have to return a value, try to fake it as soon as possible */
13906 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
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 if (hf_field->bitmask != 0) {
13910 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)
13911 " 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)
13912 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)
;
13913 }
13914
13915 if (no_of_bits < 0) {
13916 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13917 } else if (no_of_bits == 0) {
13918 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)
13919 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)
;
13920 }
13921
13922 /* Byte align offset */
13923 offset = bit_offset>>3;
13924
13925 /*
13926 * Calculate the number of octets used to hold the bits
13927 */
13928 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13929 length = tot_no_bits>>3;
13930 /* If we are using part of the next octet, increase length by 1 */
13931 if (tot_no_bits & 0x07)
13932 length++;
13933
13934 if (no_of_bits < 65) {
13935 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13936 } else {
13937 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)
13938 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)
;
13939 return NULL((void*)0);
13940 }
13941
13942 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13943
13944 (void) g_strlcat(str, " = ", 256+64);
13945 (void) g_strlcat(str, hf_field->name, 256+64);
13946
13947 /*
13948 * This function does not receive an actual value but a dimensionless pointer to that value.
13949 * For this reason, the type of the header field is examined in order to determine
13950 * what kind of value we should read from this address.
13951 * The caller of this function must make sure that for the specific header field type the address of
13952 * a compatible value is provided.
13953 */
13954 switch (hf_field->type) {
13955 case FT_BOOLEAN:
13956 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13957 "%s: %s", str, value_str);
13958 break;
13959
13960 case FT_CHAR:
13961 case FT_UINT8:
13962 case FT_UINT16:
13963 case FT_UINT24:
13964 case FT_UINT32:
13965 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13966 "%s: %s", str, value_str);
13967 break;
13968
13969 case FT_UINT40:
13970 case FT_UINT48:
13971 case FT_UINT56:
13972 case FT_UINT64:
13973 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13974 "%s: %s", str, value_str);
13975 break;
13976
13977 case FT_INT8:
13978 case FT_INT16:
13979 case FT_INT24:
13980 case FT_INT32:
13981 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13982 "%s: %s", str, value_str);
13983 break;
13984
13985 case FT_INT40:
13986 case FT_INT48:
13987 case FT_INT56:
13988 case FT_INT64:
13989 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13990 "%s: %s", str, value_str);
13991 break;
13992
13993 case FT_FLOAT:
13994 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13995 "%s: %s", str, value_str);
13996 break;
13997
13998 default:
13999 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))
14000 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))
14001 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))
14002 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))
;
14003 return NULL((void*)0);
14004 }
14005}
14006
14007static proto_item *
14008proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14009 tvbuff_t *tvb, const unsigned bit_offset,
14010 const int no_of_bits, void *value_ptr,
14011 const unsigned encoding, char *value_str)
14012{
14013 proto_item *item;
14014
14015 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14016 tvb, bit_offset, no_of_bits,
14017 value_ptr, encoding, value_str))) {
14018 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)
;
14019 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)
;
14020 }
14021 return item;
14022}
14023
14024#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);
\
14025 va_start(ap, format)__builtin_va_start(ap, format); \
14026 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14027 va_end(ap)__builtin_va_end(ap);
14028
14029proto_item *
14030proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14031 tvbuff_t *tvb, const unsigned bit_offset,
14032 const int no_of_bits, uint32_t value,
14033 const unsigned encoding,
14034 const char *format, ...)
14035{
14036 va_list ap;
14037 char *dst;
14038 header_field_info *hf_field;
14039
14040 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14041
14042 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", 14042
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14042, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14042, "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", 14042, __func__, "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); } } }
;
14043
14044 switch (hf_field->type) {
14045 case FT_UINT8:
14046 case FT_UINT16:
14047 case FT_UINT24:
14048 case FT_UINT32:
14049 break;
14050
14051 default:
14052 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)
14053 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)
;
14054 return NULL((void*)0);
14055 }
14056
14057 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);
;
14058
14059 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14060}
14061
14062proto_item *
14063proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14064 tvbuff_t *tvb, const unsigned bit_offset,
14065 const int no_of_bits, uint64_t value,
14066 const unsigned encoding,
14067 const char *format, ...)
14068{
14069 va_list ap;
14070 char *dst;
14071 header_field_info *hf_field;
14072
14073 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14074
14075 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", 14075
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14075, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14075, "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", 14075, __func__, "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); } } }
;
14076
14077 switch (hf_field->type) {
14078 case FT_UINT40:
14079 case FT_UINT48:
14080 case FT_UINT56:
14081 case FT_UINT64:
14082 break;
14083
14084 default:
14085 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)
14086 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)
;
14087 return NULL((void*)0);
14088 }
14089
14090 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);
;
14091
14092 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14093}
14094
14095proto_item *
14096proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14097 tvbuff_t *tvb, const unsigned bit_offset,
14098 const int no_of_bits, float value,
14099 const unsigned encoding,
14100 const char *format, ...)
14101{
14102 va_list ap;
14103 char *dst;
14104 header_field_info *hf_field;
14105
14106 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14107
14108 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", 14108
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14108, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14108, "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", 14108, __func__, "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); } } }
;
14109
14110 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",
14110, ((hf_field))->abbrev))))
;
14111
14112 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);
;
14113
14114 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14115}
14116
14117proto_item *
14118proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14119 tvbuff_t *tvb, const unsigned bit_offset,
14120 const int no_of_bits, int32_t value,
14121 const unsigned encoding,
14122 const char *format, ...)
14123{
14124 va_list ap;
14125 char *dst;
14126 header_field_info *hf_field;
14127
14128 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14129
14130 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", 14130
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14130, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14130, "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", 14130, __func__, "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); } } }
;
14131
14132 switch (hf_field->type) {
14133 case FT_INT8:
14134 case FT_INT16:
14135 case FT_INT24:
14136 case FT_INT32:
14137 break;
14138
14139 default:
14140 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)
14141 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)
;
14142 return NULL((void*)0);
14143 }
14144
14145 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);
;
14146
14147 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14148}
14149
14150proto_item *
14151proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14152 tvbuff_t *tvb, const unsigned bit_offset,
14153 const int no_of_bits, int64_t value,
14154 const unsigned encoding,
14155 const char *format, ...)
14156{
14157 va_list ap;
14158 char *dst;
14159 header_field_info *hf_field;
14160
14161 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14162
14163 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", 14163
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14163, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14163, "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", 14163, __func__, "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); } } }
;
14164
14165 switch (hf_field->type) {
14166 case FT_INT40:
14167 case FT_INT48:
14168 case FT_INT56:
14169 case FT_INT64:
14170 break;
14171
14172 default:
14173 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)
14174 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)
;
14175 return NULL((void*)0);
14176 }
14177
14178 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);
;
14179
14180 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14181}
14182
14183proto_item *
14184proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14185 tvbuff_t *tvb, const unsigned bit_offset,
14186 const int no_of_bits, uint64_t value,
14187 const unsigned encoding,
14188 const char *format, ...)
14189{
14190 va_list ap;
14191 char *dst;
14192 header_field_info *hf_field;
14193
14194 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14195
14196 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", 14196
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14196, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14196, "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", 14196, __func__, "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); } } }
;
14197
14198 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"
, 14198, ((hf_field))->abbrev))))
;
14199
14200 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);
;
14201
14202 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14203}
14204
14205proto_item *
14206proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14207 const unsigned bit_offset, const int no_of_chars)
14208{
14209 proto_item *pi;
14210 header_field_info *hfinfo;
14211 int byte_length;
14212 unsigned byte_offset;
14213 char *string;
14214
14215 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14216
14217 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", 14217
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14217, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14217, "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", 14217, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14218
14219 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"
, 14219, ((hfinfo))->abbrev))))
;
14220
14221 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14222 byte_offset = bit_offset >> 3;
14223
14224 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14225
14226 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14227 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14227, "byte_length >= 0"
))))
;
14228 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14229
14230 return pi;
14231}
14232
14233proto_item *
14234proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14235 const unsigned bit_offset, const int no_of_chars)
14236{
14237 proto_item *pi;
14238 header_field_info *hfinfo;
14239 int byte_length;
14240 unsigned byte_offset;
14241 char *string;
14242
14243 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14244
14245 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", 14245
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14245, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14245, "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", 14245, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14246
14247 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"
, 14247, ((hfinfo))->abbrev))))
;
14248
14249 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14250 byte_offset = bit_offset >> 3;
14251
14252 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14253
14254 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14255 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14255, "byte_length >= 0"
))))
;
14256 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14257
14258 return pi;
14259}
14260
14261const value_string proto_checksum_vals[] = {
14262 { PROTO_CHECKSUM_E_BAD, "Bad" },
14263 { PROTO_CHECKSUM_E_GOOD, "Good" },
14264 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14265 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14266 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14267
14268 { 0, NULL((void*)0) }
14269};
14270
14271#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14272
14273proto_item *
14274proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14275 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14276 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14277{
14278 header_field_info *hfinfo;
14279 uint32_t checksum;
14280 uint32_t len;
14281 proto_item* ti = NULL((void*)0);
14282 proto_item* ti2;
14283 bool_Bool incorrect_checksum = true1;
14284
14285 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", 14285, __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", 14285
, "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", 14285, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14286
14287 switch (hfinfo->type) {
14288 case FT_UINT8:
14289 len = 1;
14290 break;
14291 case FT_UINT16:
14292 len = 2;
14293 break;
14294 case FT_UINT24:
14295 len = 3;
14296 break;
14297 case FT_UINT32:
14298 len = 4;
14299 break;
14300 default:
14301 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)
14302 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14303 }
14304
14305 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14306 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14307 proto_item_set_generated(ti);
14308 // Backward compatible with use of -1
14309 if (hf_checksum_status > 0) {
14310 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14311 proto_item_set_generated(ti2);
14312 }
14313 return ti;
14314 }
14315
14316 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14317 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14318 proto_item_set_generated(ti);
14319 } else {
14320 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14321 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14322 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14323 if (computed_checksum == 0) {
14324 proto_item_append_text(ti, " [correct]");
14325 // Backward compatible with use of -1
14326 if (hf_checksum_status > 0) {
14327 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14328 proto_item_set_generated(ti2);
14329 }
14330 incorrect_checksum = false0;
14331 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14332 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14333 /* XXX - This can't distinguish between "shouldbe"
14334 * 0x0000 and 0xFFFF unless we know whether there
14335 * were any nonzero bits (other than the checksum).
14336 * Protocols should not use this path if they might
14337 * have an all zero packet.
14338 * Some implementations put the wrong zero; maybe
14339 * we should have a special expert info for that?
14340 */
14341 }
14342 } else {
14343 if (checksum == computed_checksum) {
14344 proto_item_append_text(ti, " [correct]");
14345 // Backward compatible with use of -1
14346 if (hf_checksum_status > 0) {
14347 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14348 proto_item_set_generated(ti2);
14349 }
14350 incorrect_checksum = false0;
14351 }
14352 }
14353
14354 if (incorrect_checksum) {
14355 // Backward compatible with use of -1
14356 if (hf_checksum_status > 0) {
14357 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14358 proto_item_set_generated(ti2);
14359 }
14360 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14361 proto_item_append_text(ti, " [incorrect]");
14362 if (bad_checksum_expert != NULL((void*)0))
14363 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14364 } else {
14365 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14366 if (bad_checksum_expert != NULL((void*)0))
14367 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);
14368 }
14369 }
14370 } else {
14371 // Backward compatible with use of -1
14372 if (hf_checksum_status > 0) {
14373 proto_item_append_text(ti, " [unverified]");
14374 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14375 proto_item_set_generated(ti2);
14376 }
14377 }
14378 }
14379
14380 return ti;
14381}
14382
14383proto_item *
14384proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14385 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14386 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14387{
14388 header_field_info *hfinfo;
14389 uint8_t *checksum = NULL((void*)0);
14390 proto_item* ti = NULL((void*)0);
14391 proto_item* ti2;
14392 bool_Bool incorrect_checksum = true1;
14393
14394 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", 14394, __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", 14394
, "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", 14394, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14395
14396 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",
14396, ((hfinfo))->abbrev))))
;
14397
14398 /* Make sure a NULL computed_checksum isn't dereferenced.
14399 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14400 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14401 * cases the behavior is unexpected and still a programmer error;
14402 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14403 * _NOT_PRESENT nor _GENERATED is correct.
14404 */
14405 DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS))((void) ((computed_checksum || ((flags & (0x01|0x02|0x10)
) == 0x00)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 14405, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14406
14407 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14408 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14409 proto_item_set_generated(ti);
14410 // Backward compatible with use of -1
14411 if (hf_checksum_status > 0) {
14412 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14413 proto_item_set_generated(ti2);
14414 }
14415 return ti;
14416 }
14417
14418 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14419 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14420 proto_item_set_generated(ti);
14421 return ti;
14422 }
14423
14424 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14425 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14426 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14427 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14428 bool_Bool non_zero_flag = false0;
14429 for (size_t index = 0; index < checksum_len; index++) {
14430 if (computed_checksum[index]) {
14431 non_zero_flag = true1;
14432 break;
14433 }
14434 }
14435 if (!non_zero_flag) {
14436 proto_item_append_text(ti, " [correct]");
14437 // Backward compatible with use of -1
14438 if (hf_checksum_status > 0) {
14439 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14440 proto_item_set_generated(ti2);
14441 }
14442 incorrect_checksum = false0;
14443 }
14444 } else {
14445 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14446 proto_item_append_text(ti, " [correct]");
14447 // Backward compatible with use of -1
14448 if (hf_checksum_status > 0) {
14449 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14450 proto_item_set_generated(ti2);
14451 }
14452 incorrect_checksum = false0;
14453 }
14454 }
14455
14456 if (incorrect_checksum) {
14457 // Backward compatible with use of -1
14458 if (hf_checksum_status > 0) {
14459 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14460 proto_item_set_generated(ti2);
14461 }
14462 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14463 proto_item_append_text(ti, " [incorrect]");
14464 if (bad_checksum_expert != NULL((void*)0))
14465 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14466 } else {
14467 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14468 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14469 if (bad_checksum_expert != NULL((void*)0))
14470 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14471 }
14472 }
14473 } else {
14474 // Backward compatible with use of -1
14475 if (hf_checksum_status > 0) {
14476 proto_item_append_text(ti, " [unverified]");
14477 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14478 proto_item_set_generated(ti2);
14479 }
14480 }
14481
14482 return ti;
14483}
14484
14485unsigned char
14486proto_check_field_name(const char *field_name)
14487{
14488 return module_check_valid_name(field_name, false0);
14489}
14490
14491unsigned char
14492proto_check_field_name_lower(const char *field_name)
14493{
14494 return module_check_valid_name(field_name, true1);
14495}
14496
14497bool_Bool
14498tree_expanded(int tree_type)
14499{
14500 if (tree_type <= 0) {
14501 return false0;
14502 }
14503 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", 14503, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14504 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14505}
14506
14507void
14508tree_expanded_set(int tree_type, bool_Bool value)
14509{
14510 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", 14510, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14511
14512 if (value)
14513 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14514 else
14515 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14516}
14517
14518/*
14519 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14520 *
14521 * Local variables:
14522 * c-basic-offset: 8
14523 * tab-width: 8
14524 * indent-tabs-mode: t
14525 * End:
14526 *
14527 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14528 * :indentSize=8:tabSize=8:noTabs=false:
14529 */