Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13869, 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-12-100356-3642-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 unsigned cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is equal to 0 */
102#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
103 if (length == 0) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is equal to 0 */
111#define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
112 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (length == 0) { ((void)0); return ((void*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const unsigned start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 unsigned start, int *length);
300
301static proto_item *
302proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303 unsigned start, unsigned *length);
304
305static void
306proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307static void
308proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309
310static void
311proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312static void
313proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314static void
315proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316static void
317proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318static void
319proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320static void
321proto_tree_set_string(field_info *fi, const char* value);
322static void
323proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326static void
327proto_tree_set_vines(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330static void
331proto_tree_set_ether(field_info *fi, const uint8_t* value);
332static void
333proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334static void
335proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336static void
337proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338static void
339proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340static void
341proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342static void
343proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344static void
345proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346static void
347proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348static void
349proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350static void
351proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352static void
353proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354static void
355proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356static void
357proto_tree_set_boolean(field_info *fi, uint64_t value);
358static void
359proto_tree_set_float(field_info *fi, float value);
360static void
361proto_tree_set_double(field_info *fi, double value);
362static void
363proto_tree_set_uint(field_info *fi, uint32_t value);
364static void
365proto_tree_set_int(field_info *fi, int32_t value);
366static void
367proto_tree_set_uint64(field_info *fi, uint64_t value);
368static void
369proto_tree_set_int64(field_info *fi, int64_t value);
370static void
371proto_tree_set_eui64(field_info *fi, const uint64_t value);
372static void
373proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374
375/* Handle type length mismatch (now filterable) expert info */
376static int proto_type_length_mismatch;
377static expert_field ei_type_length_mismatch_error;
378static expert_field ei_type_length_mismatch_warn;
379static void register_type_length_mismatch(void);
380
381/* Handle byte array string decoding errors with expert info */
382static int proto_byte_array_string_decoding_error;
383static expert_field ei_byte_array_string_decoding_failed_error;
384static void register_byte_array_string_decodinws_error(void);
385
386/* Handle date and time string decoding errors with expert info */
387static int proto_date_time_string_decoding_error;
388static expert_field ei_date_time_string_decoding_failed_error;
389static void register_date_time_string_decodinws_error(void);
390
391/* Handle string errors expert info */
392static int proto_string_errors;
393static expert_field ei_string_trailing_characters;
394static void register_string_errors(void);
395
396/* Handle varint errors expert info */
397static int proto_varint_errors;
398static expert_field ei_varint_decoding_failed_error;
399static void register_varint_errors(void);
400
401static int proto_register_field_init(header_field_info *hfinfo, const int parent);
402
403/* special-case header field used within proto.c */
404static header_field_info hfi_text_only =
405 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
406int hf_text_only;
407
408/* Structure for information about a protocol */
409struct _protocol {
410 const char *name; /* long description */
411 const char *short_name; /* short description */
412 const char *filter_name; /* name of this protocol in filters */
413 GPtrArray *fields; /* fields for this protocol */
414 int proto_id; /* field ID for this protocol */
415 bool_Bool is_enabled; /* true if protocol is enabled */
416 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
417 bool_Bool can_toggle; /* true if is_enabled can be changed */
418 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
419 For dissectors that need a protocol name so they
420 can be added to a dissector table, but use the
421 parent_proto_id for things like enable/disable */
422 GList *heur_list; /* Heuristic dissectors associated with this protocol */
423};
424
425/* List of all protocols */
426static GList *protocols;
427
428/* Structure stored for deregistered g_slice */
429struct g_slice_data {
430 size_t block_size;
431 void *mem_block;
432};
433
434/* Deregistered fields */
435static GPtrArray *deregistered_fields;
436static GPtrArray *deregistered_data;
437static GPtrArray *deregistered_slice;
438
439/* indexed by prefix, contains initializers */
440static GHashTable* prefixes;
441
442/* Contains information about a field when a dissector calls
443 * proto_tree_add_item. */
444#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
445#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
446
447/* Contains the space for proto_nodes. */
448#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
449 node->first_child = NULL((void*)0); \
450 node->last_child = NULL((void*)0); \
451 node->next = NULL((void*)0);
452
453#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
454 wmem_free(pool, node)
455
456/* String space for protocol and field items for the GUI */
457#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
458 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
459 il->value_pos = 0; \
460 il->value_len = 0;
461#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
462 wmem_free(pool, il);
463
464#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 464, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 464, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
465 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
466 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 466
, __func__, "Unregistered hf! index=%d", hfindex)
; \
467 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 467, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
468 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 468, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
469 hfinfo = gpa_hfinfo.hfi[hfindex];
470
471#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
472
473/* List which stores protocols and fields that have been registered */
474typedef struct _gpa_hfinfo_t {
475 uint32_t len;
476 uint32_t allocated_len;
477 header_field_info **hfi;
478} gpa_hfinfo_t;
479
480static gpa_hfinfo_t gpa_hfinfo;
481
482/* Hash table of abbreviations and IDs */
483static wmem_map_t *gpa_name_map;
484static header_field_info *same_name_hfinfo;
485
486/* Hash table protocol aliases. const char * -> const char * */
487static GHashTable *gpa_protocol_aliases;
488
489/*
490 * We're called repeatedly with the same field name when sorting a column.
491 * Cache our last gpa_name_map hit for faster lookups.
492 */
493static char *last_field_name;
494static header_field_info *last_hfinfo;
495
496/* Points to the first element of an array of bits, indexed by
497 a subtree item type; that array element is true if subtrees of
498 an item of that type are to be expanded. */
499static uint32_t *tree_is_expanded;
500
501/* Number of elements in that array. The entry with index 0 is not used. */
502int num_tree_types = 1;
503
504/* Name hashtables for fast detection of duplicate names */
505static GHashTable* proto_names;
506static GHashTable* proto_short_names;
507static GHashTable* proto_filter_names;
508
509static const char * const reserved_filter_names[] = {
510 /* Display filter keywords. */
511 "eq",
512 "ne",
513 "all_eq",
514 "any_eq",
515 "all_ne",
516 "any_ne",
517 "gt",
518 "ge",
519 "lt",
520 "le",
521 "bitand",
522 "bitwise_and",
523 "contains",
524 "matches",
525 "not",
526 "and",
527 "or",
528 "xor",
529 "in",
530 "any",
531 "all",
532 "true",
533 "false",
534 "nan",
535 "inf",
536 "infinity",
537 NULL((void*)0)
538};
539
540static GHashTable *proto_reserved_filter_names;
541static GQueue* saved_dir_queue;
542
543static int
544proto_compare_name(const void *p1_arg, const void *p2_arg)
545{
546 const protocol_t *p1 = (const protocol_t *)p1_arg;
547 const protocol_t *p2 = (const protocol_t *)p2_arg;
548
549 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
550}
551
552static GSList *dissector_plugins;
553
554#ifdef HAVE_PLUGINS1
555void
556proto_register_plugin(const proto_plugin *plug)
557{
558 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
559}
560#else /* HAVE_PLUGINS */
561void
562proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
563{
564 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 564, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
565}
566#endif /* HAVE_PLUGINS */
567
568static void
569call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
570{
571 proto_plugin *plug = (proto_plugin *)data;
572
573 if (plug->register_protoinfo) {
574 plug->register_protoinfo();
575 }
576}
577
578static void
579call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
580{
581 proto_plugin *plug = (proto_plugin *)data;
582
583 if (plug->register_handoff) {
584 plug->register_handoff();
585 }
586}
587
588void proto_pre_init(void)
589{
590 saved_dir_queue = g_queue_new();
591
592 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
593 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
594 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
595
596 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
597 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
598 /* GHashTable has no key destructor so the cast is safe. */
599 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
600 }
601
602 gpa_hfinfo.len = 0;
603 gpa_hfinfo.allocated_len = 0;
604 gpa_hfinfo.hfi = NULL((void*)0);
605 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
606 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
607 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
608 deregistered_fields = g_ptr_array_new();
609 deregistered_data = g_ptr_array_new();
610 deregistered_slice = g_ptr_array_new();
611}
612
613/* initialize data structures and register protocols and fields */
614void
615proto_init(GSList *register_all_plugin_protocols_list,
616 GSList *register_all_plugin_handoffs_list,
617 register_entity_func register_func, register_entity_func handoff_func,
618 register_cb cb,
619 void *client_data)
620{
621 /* Initialize the ftype subsystem */
622 ftypes_initialize();
623
624 /* Initialize the address type subsystem */
625 address_types_initialize();
626
627 /* Register one special-case FT_TEXT_ONLY field for use when
628 converting wireshark to new-style proto_tree. These fields
629 are merely strings on the GUI tree; they are not filterable */
630 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
631
632 /* Register the pseudo-protocols used for exceptions. */
633 register_show_exception();
634 register_type_length_mismatch();
635 register_byte_array_string_decodinws_error();
636 register_date_time_string_decodinws_error();
637 register_string_errors();
638 register_varint_errors();
639 ftypes_register_pseudofields();
640 col_register_protocol();
641
642 /* Have each built-in dissector register its protocols, fields,
643 dissector tables, and dissectors to be called through a
644 handle, and do whatever one-time initialization it needs to
645 do. */
646 if (register_func != NULL((void*)0))
647 register_func(cb, client_data);
648
649 /* Now call the registration routines for all epan plugins. */
650 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
651 ((void (*)(register_cb, void *))l->data)(cb, client_data);
652 }
653
654 /* Now call the registration routines for all dissector plugins. */
655 if (cb)
656 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
657 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
658
659 /* Now call the "handoff registration" routines of all built-in
660 dissectors; those routines register the dissector in other
661 dissectors' handoff tables, and fetch any dissector handles
662 they need. */
663 if (handoff_func != NULL((void*)0))
664 handoff_func(cb, client_data);
665
666 /* Now do the same with epan plugins. */
667 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
668 ((void (*)(register_cb, void *))l->data)(cb, client_data);
669 }
670
671 /* Now do the same with dissector plugins. */
672 if (cb)
673 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
674 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
675
676 /* sort the protocols by protocol name */
677 protocols = g_list_sort(protocols, proto_compare_name);
678
679 /* sort the dissector handles in dissector tables (for -G reports
680 * and -d error messages. The GUI sorts the handles itself.) */
681 packet_all_tables_sort_handles();
682
683 /* We've assigned all the subtree type values; allocate the array
684 for them, and zero it out. */
685 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
686}
687
688static void
689proto_cleanup_base(void)
690{
691 protocol_t *protocol;
692 header_field_info *hfinfo;
693
694 /* Free the abbrev/ID hash table */
695 if (gpa_name_map) {
696 // XXX - We don't have a wmem_map_destroy, but
697 // it does get cleaned up when epan scope is
698 // destroyed
699 //g_hash_table_destroy(gpa_name_map);
700 gpa_name_map = NULL((void*)0);
701 }
702 if (gpa_protocol_aliases) {
703 g_hash_table_destroy(gpa_protocol_aliases);
704 gpa_protocol_aliases = NULL((void*)0);
705 }
706 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
707 last_field_name = NULL((void*)0);
708
709 while (protocols) {
710 protocol = (protocol_t *)protocols->data;
711 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 711
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 711, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 711, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
712 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 712, "protocol->proto_id == hfinfo->id"
))))
;
713
714 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
715 if (protocol->parent_proto_id != -1) {
716 // pino protocol
717 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 717, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
718 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 718, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
719 } else {
720 if (protocol->fields) {
721 g_ptr_array_free(protocol->fields, true1);
722 }
723 g_list_free(protocol->heur_list);
724 }
725 protocols = g_list_remove(protocols, protocol);
726 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
727 }
728
729 if (proto_names) {
730 g_hash_table_destroy(proto_names);
731 proto_names = NULL((void*)0);
732 }
733
734 if (proto_short_names) {
735 g_hash_table_destroy(proto_short_names);
736 proto_short_names = NULL((void*)0);
737 }
738
739 if (proto_filter_names) {
740 g_hash_table_destroy(proto_filter_names);
741 proto_filter_names = NULL((void*)0);
742 }
743
744 if (proto_reserved_filter_names) {
745 g_hash_table_destroy(proto_reserved_filter_names);
746 proto_reserved_filter_names = NULL((void*)0);
747 }
748
749 if (gpa_hfinfo.allocated_len) {
750 gpa_hfinfo.len = 0;
751 gpa_hfinfo.allocated_len = 0;
752 g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1
)) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo
.hfi), 0)) : (g_free) (gpa_hfinfo.hfi)
;
753 gpa_hfinfo.hfi = NULL((void*)0);
754 }
755
756 if (deregistered_fields) {
757 g_ptr_array_free(deregistered_fields, true1);
758 deregistered_fields = NULL((void*)0);
759 }
760
761 if (deregistered_data) {
762 g_ptr_array_free(deregistered_data, true1);
763 deregistered_data = NULL((void*)0);
764 }
765
766 if (deregistered_slice) {
767 g_ptr_array_free(deregistered_slice, true1);
768 deregistered_slice = NULL((void*)0);
769 }
770
771 g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) -
1)) ? g_free_sized (tree_is_expanded, __builtin_object_size (
(tree_is_expanded), 0)) : (g_free) (tree_is_expanded)
;
772 tree_is_expanded = NULL((void*)0);
773
774 if (prefixes)
775 g_hash_table_destroy(prefixes);
776
777 if (saved_dir_queue != NULL((void*)0)) {
778 g_queue_clear_full(saved_dir_queue, g_free);
779 g_queue_free(saved_dir_queue);
780 saved_dir_queue = NULL((void*)0);
781 }
782}
783
784void
785proto_cleanup(void)
786{
787 proto_free_deregistered_fields();
788 proto_cleanup_base();
789
790 g_slist_free(dissector_plugins);
791 dissector_plugins = NULL((void*)0);
792}
793
794static bool_Bool
795ws_pushd(const char* dir)
796{
797 //Save the current working directory
798 const char* save_wd = get_current_working_dir();
799 if (save_wd != NULL((void*)0))
800 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
801
802 //Change to the new one
803#ifdef _WIN32
804 SetCurrentDirectory(utf_8to16(dir));
805 return true1;
806#else
807 return (chdir(dir) == 0);
808#endif
809}
810
811static bool_Bool
812ws_popd(void)
813{
814 int ret = 0;
815 char* saved_wd = g_queue_pop_head(saved_dir_queue);
816 if (saved_wd == NULL((void*)0))
817 return false0;
818
819 //Restore the previous one
820#ifdef _WIN32
821 SetCurrentDirectory(utf_8to16(saved_wd));
822#else
823 ret = chdir(saved_wd);
824#endif
825 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
826 return (ret == 0);
827}
828
829void
830proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
831{
832 if (ws_pushd(dir))
833 {
834 func(param);
835 ws_popd();
836 }
837}
838
839static bool_Bool
840// NOLINTNEXTLINE(misc-no-recursion)
841proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
842 void *data)
843{
844 proto_node *pnode = tree;
845 proto_node *child;
846 proto_node *current;
847
848 if (func(pnode, data))
849 return true1;
850
851 child = pnode->first_child;
852 while (child != NULL((void*)0)) {
853 /*
854 * The routine we call might modify the child, e.g. by
855 * freeing it, so we get the child's successor before
856 * calling that routine.
857 */
858 current = child;
859 child = current->next;
860 // We recurse here, but we're limited by prefs.gui_max_tree_depth
861 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
862 return true1;
863 }
864
865 return false0;
866}
867
868void
869proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
870 void *data)
871{
872 proto_node *node = tree;
873 proto_node *current;
874
875 if (!node)
876 return;
877
878 node = node->first_child;
879 while (node != NULL((void*)0)) {
880 current = node;
881 node = current->next;
882 func((proto_tree *)current, data);
883 }
884}
885
886static void
887free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
888{
889 GPtrArray *ptrs = (GPtrArray *)value;
890 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
891 header_field_info *hfinfo;
892
893 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 893, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 893, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 893, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
894 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
895 /* when a field is referenced by a filter this also
896 affects the refcount for the parent protocol so we need
897 to adjust the refcount for the parent as well
898 */
899 if (hfinfo->parent != -1) {
900 header_field_info *parent_hfinfo;
901 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 901
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 901, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 901, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
902 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
903 }
904 hfinfo->ref_type = HF_REF_TYPE_NONE;
905 }
906
907 g_ptr_array_free(ptrs, true1);
908}
909
910static void
911proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
912{
913 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
914
915 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
916
917 if (finfo) {
918 // The fvalue_t structure was allocated using fvalue_new_pool()
919 // (see new_field_info()) and will be reclaimed when the pool is
920 // freed, so we only release the type-specific data it owns here.
921 fvalue_cleanup(finfo->value);
922 finfo->value = NULL((void*)0);
923 }
924}
925
926void
927proto_tree_reset(proto_tree *tree)
928{
929 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
930
931 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
932
933 /* free tree data */
934 if (tree_data->interesting_hfids) {
935 /* Free all the GPtrArray's in the interesting_hfids hash. */
936 g_hash_table_foreach(tree_data->interesting_hfids,
937 free_GPtrArray_value, NULL((void*)0));
938
939 /* And then remove all values. */
940 g_hash_table_remove_all(tree_data->interesting_hfids);
941 }
942
943 /* Reset track of the number of children */
944 tree_data->count = 0;
945
946 /* Reset our loop checks */
947 tree_data->idle_count_ds_tvb = NULL((void*)0);
948 tree_data->max_start = 0;
949 tree_data->start_idle_count = 0;
950
951 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
952}
953
954/* frees the resources that the dissection a proto_tree uses */
955void
956proto_tree_free(proto_tree *tree)
957{
958 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
959
960 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
961
962 /* free tree data */
963 if (tree_data->interesting_hfids) {
964 /* Free all the GPtrArray's in the interesting_hfids hash. */
965 g_hash_table_foreach(tree_data->interesting_hfids,
966 free_GPtrArray_value, NULL((void*)0));
967
968 /* And then destroy the hash. */
969 g_hash_table_destroy(tree_data->interesting_hfids);
970 }
971
972 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
973
974 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
975}
976
977/* Is the parsing being done for a visible proto_tree or an invisible one?
978 * By setting this correctly, the proto_tree creation is sped up by not
979 * having to call vsnprintf and copy strings around.
980 */
981bool_Bool
982proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
983{
984 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
985
986 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
987
988 return old_visible;
989}
990
991void
992proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
993{
994 if (tree)
995 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
996}
997
998/* Assume dissector set only its protocol fields.
999 This function is called by dissectors and allows the speeding up of filtering
1000 in wireshark; if this function returns false it is safe to reset tree to NULL
1001 and thus skip calling most of the expensive proto_tree_add_...()
1002 functions.
1003 If the tree is visible we implicitly assume the field is referenced.
1004*/
1005bool_Bool
1006proto_field_is_referenced(proto_tree *tree, int proto_id)
1007{
1008 register header_field_info *hfinfo;
1009
1010
1011 if (!tree)
1012 return false0;
1013
1014 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1015 return true1;
1016
1017 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1017, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1017,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1017, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1018 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1019 return true1;
1020
1021 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1022 return true1;
1023
1024 return false0;
1025}
1026
1027
1028/* Finds a record in the hfinfo array by id. */
1029header_field_info *
1030proto_registrar_get_nth(unsigned hfindex)
1031{
1032 register header_field_info *hfinfo;
1033
1034 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1034, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1034,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1034, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1035 return hfinfo;
1036}
1037
1038
1039/* Prefix initialization
1040 * this allows for a dissector to register a display filter name prefix
1041 * so that it can delay the initialization of the hf array as long as
1042 * possible.
1043 */
1044
1045/* compute a hash for the part before the dot of a display filter */
1046static unsigned
1047prefix_hash (const void *key) {
1048 /* end the string at the dot and compute its hash */
1049 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1050 char* c = copy;
1051 unsigned tmp;
1052
1053 for (; *c; c++) {
1054 if (*c == '.') {
1055 *c = 0;
1056 break;
1057 }
1058 }
1059
1060 tmp = wmem_str_hash(copy);
1061 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1062 return tmp;
1063}
1064
1065/* are both strings equal up to the end or the dot? */
1066static gboolean
1067prefix_equal (const void *ap, const void *bp) {
1068 const char* a = (const char *)ap;
1069 const char* b = (const char *)bp;
1070
1071 do {
1072 char ac = *a++;
1073 char bc = *b++;
1074
1075 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1076
1077 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1078 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1079
1080 if (ac != bc) return FALSE(0);
1081 } while (1);
1082
1083 return FALSE(0);
1084}
1085
1086/* Register a new prefix for "delayed" initialization of field arrays */
1087void
1088proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1089 if (! prefixes ) {
1090 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1091 }
1092
1093 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1094}
1095
1096/* helper to call all prefix initializers */
1097static gboolean
1098initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1099 ((prefix_initializer_t)v)((const char *)k);
1100 return TRUE(!(0));
1101}
1102
1103/** Initialize every remaining uninitialized prefix. */
1104void
1105proto_initialize_all_prefixes(void) {
1106 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1107}
1108
1109/* Finds a record in the hfinfo array by name.
1110 * If it fails to find it in the already registered fields,
1111 * it tries to find and call an initializer in the prefixes
1112 * table and if so it looks again.
1113 */
1114
1115header_field_info *
1116proto_registrar_get_byname(const char *field_name)
1117{
1118 header_field_info *hfinfo;
1119 prefix_initializer_t pi;
1120
1121 if (!field_name)
1122 return NULL((void*)0);
1123
1124 if (g_strcmp0(field_name, last_field_name) == 0) {
1125 return last_hfinfo;
1126 }
1127
1128 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1129
1130 if (hfinfo) {
1131 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1132 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1133 last_hfinfo = hfinfo;
1134 return hfinfo;
1135 }
1136
1137 if (!prefixes)
1138 return NULL((void*)0);
1139
1140 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1141 pi(field_name);
1142 g_hash_table_remove(prefixes, field_name);
1143 } else {
1144 return NULL((void*)0);
1145 }
1146
1147 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1148
1149 if (hfinfo) {
1150 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1151 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1152 last_hfinfo = hfinfo;
1153 }
1154 return hfinfo;
1155}
1156
1157header_field_info*
1158proto_registrar_get_byalias(const char *alias_name)
1159{
1160 if (!alias_name) {
1161 return NULL((void*)0);
1162 }
1163
1164 /* Find our aliased protocol. */
1165 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1166 char *dot = strchr(an_copy, '.');
1167 if (dot) {
1168 *dot = '\0';
1169 }
1170 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1171 if (!proto_pfx) {
1172 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1173 return NULL((void*)0);
1174 }
1175
1176 /* Construct our aliased field and look it up. */
1177 GString *filter_name = g_string_new(proto_pfx);
1178 if (dot) {
1179 g_string_append_printf(filter_name, ".%s", dot+1);
1180 }
1181 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1182 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1183 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1184
1185 return hfinfo;
1186}
1187
1188int
1189proto_registrar_get_id_byname(const char *field_name)
1190{
1191 header_field_info *hfinfo;
1192
1193 hfinfo = proto_registrar_get_byname(field_name);
1194
1195 if (!hfinfo)
1196 return -1;
1197
1198 return hfinfo->id;
1199}
1200
1201static int
1202label_strcat_flags(const header_field_info *hfinfo)
1203{
1204 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1205 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1206
1207 return 0;
1208}
1209
1210static char *
1211format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1212 const uint8_t *bytes, unsigned length, size_t max_str_len)
1213{
1214 char *str = NULL((void*)0);
1215 const uint8_t *p;
1216 bool_Bool is_printable;
1217
1218 if (bytes) {
1219 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1220 /*
1221 * If all bytes are valid and printable UTF-8, show the
1222 * bytes as a string - in quotes to indicate that it's
1223 * a string.
1224 */
1225 if (isprint_utf8_string((const char*)bytes, length)) {
1226 str = wmem_strdup_printf(scope, "\"%.*s\"",
1227 (int)length, bytes);
1228 return str;
1229 }
1230 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1231 /*
1232 * Check whether all bytes are printable.
1233 */
1234 is_printable = true1;
1235 for (p = bytes; p < bytes+length; p++) {
1236 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1237 /* Not printable. */
1238 is_printable = false0;
1239 break;
1240 }
1241 }
1242
1243 /*
1244 * If all bytes are printable ASCII, show the bytes
1245 * as a string - in quotes to indicate that it's
1246 * a string.
1247 */
1248 if (is_printable) {
1249 str = wmem_strdup_printf(scope, "\"%.*s\"",
1250 (int)length, bytes);
1251 return str;
1252 }
1253 }
1254
1255 /*
1256 * Either it's not printable ASCII, or we don't care whether
1257 * it's printable ASCII; show it as hex bytes.
1258 */
1259 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1260 case SEP_DOT:
1261 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1262 break;
1263 case SEP_DASH:
1264 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1265 break;
1266 case SEP_COLON:
1267 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1268 break;
1269 case SEP_SPACE:
1270 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1271 break;
1272 case BASE_NONE:
1273 default:
1274 if (prefs.display_byte_fields_with_spaces) {
1275 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1276 } else {
1277 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1278 }
1279 break;
1280 }
1281 }
1282 else {
1283 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1284 str = wmem_strdup(scope, "<none>");
1285 } else {
1286 str = wmem_strdup(scope, "<MISSING>");
1287 }
1288 }
1289 return str;
1290}
1291
1292static char *
1293format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1294 const uint8_t *bytes, unsigned length)
1295{
1296 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1297}
1298
1299static void
1300ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1301{
1302 subtree_lvl *pushed_tree;
1303
1304 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1304, "ptvc->pushed_tree_max <= 256-8"))))
;
1305 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1306
1307 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1308 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1308, "pushed_tree != ((void*)0)"
))))
;
1309 ptvc->pushed_tree = pushed_tree;
1310}
1311
1312static void
1313ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1314{
1315 ptvc->pushed_tree = NULL((void*)0);
1316 ptvc->pushed_tree_max = 0;
1317 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1317, "ptvc->pushed_tree_index == 0"
))))
;
1318 ptvc->pushed_tree_index = 0;
1319}
1320
1321/* Allocates an initializes a ptvcursor_t with 3 variables:
1322 * proto_tree, tvbuff, and offset. */
1323ptvcursor_t *
1324ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1325{
1326 ptvcursor_t *ptvc;
1327
1328 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1329 ptvc->scope = scope;
1330 ptvc->tree = tree;
1331 ptvc->tvb = tvb;
1332 ptvc->offset = offset;
1333 ptvc->pushed_tree = NULL((void*)0);
1334 ptvc->pushed_tree_max = 0;
1335 ptvc->pushed_tree_index = 0;
1336 return ptvc;
1337}
1338
1339
1340/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1341void
1342ptvcursor_free(ptvcursor_t *ptvc)
1343{
1344 ptvcursor_free_subtree_levels(ptvc);
1345 wmem_free(ptvc->scope, ptvc);
1346}
1347
1348/* Returns tvbuff. */
1349tvbuff_t *
1350ptvcursor_tvbuff(ptvcursor_t *ptvc)
1351{
1352 return ptvc->tvb;
1353}
1354
1355/* Returns current offset. */
1356unsigned
1357ptvcursor_current_offset(ptvcursor_t *ptvc)
1358{
1359 return ptvc->offset;
1360}
1361
1362proto_tree *
1363ptvcursor_tree(ptvcursor_t *ptvc)
1364{
1365 if (!ptvc)
1366 return NULL((void*)0);
1367
1368 return ptvc->tree;
1369}
1370
1371void
1372ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1373{
1374 ptvc->tree = tree;
1375}
1376
1377/* creates a subtree, sets it as the working tree and pushes the old working tree */
1378proto_tree *
1379ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1380{
1381 subtree_lvl *subtree;
1382 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1383 ptvcursor_new_subtree_levels(ptvc);
1384
1385 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1386 subtree->tree = ptvc->tree;
1387 subtree->it= NULL((void*)0);
1388 ptvc->pushed_tree_index++;
1389 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1390}
1391
1392/* pops a subtree */
1393void
1394ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1395{
1396 subtree_lvl *subtree;
1397
1398 if (ptvc->pushed_tree_index <= 0)
1399 return;
1400
1401 ptvc->pushed_tree_index--;
1402 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1403 if (subtree->it != NULL((void*)0))
1404 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1405
1406 ptvc->tree = subtree->tree;
1407}
1408
1409/* saves the current tvb offset and the item in the current subtree level */
1410static void
1411ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1412{
1413 subtree_lvl *subtree;
1414
1415 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1415, "ptvc->pushed_tree_index > 0"
))))
;
1416
1417 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1418 subtree->it = it;
1419 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1420}
1421
1422/* Creates a subtree and adds it to the cursor as the working tree but does not
1423 * save the old working tree */
1424proto_tree *
1425ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1426{
1427 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1428 return ptvc->tree;
1429}
1430
1431static proto_tree *
1432ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1433{
1434 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1435 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1436 ptvcursor_subtree_set_item(ptvc, it);
1437 return ptvcursor_tree(ptvc);
1438}
1439
1440/* Add an item to the tree and create a subtree
1441 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1442 * In this case, when the subtree will be closed, the parent item length will
1443 * be equal to the advancement of the cursor since the creation of the subtree.
1444 */
1445proto_tree *
1446ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1447 const unsigned encoding, int ett_subtree)
1448{
1449 proto_item *it;
1450
1451 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1452 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1453}
1454
1455static proto_item *
1456proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1457
1458/* Add a text node to the tree and create a subtree
1459 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1460 * In this case, when the subtree will be closed, the item length will be equal
1461 * to the advancement of the cursor since the creation of the subtree.
1462 */
1463proto_tree *
1464ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1465 int ett_subtree, const char *format, ...)
1466{
1467 proto_item *pi;
1468 va_list ap;
1469 header_field_info *hfinfo;
1470 proto_tree *tree;
1471
1472 tree = ptvcursor_tree(ptvc);
1473
1474 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1475
1476 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1476
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1476, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1476, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1476, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1477
1478 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1479 ptvcursor_current_offset(ptvc), length);
1480
1481 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1481, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1482
1483 va_start(ap, format)__builtin_va_start(ap, format);
1484 proto_tree_set_representation(pi, format, ap);
1485 va_end(ap)__builtin_va_end(ap);
1486
1487 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1488}
1489
1490/* Add a text-only node, leaving it to our caller to fill the text in */
1491static proto_item *
1492proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1493{
1494 proto_item *pi;
1495
1496 if (tree == NULL((void*)0))
1497 return NULL((void*)0);
1498
1499 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1500
1501 return pi;
1502}
1503
1504/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1505proto_item *
1506proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1507 const char *format, ...)
1508{
1509 proto_item *pi;
1510 va_list ap;
1511 header_field_info *hfinfo;
1512
1513 tvb_ensure_bytes_exist(tvb, start, length);
1514
1515 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1516
1517 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1517
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1517, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1517, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1517, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1518
1519 pi = proto_tree_add_text_node(tree, tvb, start, length);
1520
1521 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1521, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1522
1523 va_start(ap, format)__builtin_va_start(ap, format);
1524 proto_tree_set_representation(pi, format, ap);
1525 va_end(ap)__builtin_va_end(ap);
1526
1527 return pi;
1528}
1529
1530/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1531proto_item *
1532proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1533 unsigned length, const char *format, va_list ap)
1534{
1535 proto_item *pi;
1536 header_field_info *hfinfo;
1537
1538 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1539 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1540 * the length to be what's in the tvbuff if length is -1, and the
1541 * minimum of length and what's in the tvbuff if not.
1542 */
1543
1544 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1545
1546 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1546
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1546, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1546, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1546, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1547
1548 pi = proto_tree_add_text_node(tree, tvb, start, length);
1549
1550 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1550, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1551
1552 proto_tree_set_representation(pi, format, ap);
1553
1554 return pi;
1555}
1556
1557/* Add a text-only node that creates a subtree underneath.
1558 */
1559proto_tree *
1560proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1561{
1562 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1563}
1564
1565/* Add a text-only node that creates a subtree underneath.
1566 */
1567proto_tree *
1568proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1569{
1570 proto_tree *pt;
1571 proto_item *pi;
1572 va_list ap;
1573
1574 if (length == -1) {
1575 length = tvb_captured_length_remaining(tvb, start);
1576 }
1577
1578 va_start(ap, format)__builtin_va_start(ap, format);
1579 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1580 va_end(ap)__builtin_va_end(ap);
1581
1582 if (tree_item != NULL((void*)0))
1583 *tree_item = pi;
1584
1585 pt = proto_item_add_subtree(pi, idx);
1586
1587 return pt;
1588}
1589
1590/* Add a text-only node for debugging purposes. The caller doesn't need
1591 * to worry about tvbuff, start, or length. Debug message gets sent to
1592 * STDOUT, too */
1593proto_item *
1594proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1595{
1596 proto_item *pi;
1597 va_list ap;
1598
1599 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1600
1601 if (pi) {
1602 va_start(ap, format)__builtin_va_start(ap, format);
1603 proto_tree_set_representation(pi, format, ap);
1604 va_end(ap)__builtin_va_end(ap);
1605 }
1606 va_start(ap, format)__builtin_va_start(ap, format);
1607 vprintf(format, ap);
1608 va_end(ap)__builtin_va_end(ap);
1609 printf("\n");
1610
1611 return pi;
1612}
1613
1614proto_item *
1615proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1616{
1617 proto_item *pi;
1618 header_field_info *hfinfo;
1619
1620 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1621
1622 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1622
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1622, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1622, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1622, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1623
1624 pi = proto_tree_add_text_node(tree, tvb, start, length);
1625
1626 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1626, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1627
1628 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1629
1630 return pi;
1631}
1632
1633proto_item *
1634proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1635{
1636 proto_item *pi;
1637 header_field_info *hfinfo;
1638 char *str;
1639
1640 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1641
1642 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1642
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1642, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1642, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1642, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1643
1644 pi = proto_tree_add_text_node(tree, tvb, start, length);
1645
1646 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1646, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1647
1648 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1649 proto_item_set_text(pi, "%s", str);
1650 wmem_free(NULL((void*)0), str);
1651
1652 return pi;
1653}
1654
1655void proto_report_dissector_bug(const char *format, ...)
1656{
1657 va_list args;
1658
1659 if (wireshark_abort_on_dissector_bug) {
1660 /*
1661 * Try to have the error message show up in the crash
1662 * information.
1663 */
1664 va_start(args, format)__builtin_va_start(args, format);
1665 ws_vadd_crash_info(format, args);
1666 va_end(args)__builtin_va_end(args);
1667
1668 /*
1669 * Print the error message.
1670 */
1671 va_start(args, format)__builtin_va_start(args, format);
1672 vfprintf(stderrstderr, format, args);
1673 va_end(args)__builtin_va_end(args);
1674 putc('\n', stderrstderr);
1675
1676 /*
1677 * And crash.
1678 */
1679 abort();
1680 } else {
1681 va_start(args, format)__builtin_va_start(args, format);
1682 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1683 va_end(args)__builtin_va_end(args);
1684 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1684
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1685 }
1686}
1687
1688/* We could probably get away with changing is_error to a minimum length value. */
1689static void
1690report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1691{
1692 if (is_error) {
1693 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1694 } else {
1695 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1696 }
1697
1698 if (is_error) {
1699 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1700 }
1701}
1702
1703static uint32_t
1704get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1705{
1706 uint32_t value;
1707 bool_Bool length_error;
1708
1709 switch (length) {
1710
1711 case 1:
1712 value = tvb_get_uint8(tvb, offset);
1713 if (encoding & ENC_ZIGBEE0x40000000) {
1714 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1715 value = 0;
1716 }
1717 }
1718 break;
1719
1720 case 2:
1721 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1722 : tvb_get_ntohs(tvb, offset);
1723 if (encoding & ENC_ZIGBEE0x40000000) {
1724 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1725 value = 0;
1726 }
1727 }
1728 break;
1729
1730 case 3:
1731 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1732 : tvb_get_ntoh24(tvb, offset);
1733 break;
1734
1735 case 4:
1736 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1737 : tvb_get_ntohl(tvb, offset);
1738 break;
1739
1740 default:
1741 if (length < 1) {
1742 length_error = true1;
1743 value = 0;
1744 } else {
1745 length_error = false0;
1746 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1747 : tvb_get_ntohl(tvb, offset);
1748 }
1749 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1750 break;
1751 }
1752 return value;
1753}
1754
1755static inline uint64_t
1756get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1757{
1758 uint64_t value;
1759
1760 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1761
1762 if (length < 1 || length > 8) {
1763 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1764 }
1765
1766 return value;
1767}
1768
1769static int32_t
1770get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1771{
1772 int32_t value;
1773 bool_Bool length_error;
1774
1775 switch (length) {
1776
1777 case 1:
1778 value = tvb_get_int8(tvb, offset);
1779 break;
1780
1781 case 2:
1782 value = encoding ? tvb_get_letohis(tvb, offset)
1783 : tvb_get_ntohis(tvb, offset);
1784 break;
1785
1786 case 3:
1787 value = encoding ? tvb_get_letohi24(tvb, offset)
1788 : tvb_get_ntohi24(tvb, offset);
1789 break;
1790
1791 case 4:
1792 value = encoding ? tvb_get_letohil(tvb, offset)
1793 : tvb_get_ntohil(tvb, offset);
1794 break;
1795
1796 default:
1797 if (length < 1) {
1798 length_error = true1;
1799 value = 0;
1800 } else {
1801 length_error = false0;
1802 value = encoding ? tvb_get_letohil(tvb, offset)
1803 : tvb_get_ntohil(tvb, offset);
1804 }
1805 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1806 break;
1807 }
1808 return value;
1809}
1810
1811/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1812 * be cast-able as a int64_t. This is weird, but what the code has always done.
1813 */
1814static inline uint64_t
1815get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1816{
1817 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1818
1819 switch (length) {
1820 case 7:
1821 value = ws_sign_ext64(value, 56);
1822 break;
1823 case 6:
1824 value = ws_sign_ext64(value, 48);
1825 break;
1826 case 5:
1827 value = ws_sign_ext64(value, 40);
1828 break;
1829 case 4:
1830 value = ws_sign_ext64(value, 32);
1831 break;
1832 case 3:
1833 value = ws_sign_ext64(value, 24);
1834 break;
1835 case 2:
1836 value = ws_sign_ext64(value, 16);
1837 break;
1838 case 1:
1839 value = ws_sign_ext64(value, 8);
1840 break;
1841 }
1842
1843 return value;
1844}
1845
1846/* For FT_STRING */
1847static inline const uint8_t *
1848get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1849 int length, unsigned *ret_length, const unsigned encoding)
1850{
1851 if (length == -1) {
1852 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1853 } else {
1854 *ret_length = length;
1855 }
1856 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1857}
1858
1859/* For FT_STRINGZ */
1860static inline const uint8_t *
1861get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1862 unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1863{
1864 const uint8_t *value;
1865
1866 if (length < -1) {
1867 report_type_length_mismatch(tree, "a string", length, true1);
1868 }
1869
1870 /* XXX - Ideally, every "null-terminated string which fits into a
1871 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1872 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1873 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1874 * as unknown length as well (since there is a trailing '\0', the real
1875 * length is never zero), allowing switching to unsigned lengths.
1876 */
1877 if (length == -1) {
1878 /* This can throw an exception */
1879 value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1880 } else {
1881 /* In this case, length signifies the length of the string.
1882 *
1883 * This could either be a null-padded string, which doesn't
1884 * necessarily have a '\0' at the end, or a null-terminated
1885 * string, with a trailing '\0'. (Yes, there are cases
1886 * where you have a string that's both counted and null-
1887 * terminated.)
1888 *
1889 * In the first case, we must allocate a buffer of length
1890 * "length+1", to make room for a trailing '\0'.
1891 *
1892 * In the second case, we don't assume that there is a
1893 * trailing '\0' there, as the packet might be malformed.
1894 * (XXX - should we throw an exception if there's no
1895 * trailing '\0'?) Therefore, we allocate a buffer of
1896 * length "length+1", and put in a trailing '\0', just to
1897 * be safe.
1898 *
1899 * (XXX - this would change if we made string values counted
1900 * rather than null-terminated.)
1901 */
1902 *ret_length = length;
1903 value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1904 }
1905 return value;
1906}
1907
1908/* For FT_UINT_STRING */
1909static inline const uint8_t *
1910get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1911 tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1912 const unsigned encoding)
1913{
1914 uint32_t n;
1915 const uint8_t *value;
1916
1917 /* I believe it's ok if this is called with a NULL tree */
1918 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1919 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1920 *ret_length = length + n;
1921 return value;
1922}
1923
1924/* For FT_STRINGZPAD */
1925static inline const uint8_t *
1926get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1927 int length, unsigned *ret_length, const unsigned encoding)
1928{
1929 /*
1930 * XXX - currently, string values are null-
1931 * terminated, so a "zero-padded" string
1932 * isn't special. If we represent string
1933 * values as something that includes a counted
1934 * array of bytes, we'll need to strip the
1935 * trailing NULs.
1936 */
1937 if (length == -1) {
1938 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1939 } else {
1940 *ret_length = length;
1941 }
1942 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1943}
1944
1945/* For FT_STRINGZTRUNC */
1946static inline const uint8_t *
1947get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1948 int length, unsigned *ret_length, const unsigned encoding)
1949{
1950 /*
1951 * XXX - currently, string values are null-
1952 * terminated, so a "zero-truncated" string
1953 * isn't special. If we represent string
1954 * values as something that includes a counted
1955 * array of bytes, we'll need to strip everything
1956 * starting with the terminating NUL.
1957 */
1958 if (length == -1) {
1959 *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1960 } else {
1961 *ret_length = length;
1962 }
1963 return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1964}
1965
1966/*
1967 * Deltas between the epochs for various non-UN*X time stamp formats and
1968 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1969 * stamp format.
1970 */
1971
1972/*
1973 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1974 * XXX - if it's OK if this is unsigned, can we just use
1975 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1976 */
1977#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1978
1979/*
1980 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1981 */
1982#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1983
1984/* this can be called when there is no tree, so tree may be null */
1985static void
1986get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1987 const int length, const unsigned encoding, nstime_t *time_stamp,
1988 const bool_Bool is_relative)
1989{
1990 uint32_t tmpsecs;
1991 uint64_t tmp64secs;
1992 uint64_t todusecs;
1993
1994 switch (encoding) {
1995
1996 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1997 /*
1998 * If the length is 16, 8-byte seconds, followed
1999 * by 8-byte fractional time in nanoseconds,
2000 * both big-endian.
2001 *
2002 * If the length is 12, 8-byte seconds, followed
2003 * by 4-byte fractional time in nanoseconds,
2004 * both big-endian.
2005 *
2006 * If the length is 8, 4-byte seconds, followed
2007 * by 4-byte fractional time in nanoseconds,
2008 * both big-endian.
2009 *
2010 * For absolute times, the seconds are seconds
2011 * since the UN*X epoch.
2012 */
2013 if (length == 16) {
2014 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2015 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2016 } else if (length == 12) {
2017 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2018 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2019 } else if (length == 8) {
2020 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2021 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2022 } else if (length == 4) {
2023 /*
2024 * Backwards compatibility.
2025 * ENC_TIME_SECS_NSECS is 0; using
2026 * ENC_BIG_ENDIAN by itself with a 4-byte
2027 * time-in-seconds value was done in the
2028 * past.
2029 */
2030 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2031 time_stamp->nsecs = 0;
2032 } else {
2033 time_stamp->secs = 0;
2034 time_stamp->nsecs = 0;
2035 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2036 }
2037 break;
2038
2039 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2040 /*
2041 * If the length is 16, 8-byte seconds, followed
2042 * by 8-byte fractional time in nanoseconds,
2043 * both little-endian.
2044 *
2045 * If the length is 12, 8-byte seconds, followed
2046 * by 4-byte fractional time in nanoseconds,
2047 * both little-endian.
2048 *
2049 * If the length is 8, 4-byte seconds, followed
2050 * by 4-byte fractional time in nanoseconds,
2051 * both little-endian.
2052 *
2053 * For absolute times, the seconds are seconds
2054 * since the UN*X epoch.
2055 */
2056 if (length == 16) {
2057 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2058 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2059 } else if (length == 12) {
2060 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2061 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2062 } else if (length == 8) {
2063 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2064 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2065 } else if (length == 4) {
2066 /*
2067 * Backwards compatibility.
2068 * ENC_TIME_SECS_NSECS is 0; using
2069 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2070 * time-in-seconds value was done in the
2071 * past.
2072 */
2073 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2074 time_stamp->nsecs = 0;
2075 } else {
2076 time_stamp->secs = 0;
2077 time_stamp->nsecs = 0;
2078 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2079 }
2080 break;
2081
2082 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2083 /*
2084 * NTP time stamp, big-endian.
2085 * Only supported for absolute times.
2086 */
2087 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2087, "!is_relative"
))))
;
2088
2089 /* We need a temporary variable here so the unsigned math
2090 * works correctly (for years > 2036 according to RFC 2030
2091 * chapter 3).
2092 *
2093 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2094 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2095 * If bit 0 is not set, the time is in the range 2036-2104 and
2096 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2097 */
2098 tmpsecs = tvb_get_ntohl(tvb, start);
2099 if ((tmpsecs & 0x80000000) != 0)
2100 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2101 else
2102 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2103
2104 if (length == 8) {
2105 tmp64secs = tvb_get_ntoh64(tvb, start);
2106 if (tmp64secs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 time_stamp->nsecs = 0;
2110 } else {
2111 /*
2112 * Convert 1/2^32s of a second to
2113 * nanoseconds.
2114 */
2115 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2116 }
2117 } else if (length == 4) {
2118 /*
2119 * Backwards compatibility.
2120 */
2121 if (tmpsecs == 0) {
2122 //This is "NULL" time
2123 time_stamp->secs = 0;
2124 }
2125 time_stamp->nsecs = 0;
2126 } else {
2127 time_stamp->secs = 0;
2128 time_stamp->nsecs = 0;
2129 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2130 }
2131 break;
2132
2133 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2134 /*
2135 * NTP time stamp, little-endian.
2136 * Only supported for absolute times.
2137 *
2138 * NTP doesn't use this, because it's an Internet format
2139 * and hence big-endian. Any implementation must decide
2140 * whether the NTP timestamp is a 64-bit unsigned fixed
2141 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2142 * with a 32-bit unsigned seconds field followed by a
2143 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2144 * the previous two).
2145 *
2146 * XXX: We do the latter, but no dissector uses this format.
2147 * OTOH, ERF timestamps do the former, so perhaps we
2148 * should switch the interpretation so that packet-erf.c
2149 * could use this directly? (ENC_TIME_RTPS is this 64-bit
2150 * struct with two 32-bit fields, but with the UN*X epoch.)
2151 */
2152 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2152, "!is_relative"
))))
;
2153
2154 /* We need a temporary variable here so the unsigned math
2155 * works correctly (for years > 2036 according to RFC 2030
2156 * chapter 3).
2157 *
2158 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2159 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2160 * If bit 0 is not set, the time is in the range 2036-2104 and
2161 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2162 */
2163 tmpsecs = tvb_get_letohl(tvb, start);
2164 if ((tmpsecs & 0x80000000) != 0)
2165 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2166 else
2167 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2168
2169 if (length == 8) {
2170 tmp64secs = tvb_get_letoh64(tvb, start);
2171 if (tmp64secs == 0) {
2172 //This is "NULL" time
2173 time_stamp->secs = 0;
2174 time_stamp->nsecs = 0;
2175 } else {
2176 /*
2177 * Convert 1/2^32s of a second to
2178 * nanoseconds.
2179 */
2180 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2181 }
2182 } else if (length == 4) {
2183 /*
2184 * Backwards compatibility.
2185 */
2186 if (tmpsecs == 0) {
2187 //This is "NULL" time
2188 time_stamp->secs = 0;
2189 }
2190 time_stamp->nsecs = 0;
2191 } else {
2192 time_stamp->secs = 0;
2193 time_stamp->nsecs = 0;
2194 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2195 }
2196 break;
2197
2198 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2199 /*
2200 * S/3x0 and z/Architecture TOD clock time stamp,
2201 * big-endian. The epoch is January 1, 1900,
2202 * 00:00:00 (proleptic?) UTC.
2203 *
2204 * Only supported for absolute times.
2205 */
2206 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2206, "!is_relative"
))))
;
2207 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2207, "length == 8"
))))
;
2208
2209 if (length == 8) {
2210 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2211 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2212 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2213 } else {
2214 time_stamp->secs = 0;
2215 time_stamp->nsecs = 0;
2216 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2217 }
2218 break;
2219
2220 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2221 /*
2222 * S/3x0 and z/Architecture TOD clock time stamp,
2223 * little-endian. The epoch is January 1, 1900,
2224 * 00:00:00 (proleptic?) UTC.
2225 *
2226 * Only supported for absolute times.
2227 */
2228 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2228, "!is_relative"
))))
;
2229
2230 if (length == 8) {
2231 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2232 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2233 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2234 } else {
2235 time_stamp->secs = 0;
2236 time_stamp->nsecs = 0;
2237 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2238 }
2239 break;
2240
2241 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2242 /*
2243 * Time stamp using the same seconds/fraction format
2244 * as NTP, but with the origin of the time stamp being
2245 * the UNIX epoch rather than the NTP epoch; big-
2246 * endian.
2247 *
2248 * Only supported for absolute times.
2249 */
2250 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2250, "!is_relative"
))))
;
2251
2252 if (length == 8) {
2253 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2254 /*
2255 * Convert 1/2^32s of a second to nanoseconds.
2256 */
2257 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2258 } else {
2259 time_stamp->secs = 0;
2260 time_stamp->nsecs = 0;
2261 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2262 }
2263 break;
2264
2265 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2266 /*
2267 * Time stamp using the same seconds/fraction format
2268 * as NTP, but with the origin of the time stamp being
2269 * the UNIX epoch rather than the NTP epoch; little-
2270 * endian.
2271 *
2272 * Only supported for absolute times.
2273 *
2274 * The RTPS specification explicitly supports Little
2275 * Endian encoding. In one place, it states that its
2276 * Time_t representation "is the one defined by ...
2277 * RFC 1305", but in another explicitly defines it as
2278 * a struct consisting of an 32 bit unsigned seconds
2279 * field and a 32 bit unsigned fraction field, not a 64
2280 * bit fixed point, so we do that here.
2281 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2282 */
2283 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2283, "!is_relative"
))))
;
2284
2285 if (length == 8) {
2286 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2287 /*
2288 * Convert 1/2^32s of a second to nanoseconds.
2289 */
2290 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2291 } else {
2292 time_stamp->secs = 0;
2293 time_stamp->nsecs = 0;
2294 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2295 }
2296 break;
2297
2298 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2299 /*
2300 * MIP6 time stamp, big-endian.
2301 * A 64-bit unsigned integer field containing a timestamp. The
2302 * value indicates the number of seconds since January 1, 1970,
2303 * 00:00 UTC, by using a fixed point format. In this format, the
2304 * integer number of seconds is contained in the first 48 bits of
2305 * the field, and the remaining 16 bits indicate the number of
2306 * 1/65536 fractions of a second.
2307
2308 * Only supported for absolute times.
2309 */
2310 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2310, "!is_relative"
))))
;
2311
2312 if (length == 8) {
2313 /* We need a temporary variable here so the casting and fractions
2314 * of a second work correctly.
2315 */
2316 tmp64secs = tvb_get_ntoh48(tvb, start);
2317 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2318 tmpsecs <<= 16;
2319
2320 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2321 //This is "NULL" time
2322 time_stamp->secs = 0;
2323 time_stamp->nsecs = 0;
2324 } else {
2325 time_stamp->secs = (time_t)tmp64secs;
2326 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2327 }
2328 } else {
2329 time_stamp->secs = 0;
2330 time_stamp->nsecs = 0;
2331 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2332 }
2333 break;
2334
2335 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2336 /*
2337 * If the length is 16, 8-byte seconds, followed
2338 * by 8-byte fractional time in microseconds,
2339 * both big-endian.
2340 *
2341 * If the length is 12, 8-byte seconds, followed
2342 * by 4-byte fractional time in microseconds,
2343 * both big-endian.
2344 *
2345 * If the length is 8, 4-byte seconds, followed
2346 * by 4-byte fractional time in microseconds,
2347 * both big-endian.
2348 *
2349 * For absolute times, the seconds are seconds
2350 * since the UN*X epoch.
2351 */
2352 if (length == 16) {
2353 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2354 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2355 } else if (length == 12) {
2356 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2357 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2358 } else if (length == 8) {
2359 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2360 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2361 } else {
2362 time_stamp->secs = 0;
2363 time_stamp->nsecs = 0;
2364 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2365 }
2366 break;
2367
2368 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2369 /*
2370 * If the length is 16, 8-byte seconds, followed
2371 * by 8-byte fractional time in microseconds,
2372 * both little-endian.
2373 *
2374 * If the length is 12, 8-byte seconds, followed
2375 * by 4-byte fractional time in microseconds,
2376 * both little-endian.
2377 *
2378 * If the length is 8, 4-byte seconds, followed
2379 * by 4-byte fractional time in microseconds,
2380 * both little-endian.
2381 *
2382 * For absolute times, the seconds are seconds
2383 * since the UN*X epoch.
2384 */
2385 if (length == 16) {
2386 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2387 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2388 } else if (length == 12) {
2389 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2390 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2391 } else if (length == 8) {
2392 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2393 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2394 } else {
2395 time_stamp->secs = 0;
2396 time_stamp->nsecs = 0;
2397 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2398 }
2399 break;
2400
2401 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2402 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2403 /*
2404 * Seconds, 1 to 8 bytes.
2405 * For absolute times, it's seconds since the
2406 * UN*X epoch.
2407 */
2408 if (length >= 1 && length <= 8) {
2409 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2410 time_stamp->nsecs = 0;
2411 } else {
2412 time_stamp->secs = 0;
2413 time_stamp->nsecs = 0;
2414 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2415 }
2416 break;
2417
2418 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2419 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2420 /*
2421 * Milliseconds, 1 to 8 bytes.
2422 * For absolute times, it's milliseconds since the
2423 * UN*X epoch.
2424 */
2425 if (length >= 1 && length <= 8) {
2426 uint64_t msecs;
2427
2428 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2429 time_stamp->secs = (time_t)(msecs / 1000);
2430 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2431 } else {
2432 time_stamp->secs = 0;
2433 time_stamp->nsecs = 0;
2434 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2435 }
2436 break;
2437
2438 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2439 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2440 /*
2441 * Microseconds, 1 to 8 bytes.
2442 * For absolute times, it's microseconds since the
2443 * UN*X epoch.
2444 */
2445 if (length >= 1 && length <= 8) {
2446 uint64_t usecs;
2447
2448 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2449 time_stamp->secs = (time_t)(usecs / 1000000);
2450 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2451 } else {
2452 time_stamp->secs = 0;
2453 time_stamp->nsecs = 0;
2454 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2455 }
2456 break;
2457
2458 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2459 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2460 /*
2461 * nanoseconds, 1 to 8 bytes.
2462 * For absolute times, it's nanoseconds since the
2463 * UN*X epoch.
2464 */
2465
2466 if (length >= 1 && length <= 8) {
2467 uint64_t nsecs;
2468
2469 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2470 time_stamp->secs = (time_t)(nsecs / 1000000000);
2471 time_stamp->nsecs = (int)(nsecs % 1000000000);
2472 } else {
2473 time_stamp->secs = 0;
2474 time_stamp->nsecs = 0;
2475 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2476 }
2477 break;
2478
2479 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2480 /*
2481 * 1/64ths of a second since the UN*X epoch,
2482 * big-endian.
2483 *
2484 * Only supported for absolute times.
2485 */
2486 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2486, "!is_relative"
))))
;
2487
2488 if (length == 8) {
2489 /*
2490 * The upper 48 bits are seconds since the
2491 * UN*X epoch.
2492 */
2493 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2494 /*
2495 * The lower 16 bits are 1/2^16s of a second;
2496 * convert them to nanoseconds.
2497 *
2498 * XXX - this may give the impression of higher
2499 * precision than you actually get.
2500 */
2501 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2502 } else {
2503 time_stamp->secs = 0;
2504 time_stamp->nsecs = 0;
2505 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2506 }
2507 break;
2508
2509 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2510 /*
2511 * 1/64ths of a second since the UN*X epoch,
2512 * little-endian.
2513 *
2514 * Only supported for absolute times.
2515 */
2516 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2516, "!is_relative"
))))
;
2517
2518 if (length == 8) {
2519 /*
2520 * XXX - this is assuming that, if anybody
2521 * were ever to use this format - RFC 3971
2522 * doesn't, because that's an Internet
2523 * protocol, and those use network byte
2524 * order, i.e. big-endian - they'd treat it
2525 * as a 64-bit count of 1/2^16s of a second,
2526 * putting the upper 48 bits at the end.
2527 *
2528 * The lower 48 bits are seconds since the
2529 * UN*X epoch.
2530 */
2531 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2532 /*
2533 * The upper 16 bits are 1/2^16s of a second;
2534 * convert them to nanoseconds.
2535 *
2536 * XXX - this may give the impression of higher
2537 * precision than you actually get.
2538 */
2539 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2540 } else {
2541 time_stamp->secs = 0;
2542 time_stamp->nsecs = 0;
2543 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2544 }
2545 break;
2546
2547 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2548 /*
2549 * NTP time stamp, with 1-second resolution (i.e.,
2550 * seconds since the NTP epoch), big-endian.
2551 * Only supported for absolute times.
2552 */
2553 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2553, "!is_relative"
))))
;
2554
2555 if (length == 4) {
2556 /*
2557 * We need a temporary variable here so the unsigned math
2558 * works correctly (for years > 2036 according to RFC 2030
2559 * chapter 3).
2560 *
2561 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2562 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2563 * If bit 0 is not set, the time is in the range 2036-2104 and
2564 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2565 */
2566 tmpsecs = tvb_get_ntohl(tvb, start);
2567 if ((tmpsecs & 0x80000000) != 0)
2568 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2569 else
2570 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2571 time_stamp->nsecs = 0;
2572 } else {
2573 time_stamp->secs = 0;
2574 time_stamp->nsecs = 0;
2575 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2576 }
2577 break;
2578
2579 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2580 /*
2581 * NTP time stamp, with 1-second resolution (i.e.,
2582 * seconds since the NTP epoch), little-endian.
2583 * Only supported for absolute times.
2584 */
2585 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2585, "!is_relative"
))))
;
2586
2587 /*
2588 * We need a temporary variable here so the unsigned math
2589 * works correctly (for years > 2036 according to RFC 2030
2590 * chapter 3).
2591 *
2592 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2593 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2594 * If bit 0 is not set, the time is in the range 2036-2104 and
2595 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2596 */
2597 if (length == 4) {
2598 tmpsecs = tvb_get_letohl(tvb, start);
2599 if ((tmpsecs & 0x80000000) != 0)
2600 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2601 else
2602 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2603 time_stamp->nsecs = 0;
2604 } else {
2605 time_stamp->secs = 0;
2606 time_stamp->nsecs = 0;
2607 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2608 }
2609 break;
2610
2611 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2612 /*
2613 * Milliseconds, 6 to 8 bytes.
2614 * For absolute times, it's milliseconds since the
2615 * NTP epoch.
2616 *
2617 * ETSI TS 129.274 8.119 defines this as:
2618 * "a 48 bit unsigned integer in network order format
2619 * ...encoded as the number of milliseconds since
2620 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2621 * rounded value of 1000 x the value of the 64-bit
2622 * timestamp (Seconds + (Fraction / (1<<32))) defined
2623 * in clause 6 of IETF RFC 5905."
2624 *
2625 * Taken literally, the part after "i.e." would
2626 * mean that the value rolls over before reaching
2627 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2628 * when the 64 bit timestamp rolls over, and we have
2629 * to pick an NTP Era equivalence class to support
2630 * (such as 1968-01-20 to 2104-02-06).
2631 *
2632 * OTOH, the extra room might be used to store Era
2633 * information instead, in which case times until
2634 * 10819-08-03 can be represented with 6 bytes without
2635 * ambiguity. We handle both implementations, and assume
2636 * that times before 1968-01-20 are not represented.
2637 *
2638 * Only 6 bytes or more makes sense as an absolute
2639 * time. 5 bytes or fewer could express a span of
2640 * less than 35 years, either 1900-1934 or 2036-2070.
2641 */
2642 if (length >= 6 && length <= 8) {
2643 uint64_t msecs;
2644
2645 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2646 tmp64secs = (msecs / 1000);
2647 /*
2648 * Assume that times in the first half of NTP
2649 * Era 0 really represent times in the NTP
2650 * Era 1.
2651 */
2652 if (tmp64secs >= 0x80000000)
2653 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2654 else
2655 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2656 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2657 }
2658 else {
2659 time_stamp->secs = 0;
2660 time_stamp->nsecs = 0;
2661 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2662 }
2663 break;
2664
2665 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2666 /*
2667 * MP4 file time stamps, big-endian.
2668 * Only supported for absolute times.
2669 */
2670 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2670, "!is_relative"
))))
;
2671
2672 if (length == 8) {
2673 tmp64secs = tvb_get_ntoh64(tvb, start);
2674 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2675 time_stamp->nsecs = 0;
2676 } else if (length == 4) {
2677 tmpsecs = tvb_get_ntohl(tvb, start);
2678 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2679 time_stamp->nsecs = 0;
2680 } else {
2681 time_stamp->secs = 0;
2682 time_stamp->nsecs = 0;
2683 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2684 }
2685 break;
2686
2687 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2688 /*
2689 * Zigbee ZCL time stamps, big-endian.
2690 * Only supported for absolute times.
2691 */
2692 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2692, "!is_relative"
))))
;
2693
2694 if (length == 8) {
2695 tmp64secs = tvb_get_ntoh64(tvb, start);
2696 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))
) {
2697 /* There are several other possible choices for what to do
2698 * with overflow; make sure to coordinate with whatever
2699 * packet-zbee-zcl.h does. */
2700 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))))))
;
2701 }
2702 time_stamp->nsecs = 0;
2703 } else if (length == 4) {
2704 tmpsecs = tvb_get_ntohl(tvb, start);
2705 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))
) {
2706 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))))))
;
2707 }
2708 time_stamp->nsecs = 0;
2709 } else {
2710 time_stamp->secs = 0;
2711 time_stamp->nsecs = 0;
2712 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2713 }
2714 break;
2715
2716 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2717 /*
2718 * Zigbee ZCL time stamps, little-endian.
2719 * Only supported for absolute times.
2720 */
2721 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2721, "!is_relative"
))))
;
2722
2723 if (length == 8) {
2724 tmp64secs = tvb_get_letoh64(tvb, start);
2725 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))
) {
2726 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))))))
;
2727 }
2728 time_stamp->nsecs = 0;
2729 } else if (length == 4) {
2730 tmpsecs = tvb_get_letohl(tvb, start);
2731 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))
) {
2732 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))))))
;
2733 }
2734 time_stamp->nsecs = 0;
2735 } else {
2736 time_stamp->secs = 0;
2737 time_stamp->nsecs = 0;
2738 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2739 }
2740 break;
2741
2742 case ENC_TIME_WINDOWS0x00000034 | ENC_BIG_ENDIAN0x00000000:
2743 /*
2744 * WINDOWS FILETIME, big-endian.
2745 * Only supported for absolute times.
2746 * A FILETIME is a struct with the low 32-bits followed
2747 * by the high 32-bits:
2748 * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2749 * There exist cases where the value is stored in a
2750 * 64-bit integer:
2751 * (See epan/dissectors/pidl/samr/samr.idl "NTTIME_hyper last_password_change;"
2752 * which is confirmed as "LARGE_INTEGER PasswordLastSet;" in
2753 * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1cd138b9-cc1b-4706-b115-49e53189e32e
2754 * That doesn't make a difference when retrieving little-endian,
2755 * because tvb_get_letoh64 handles unaligned accesses and it's
2756 * otherwise the same. However, for big-endian, it does matter,
2757 * analogous to the ENC_TIME_NTP little-endian case. We use the
2758 * struct version, but that means that this MUST NOT be used
2759 * for dissect_nttime_hyper in packet-windows-common.h, at
2760 * least
2761 */
2762 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2762, "!is_relative"
))))
;
2763
2764 if (length == 8) {
2765 tmp64secs = tvb_get_ntoh64(tvb, start); // Really 100-ns units
2766 if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2767 // With 32-bit time_t, this could overflow in
2768 // either direction. We should probably add some
2769 // kind of time overflow expert item to all
2770 // encodings.
2771 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))))))
;
2772 time_stamp->nsecs = 0;
2773 }
2774 } else {
2775 time_stamp->secs = 0;
2776 time_stamp->nsecs = 0;
2777 report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2778 }
2779 break;
2780
2781 case ENC_TIME_WINDOWS0x00000034 | ENC_LITTLE_ENDIAN0x80000000:
2782 /*
2783 * WINDOWS FILETIME, big-endian.
2784 * Only supported for absolute times.
2785 * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2786 */
2787 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2787, "!is_relative"
))))
;
2788
2789 if (length == 8) {
2790 tmp64secs = tvb_get_letoh64(tvb, start); // Really 100-ns units
2791 if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2792 // With 32-bit time_t, this could overflow in
2793 // either direction. We should probably add some
2794 // kind of time overflow expert item to all
2795 // encodings.
2796 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))))))
;
2797 time_stamp->nsecs = 0;
2798 }
2799 } else {
2800 time_stamp->secs = 0;
2801 time_stamp->nsecs = 0;
2802 report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2803 }
2804 break;
2805 default:
2806 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2806))
;
2807 break;
2808 }
2809}
2810
2811static void
2812tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2813{
2814 const header_field_info *hfinfo = fi->hfinfo;
2815
2816 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2817 GPtrArray *ptrs = NULL((void*)0);
2818
2819 if (tree_data->interesting_hfids == NULL((void*)0)) {
2820 /* Initialize the hash because we now know that it is needed */
2821 tree_data->interesting_hfids =
2822 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2823 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2824 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2825 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2826 }
2827
2828 if (!ptrs) {
2829 /* First element triggers the creation of pointer array */
2830 ptrs = g_ptr_array_new();
2831 g_hash_table_insert(tree_data->interesting_hfids,
2832 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2833 }
2834
2835 g_ptr_array_add(ptrs, fi);
2836 }
2837}
2838
2839
2840/*
2841 * Validates that field length bytes are available starting from
2842 * start (pos/neg). Throws an exception if they aren't.
2843 */
2844static void
2845test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2846 unsigned start, int length, const unsigned encoding)
2847{
2848 int size = length;
2849
2850 if (!tvb)
2851 return;
2852
2853 if ((hfinfo->type == FT_STRINGZ) ||
2854 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2855 (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
))
))) {
2856 /* If we're fetching until the end of the TVB, only validate
2857 * that the offset is within range.
2858 */
2859 if (length == -1)
2860 size = 0;
2861 }
2862
2863 tvb_ensure_bytes_exist(tvb, start, size);
2864}
2865
2866static void
2867detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2868{
2869 bool_Bool found_stray_character = false0;
2870
2871 if (!string)
2872 return;
2873
2874 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2875 case ENC_ASCII0x00000000:
2876 case ENC_UTF_80x00000002:
2877 for (int i = (int)strlen(string); i < length; i++) {
2878 if (string[i] != '\0') {
2879 found_stray_character = true1;
2880 break;
2881 }
2882 }
2883 break;
2884
2885 default:
2886 break;
2887 }
2888
2889 if (found_stray_character) {
2890 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2891 }
2892}
2893
2894/* Add an item to a proto_tree, using the text label registered to that item;
2895 the item is extracted from the tvbuff handed to it. */
2896static proto_item *
2897proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2898 tvbuff_t *tvb, unsigned start, int length,
2899 unsigned encoding)
2900{
2901 proto_item *pi;
2902 uint32_t value, n;
2903 uint64_t value64;
2904 ws_in4_addr ipv4_value;
2905 float floatval;
2906 double doubleval;
2907 const char *stringval = NULL((void*)0);
2908 nstime_t time_stamp;
2909 bool_Bool length_error;
2910 unsigned item_length;
2911
2912 // new_fi->value is allocated from the packet-scoped pool (see
2913 // new_field_info()), so if a tvbuff accessor below throws before the
2914 // node is added to the tree the fvalue_t structure is still reclaimed
2915 // when the pool is freed; no explicit cleanup handler is needed. This
2916 // relies on the invariant that the type-specific data an fvalue owns
2917 // (byte arrays, string buffers, ...) is only allocated *after* the
2918 // throwing tvbuff read that produced it succeeds, so nothing that would
2919 // need fvalue_cleanup() is ever leaked on the exception path.
2920 switch (new_fi->hfinfo->type) {
2921 case FT_NONE:
2922 /* no value to set for FT_NONE */
2923 break;
2924
2925 case FT_PROTOCOL:
2926 /* Set the protocol_tvb via the start offset, but include
2927 * rest of the ds_tvb so that if finfo_set_len is called
2928 * later it can be lengthened as much as possible. */
2929 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);
2930 break;
2931
2932 case FT_BYTES:
2933 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2934 break;
2935
2936 case FT_UINT_BYTES:
2937 n = get_uint_value(tree, tvb, start, length, encoding);
2938 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2939
2940 /* Instead of calling proto_item_set_len(), since we don't yet
2941 * have a proto_item, we set the field_info's length ourselves. */
2942 new_fi->length = n + length;
2943 break;
2944
2945 case FT_BOOLEAN:
2946 /*
2947 * Map all non-zero values to little-endian for
2948 * backwards compatibility.
2949 */
2950 if (encoding)
2951 encoding = ENC_LITTLE_ENDIAN0x80000000;
2952 proto_tree_set_boolean(new_fi,
2953 get_uint64_value(tree, tvb, start, length, encoding));
2954 break;
2955
2956 case FT_CHAR:
2957 /* XXX - make these just FT_UINT? */
2958 case FT_UINT8:
2959 case FT_UINT16:
2960 case FT_UINT24:
2961 case FT_UINT32:
2962 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2963 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2964 value = (uint32_t)value64;
2965 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2966 new_fi->flags |= FI_VARINT0x00040000;
2967 }
2968 }
2969 else {
2970 /*
2971 * Map all non-zero values to little-endian for
2972 * backwards compatibility.
2973 */
2974 if (encoding)
2975 encoding = ENC_LITTLE_ENDIAN0x80000000;
2976
2977 value = get_uint_value(tree, tvb, start, length, encoding);
2978 }
2979 proto_tree_set_uint(new_fi, value);
2980 break;
2981
2982 case FT_UINT40:
2983 case FT_UINT48:
2984 case FT_UINT56:
2985 case FT_UINT64:
2986 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2987 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2988 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2989 new_fi->flags |= FI_VARINT0x00040000;
2990 }
2991 }
2992 else {
2993 /*
2994 * Map all other non-zero values to little-endian for
2995 * backwards compatibility.
2996 */
2997 if (encoding)
2998 encoding = ENC_LITTLE_ENDIAN0x80000000;
2999
3000 value64 = get_uint64_value(tree, tvb, start, length, encoding);
3001 }
3002 proto_tree_set_uint64(new_fi, value64);
3003 break;
3004
3005 /* XXX - make these just FT_INT? */
3006 case FT_INT8:
3007 case FT_INT16:
3008 case FT_INT24:
3009 case FT_INT32:
3010 /*
3011 * Map all non-zero values to little-endian for
3012 * backwards compatibility.
3013 */
3014 if (encoding)
3015 encoding = ENC_LITTLE_ENDIAN0x80000000;
3016 proto_tree_set_int(new_fi,
3017 get_int_value(tree, tvb, start, length, encoding));
3018 break;
3019
3020 case FT_INT40:
3021 case FT_INT48:
3022 case FT_INT56:
3023 case FT_INT64:
3024 /*
3025 * Map all non-zero values to little-endian for
3026 * backwards compatibility.
3027 */
3028 if (encoding)
3029 encoding = ENC_LITTLE_ENDIAN0x80000000;
3030 proto_tree_set_int64(new_fi,
3031 get_int64_value(tree, tvb, start, length, encoding));
3032 break;
3033
3034 case FT_IPv4:
3035 /*
3036 * Map all non-zero values to little-endian for
3037 * backwards compatibility.
3038 */
3039 if (encoding)
3040 encoding = ENC_LITTLE_ENDIAN0x80000000;
3041 if (length != FT_IPv4_LEN4) {
3042 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
3043 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
3044 }
3045 ipv4_value = tvb_get_ipv4(tvb, start);
3046 /*
3047 * NOTE: to support code written when
3048 * proto_tree_add_item() took a bool as its
3049 * last argument, with false meaning "big-endian"
3050 * and true meaning "little-endian", we treat any
3051 * non-zero value of "encoding" as meaning
3052 * "little-endian".
3053 */
3054 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);
3055 break;
3056
3057 case FT_IPXNET:
3058 if (length != FT_IPXNET_LEN4) {
3059 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
3060 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
3061 }
3062 proto_tree_set_ipxnet(new_fi,
3063 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
3064 break;
3065
3066 case FT_IPv6:
3067 if (length != FT_IPv6_LEN16) {
3068 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
3069 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3070 }
3071 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3072 break;
3073
3074 case FT_FCWWN:
3075 if (length != FT_FCWWN_LEN8) {
3076 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3077 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3078 }
3079 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3080 break;
3081
3082 case FT_AX25:
3083 if (length != 7) {
3084 length_error = length < 7 ? true1 : false0;
3085 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3086 }
3087 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3088 break;
3089
3090 case FT_VINES:
3091 if (length != VINES_ADDR_LEN6) {
3092 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3093 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3094 }
3095 proto_tree_set_vines_tvb(new_fi, tvb, start);
3096 break;
3097
3098 case FT_ETHER:
3099 if (length != FT_ETHER_LEN6) {
3100 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3101 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3102 }
3103 proto_tree_set_ether_tvb(new_fi, tvb, start);
3104 break;
3105
3106 case FT_EUI64:
3107 /*
3108 * Map all non-zero values to little-endian for
3109 * backwards compatibility.
3110 */
3111 if (encoding)
3112 encoding = ENC_LITTLE_ENDIAN0x80000000;
3113 if (length != FT_EUI64_LEN8) {
3114 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3115 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3116 }
3117 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3118 break;
3119 case FT_GUID:
3120 /*
3121 * Map all non-zero values to little-endian for
3122 * backwards compatibility.
3123 */
3124 if (encoding)
3125 encoding = ENC_LITTLE_ENDIAN0x80000000;
3126 if (length != FT_GUID_LEN16) {
3127 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3128 report_type_length_mismatch(tree, "a GUID", length, length_error);
3129 }
3130 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3131 break;
3132
3133 case FT_OID:
3134 case FT_REL_OID:
3135 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3136 break;
3137
3138 case FT_SYSTEM_ID:
3139 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3140 break;
3141
3142 case FT_FLOAT:
3143 /*
3144 * NOTE: to support code written when
3145 * proto_tree_add_item() took a bool as its
3146 * last argument, with false meaning "big-endian"
3147 * and true meaning "little-endian", we treat any
3148 * non-zero value of "encoding" as meaning
3149 * "little-endian".
3150 *
3151 * At some point in the future, we might
3152 * support non-IEEE-binary floating-point
3153 * formats in the encoding as well
3154 * (IEEE decimal, System/3x0, VAX).
3155 */
3156 if (encoding)
3157 encoding = ENC_LITTLE_ENDIAN0x80000000;
3158 if (length != 4) {
3159 length_error = length < 4 ? true1 : false0;
3160 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3161 }
3162 if (encoding)
3163 floatval = tvb_get_letohieee_float(tvb, start);
3164 else
3165 floatval = tvb_get_ntohieee_float(tvb, start);
3166 proto_tree_set_float(new_fi, floatval);
3167 break;
3168
3169 case FT_DOUBLE:
3170 /*
3171 * NOTE: to support code written when
3172 * proto_tree_add_item() took a bool as its
3173 * last argument, with false meaning "big-endian"
3174 * and true meaning "little-endian", we treat any
3175 * non-zero value of "encoding" as meaning
3176 * "little-endian".
3177 *
3178 * At some point in the future, we might
3179 * support non-IEEE-binary floating-point
3180 * formats in the encoding as well
3181 * (IEEE decimal, System/3x0, VAX).
3182 */
3183 if (encoding == true1)
3184 encoding = ENC_LITTLE_ENDIAN0x80000000;
3185 if (length != 8) {
3186 length_error = length < 8 ? true1 : false0;
3187 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3188 }
3189 if (encoding)
3190 doubleval = tvb_get_letohieee_double(tvb, start);
3191 else
3192 doubleval = tvb_get_ntohieee_double(tvb, start);
3193 proto_tree_set_double(new_fi, doubleval);
3194 break;
3195
3196 case FT_STRING:
3197 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3198 tvb, start, length, &item_length, encoding);
3199 proto_tree_set_string(new_fi, stringval);
3200
3201 /* Instead of calling proto_item_set_len(), since we
3202 * don't yet have a proto_item, we set the
3203 * field_info's length ourselves.
3204 *
3205 * XXX - our caller can't use that length to
3206 * advance an offset unless they arrange that
3207 * there always be a protocol tree into which
3208 * we're putting this item.
3209 */
3210 new_fi->length = item_length;
3211 break;
3212
3213 case FT_STRINGZ:
3214 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3215 tree, tvb, start, length, &item_length, encoding);
3216 proto_tree_set_string(new_fi, stringval);
3217
3218 /* Instead of calling proto_item_set_len(),
3219 * since we don't yet have a proto_item, we
3220 * set the field_info's length ourselves.
3221 *
3222 * XXX - our caller can't use that length to
3223 * advance an offset unless they arrange that
3224 * there always be a protocol tree into which
3225 * we're putting this item.
3226 */
3227 new_fi->length = item_length;
3228 break;
3229
3230 case FT_UINT_STRING:
3231 /*
3232 * NOTE: to support code written when
3233 * proto_tree_add_item() took a bool as its
3234 * last argument, with false meaning "big-endian"
3235 * and true meaning "little-endian", if the
3236 * encoding value is true, treat that as
3237 * ASCII with a little-endian length.
3238 *
3239 * This won't work for code that passes
3240 * arbitrary non-zero values; that code
3241 * will need to be fixed.
3242 */
3243 if (encoding == true1)
3244 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3245 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3246 tree, tvb, start, length, &item_length, encoding);
3247 proto_tree_set_string(new_fi, stringval);
3248
3249 /* Instead of calling proto_item_set_len(), since we
3250 * don't yet have a proto_item, we set the
3251 * field_info's length ourselves.
3252 *
3253 * XXX - our caller can't use that length to
3254 * advance an offset unless they arrange that
3255 * there always be a protocol tree into which
3256 * we're putting this item.
3257 */
3258 new_fi->length = item_length;
3259 break;
3260
3261 case FT_STRINGZPAD:
3262 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3263 tvb, start, length, &item_length, encoding);
3264 proto_tree_set_string(new_fi, stringval);
3265
3266 /* Instead of calling proto_item_set_len(), since we
3267 * don't yet have a proto_item, we set the
3268 * field_info's length ourselves.
3269 *
3270 * XXX - our caller can't use that length to
3271 * advance an offset unless they arrange that
3272 * there always be a protocol tree into which
3273 * we're putting this item.
3274 */
3275 new_fi->length = item_length;
3276 break;
3277
3278 case FT_STRINGZTRUNC:
3279 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3280 tvb, start, length, &item_length, encoding);
3281 proto_tree_set_string(new_fi, stringval);
3282
3283 /* Instead of calling proto_item_set_len(), since we
3284 * don't yet have a proto_item, we set the
3285 * field_info's length ourselves.
3286 *
3287 * XXX - our caller can't use that length to
3288 * advance an offset unless they arrange that
3289 * there always be a protocol tree into which
3290 * we're putting this item.
3291 */
3292 new_fi->length = item_length;
3293 break;
3294
3295 case FT_ABSOLUTE_TIME:
3296 /*
3297 * Absolute times can be in any of a number of
3298 * formats, and they can be big-endian or
3299 * little-endian.
3300 *
3301 * Historically FT_TIMEs were only timespecs;
3302 * the only question was whether they were stored
3303 * in big- or little-endian format.
3304 *
3305 * For backwards compatibility, we interpret an
3306 * encoding of 1 as meaning "little-endian timespec",
3307 * so that passing true is interpreted as that.
3308 */
3309 if (encoding == true1)
3310 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3311
3312 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3313
3314 proto_tree_set_time(new_fi, &time_stamp);
3315 break;
3316
3317 case FT_RELATIVE_TIME:
3318 /*
3319 * Relative times can be in any of a number of
3320 * formats, and they can be big-endian or
3321 * little-endian.
3322 *
3323 * Historically FT_TIMEs were only timespecs;
3324 * the only question was whether they were stored
3325 * in big- or little-endian format.
3326 *
3327 * For backwards compatibility, we interpret an
3328 * encoding of 1 as meaning "little-endian timespec",
3329 * so that passing true is interpreted as that.
3330 */
3331 if (encoding == true1)
3332 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3333
3334 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3335
3336 proto_tree_set_time(new_fi, &time_stamp);
3337 break;
3338 case FT_IEEE_11073_SFLOAT:
3339 if (encoding)
3340 encoding = ENC_LITTLE_ENDIAN0x80000000;
3341 if (length != 2) {
3342 length_error = length < 2 ? true1 : false0;
3343 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3344 }
3345
3346 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3347
3348 break;
3349 case FT_IEEE_11073_FLOAT:
3350 if (encoding)
3351 encoding = ENC_LITTLE_ENDIAN0x80000000;
3352 if (length != 4) {
3353 length_error = length < 4 ? true1 : false0;
3354 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3355 }
3356 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3357
3358 break;
3359 default:
3360 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))
3361 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))
3362 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))
3363 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))
;
3364 break;
3365 }
3366 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)
;
3367
3368 /* Don't add new node to proto_tree until now so that any exceptions
3369 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3370 /* XXX. wouldn't be better to add this item to tree, with some special
3371 * flag (FI_EXCEPTION?) to know which item caused exception? For
3372 * strings and bytes, we would have to set new_fi->value to something
3373 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3374 * could handle NULL values. */
3375 pi = proto_tree_add_node(tree, new_fi);
3376
3377 switch (new_fi->hfinfo->type) {
3378
3379 case FT_STRING:
3380 /* XXX: trailing stray character detection should be done
3381 * _before_ conversion to UTF-8, because conversion can change
3382 * the length, or else get_string_length should return a value
3383 * for the "length in bytes of the string after conversion
3384 * including internal nulls." (Noting that we do, for other
3385 * reasons, still need the "length in bytes in the field",
3386 * especially for FT_STRINGZ.)
3387 *
3388 * This is true even for ASCII and UTF-8, because
3389 * substituting REPLACEMENT CHARACTERS for illegal characters
3390 * can also do so (and for UTF-8 possibly even make the
3391 * string _shorter_).
3392 */
3393 detect_trailing_stray_characters(encoding, stringval, item_length, pi);
3394 break;
3395
3396 default:
3397 break;
3398 }
3399
3400 return pi;
3401}
3402
3403proto_item *
3404proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3405 const unsigned start, unsigned length,
3406 const unsigned encoding, int32_t *retval)
3407{
3408 header_field_info *hfinfo;
3409 field_info *new_fi;
3410 int32_t value;
3411
3412 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", 3412, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3412,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3412, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3413
3414 switch (hfinfo->type) {
3415 case FT_INT8:
3416 case FT_INT16:
3417 case FT_INT24:
3418 case FT_INT32:
3419 break;
3420 case FT_INT64:
3421 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)
3422 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3423 default:
3424 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)
3425 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3426 }
3427
3428 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3429 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3430 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3431 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3432 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3433 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3434 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3435
3436 if (encoding & ENC_STRING0x07000000) {
3437 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3438 }
3439 /* I believe it's ok if this is called with a NULL tree */
3440 value = get_int_value(tree, tvb, start, length, encoding);
3441
3442 if (retval) {
3443 int no_of_bits;
3444 *retval = value;
3445 if (hfinfo->bitmask) {
3446 /* Mask out irrelevant portions */
3447 *retval &= (uint32_t)(hfinfo->bitmask);
3448 /* Shift bits */
3449 *retval >>= hfinfo_bitshift(hfinfo);
3450 }
3451 no_of_bits = ws_count_ones(hfinfo->bitmask);
3452 *retval = ws_sign_ext32(*retval, no_of_bits);
3453 }
3454
3455 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3456
3457 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", 3457
, __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", 3457, "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", 3457, "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", 3457, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3458
3459 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3460
3461 proto_tree_set_int(new_fi, value);
3462
3463 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3464
3465 return proto_tree_add_node(tree, new_fi);
3466}
3467
3468proto_item *
3469proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3470 const unsigned start, unsigned length,
3471 const unsigned encoding, uint32_t *retval)
3472{
3473 header_field_info *hfinfo;
3474 field_info *new_fi;
3475 uint32_t value;
3476
3477 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", 3477, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3477,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3477, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3478
3479 switch (hfinfo->type) {
3480 case FT_CHAR:
3481 case FT_UINT8:
3482 case FT_UINT16:
3483 case FT_UINT24:
3484 case FT_UINT32:
3485 break;
3486 default:
3487 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)
3488 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)
;
3489 }
3490
3491 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3492 {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3493 if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3494 *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3495 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3496 return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3497 }if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
3498 )if (length == 0) { { if (retval) { *retval = 0; } return ((void
*)0); }; return ((void*)0); }
;
3499
3500 if (encoding & ENC_STRING0x07000000) {
3501 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3502 }
3503 /* I believe it's ok if this is called with a NULL tree */
3504 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3505 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3506 uint64_t temp64;
3507 tvb_get_varint(tvb, start, length, &temp64, encoding);
3508 value = (uint32_t)temp64;
3509 } else {
3510 value = get_uint_value(tree, tvb, start, length, encoding);
3511 }
3512
3513 if (retval) {
3514 *retval = value;
3515 if (hfinfo->bitmask) {
3516 /* Mask out irrelevant portions */
3517 *retval &= (uint32_t)(hfinfo->bitmask);
3518 /* Shift bits */
3519 *retval >>= hfinfo_bitshift(hfinfo);
3520 }
3521 }
3522
3523 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3524
3525 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", 3525
, __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", 3525, "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", 3525, "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", 3525, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3526
3527 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3528
3529 proto_tree_set_uint(new_fi, value);
3530
3531 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3532 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3533 new_fi->flags |= FI_VARINT0x00040000;
3534 }
3535 return proto_tree_add_node(tree, new_fi);
3536}
3537
3538proto_item *
3539proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3540 const unsigned start, unsigned length,
3541 const unsigned encoding, uint32_t *retval)
3542{
3543 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3544}
3545
3546proto_item *
3547proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3548 const unsigned start, unsigned length,
3549 const unsigned encoding, uint8_t *retval)
3550{
3551 /* TODO: further restrict by hfinfo->type ? */
3552 uint32_t val32;
3553 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3554 *retval = (uint8_t)val32;
3555 return item;
3556}
3557
3558proto_item *
3559proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3560 const unsigned start, unsigned length,
3561 const unsigned encoding, uint16_t *retval)
3562{
3563 /* TODO: further restrict by hfinfo->type ? */
3564 uint32_t val32;
3565 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3566 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3567 return item;
3568}
3569
3570
3571/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3572 * and returns proto_item* and uint value retrieved*/
3573proto_item *
3574ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3575 const unsigned encoding, uint32_t *retval)
3576{
3577 field_info *new_fi;
3578 header_field_info *hfinfo;
3579 unsigned item_length;
3580 unsigned offset;
3581 uint32_t value;
3582
3583 offset = ptvc->offset;
3584 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", 3584, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3584,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3584, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3585
3586 switch (hfinfo->type) {
3587 case FT_CHAR:
3588 case FT_UINT8:
3589 case FT_UINT16:
3590 case FT_UINT24:
3591 case FT_UINT32:
3592 break;
3593 default:
3594 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)
3595 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)
;
3596 }
3597
3598 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3599 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3600
3601 /* I believe it's ok if this is called with a NULL tree */
3602 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3603 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3604
3605 if (retval) {
3606 *retval = value;
3607 if (hfinfo->bitmask) {
3608 /* Mask out irrelevant portions */
3609 *retval &= (uint32_t)(hfinfo->bitmask);
3610 /* Shift bits */
3611 *retval >>= hfinfo_bitshift(hfinfo);
3612 }
3613 }
3614
3615 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3616
3617 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3618
3619 /* Coast clear. Try and fake it */
3620 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", 3620
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3620, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3620, "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", 3620, __func__, "Adding %s would put more than %d 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); } } }
;
3621
3622 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3623
3624 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3625 offset, length, encoding);
3626}
3627
3628/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3629 * and returns proto_item* and int value retrieved*/
3630proto_item *
3631ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3632 const unsigned encoding, int32_t *retval)
3633{
3634 field_info *new_fi;
3635 header_field_info *hfinfo;
3636 unsigned item_length;
3637 unsigned offset;
3638 uint32_t value;
3639
3640 offset = ptvc->offset;
3641 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", 3641, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3641,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3641, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3642
3643 switch (hfinfo->type) {
3644 case FT_INT8:
3645 case FT_INT16:
3646 case FT_INT24:
3647 case FT_INT32:
3648 break;
3649 default:
3650 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)
3651 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3652 }
3653
3654 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3655 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3656
3657 /* I believe it's ok if this is called with a NULL tree */
3658 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3659 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3660
3661 if (retval) {
3662 int no_of_bits;
3663 *retval = value;
3664 if (hfinfo->bitmask) {
3665 /* Mask out irrelevant portions */
3666 *retval &= (uint32_t)(hfinfo->bitmask);
3667 /* Shift bits */
3668 *retval >>= hfinfo_bitshift(hfinfo);
3669 }
3670 no_of_bits = ws_count_ones(hfinfo->bitmask);
3671 *retval = ws_sign_ext32(*retval, no_of_bits);
3672 }
3673
3674 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3675
3676 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3677
3678 /* Coast clear. Try and fake it */
3679 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", 3679
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3679, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3679, "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", 3679, __func__, "Adding %s would put more than %d 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); } } }
;
3680
3681 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3682
3683 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3684 offset, length, encoding);
3685}
3686
3687/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3688 * and returns proto_item* and string value retrieved */
3689proto_item*
3690ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3691{
3692 header_field_info *hfinfo;
3693 field_info *new_fi;
3694 const uint8_t *value;
3695 unsigned item_length;
3696 unsigned offset;
3697
3698 offset = ptvc->offset;
3699
3700 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", 3700
, __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", 3700, "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", 3700, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3701
3702 switch (hfinfo->type) {
3703 case FT_STRING:
3704 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3705 break;
3706 case FT_STRINGZ:
3707 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3708 break;
3709 case FT_UINT_STRING:
3710 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3711 break;
3712 case FT_STRINGZPAD:
3713 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3714 break;
3715 case FT_STRINGZTRUNC:
3716 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3717 break;
3718 default:
3719 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)
3720 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)
;
3721 }
3722
3723 if (retval)
3724 *retval = value;
3725
3726 ptvcursor_advance(ptvc, item_length);
3727
3728 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3729
3730 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", 3730, __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", 3730,
"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", 3730, "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", 3730
, __func__, "Adding %s would put more than %d 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); } } }
;
3731
3732 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3733
3734 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3735 offset, length, encoding);
3736}
3737
3738/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3739 * and returns proto_item* and boolean value retrieved */
3740proto_item*
3741ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3742{
3743 header_field_info *hfinfo;
3744 field_info *new_fi;
3745 unsigned item_length;
3746 unsigned offset;
3747 uint64_t value, bitval;
3748
3749 offset = ptvc->offset;
3750 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", 3750, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3750,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3750, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3751
3752 if (hfinfo->type != FT_BOOLEAN) {
3753 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)
3754 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3755 }
3756
3757 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3758 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3759 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3760 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3761 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3762 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3763 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3764
3765 if (encoding & ENC_STRING0x07000000) {
3766 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3767 }
3768
3769 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3770 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3771
3772 /* I believe it's ok if this is called with a NULL tree */
3773 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3774
3775 if (retval) {
3776 bitval = value;
3777 if (hfinfo->bitmask) {
3778 /* Mask out irrelevant portions */
3779 bitval &= hfinfo->bitmask;
3780 }
3781 *retval = (bitval != 0);
3782 }
3783
3784 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3785
3786 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3787
3788 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", 3788, __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", 3788,
"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", 3788, "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", 3788
, __func__, "Adding %s would put more than %d 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); } } }
;
3789
3790 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3791
3792 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3793 offset, length, encoding);
3794}
3795
3796proto_item *
3797proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3798 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3799{
3800 header_field_info *hfinfo;
3801 field_info *new_fi;
3802 uint64_t value;
3803
3804 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", 3804, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3804,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3804, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3805
3806 switch (hfinfo->type) {
3807 case FT_UINT40:
3808 case FT_UINT48:
3809 case FT_UINT56:
3810 case FT_UINT64:
3811 break;
3812 default:
3813 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)
3814 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3815 }
3816
3817 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3818 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3819 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3820 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3821 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3822 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3823 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3824
3825 if (encoding & ENC_STRING0x07000000) {
3826 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3827 }
3828 /* I believe it's ok if this is called with a NULL tree */
3829 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3830 tvb_get_varint(tvb, start, length, &value, encoding);
3831 } else {
3832 value = get_uint64_value(tree, tvb, start, length, encoding);
3833 }
3834
3835 if (retval) {
3836 *retval = value;
3837 if (hfinfo->bitmask) {
3838 /* Mask out irrelevant portions */
3839 *retval &= hfinfo->bitmask;
3840 /* Shift bits */
3841 *retval >>= hfinfo_bitshift(hfinfo);
3842 }
3843 }
3844
3845 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3846
3847 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", 3847
, __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", 3847, "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", 3847, "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", 3847, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3848
3849 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3850
3851 proto_tree_set_uint64(new_fi, value);
3852
3853 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3854 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3855 new_fi->flags |= FI_VARINT0x00040000;
3856 }
3857
3858 return proto_tree_add_node(tree, new_fi);
3859}
3860
3861proto_item *
3862proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3863 const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3864{
3865 header_field_info *hfinfo;
3866 field_info *new_fi;
3867 int64_t value;
3868
3869 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", 3869, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3869,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3869, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3870
3871 switch (hfinfo->type) {
3872 case FT_INT40:
3873 case FT_INT48:
3874 case FT_INT56:
3875 case FT_INT64:
3876 break;
3877 default:
3878 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)
3879 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3880 }
3881
3882 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3883 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3884 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3885 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3886 *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3887 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
3888 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
3889
3890 if (encoding & ENC_STRING0x07000000) {
3891 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3892 }
3893 /* I believe it's ok if this is called with a NULL tree */
3894 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3895 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3896 }
3897 else {
3898 value = get_int64_value(tree, tvb, start, length, encoding);
3899 }
3900
3901 if (retval) {
3902 *retval = value;
3903 }
3904
3905 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3906
3907 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", 3907
, __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", 3907, "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", 3907, "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", 3907, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3908
3909 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3910
3911 proto_tree_set_int64(new_fi, value);
3912
3913 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3914 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3915 new_fi->flags |= FI_VARINT0x00040000;
3916 }
3917
3918 return proto_tree_add_node(tree, new_fi);
3919}
3920
3921proto_item *
3922proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3923 const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3924{
3925 header_field_info *hfinfo;
3926 field_info *new_fi;
3927 uint64_t value;
3928
3929 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3929, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3929,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3929, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3930
3931 if ((!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
))
)) {
3932 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)
3933 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3934 }
3935
3936 if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3937 REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3938 }
3939
3940 if (encoding & ENC_STRING0x07000000) {
3941 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3942 }
3943
3944 /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3945 * It also handles length 0, setting both return values to 0.
3946 * XXX - Should the max length be affected by the field type and/or
3947 * encoding, e.g. 5 for FT_[U]INT32?
3948 * XXX - Should there be separate _varint and _varuint versions to
3949 * avoid the changing the sign when casting the return value?
3950 * XXX - Do we even need the length parameter? Every user of this
3951 * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3952 * separate function, but unlike some field types, variable length
3953 * is the typical case here, not the exception, and the typical
3954 * case should have the shorter, more convenient function name.
3955 * Having the length makes the signature more similar to other
3956 * functions, though. */
3957 length = tvb_get_varint(tvb, start, length, &value, encoding);
3958
3959 if (length == 0) {
3960 expert_add_info(NULL((void*)0), tree, &ei_varint_decoding_failed_error);
3961 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3962 }
3963
3964 if (retval) {
3965 *retval = value;
3966 if (hfinfo->bitmask) {
3967 /* Mask out irrelevant portions */
3968 *retval &= hfinfo->bitmask;
3969 /* Shift bits */
3970 *retval >>= hfinfo_bitshift(hfinfo);
3971 }
3972 }
3973
3974 if (lenretval) {
3975 *lenretval = length;
3976 }
3977
3978 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3979
3980 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", 3980
, __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", 3980, "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", 3980, "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", 3980, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3981
3982 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3983
3984 proto_tree_set_uint64(new_fi, value);
3985
3986 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3987 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3988 new_fi->flags |= FI_VARINT0x00040000;
3989 }
3990
3991 return proto_tree_add_node(tree, new_fi);
3992
3993}
3994
3995proto_item *
3996proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3997 const unsigned start, unsigned length,
3998 const unsigned encoding, bool_Bool *retval)
3999{
4000 header_field_info *hfinfo;
4001 field_info *new_fi;
4002 uint64_t value, bitval;
4003
4004 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", 4004, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4004,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4004, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4005
4006 if (hfinfo->type != FT_BOOLEAN) {
4007 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)
4008 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
4009 }
4010
4011 CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4012 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4013 if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4014 {if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4015 *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4016 }if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
4017 } )if (length == 0) { { if(retval) { *retval = 0; } }; return ((
void*)0); }
;
4018
4019 if (encoding & ENC_STRING0x07000000) {
4020 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4021 }
4022 /* I believe it's ok if this is called with a NULL tree */
4023 value = get_uint64_value(tree, tvb, start, length, encoding);
4024
4025 if (retval) {
4026 bitval = value;
4027 if (hfinfo->bitmask) {
4028 /* Mask out irrelevant portions */
4029 bitval &= hfinfo->bitmask;
4030 }
4031 *retval = (bitval != 0);
4032 }
4033
4034 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4035
4036 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", 4036
, __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", 4036, "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", 4036, "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", 4036, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4037
4038 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4039
4040 proto_tree_set_boolean(new_fi, value);
4041
4042 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4043
4044 return proto_tree_add_node(tree, new_fi);
4045}
4046
4047proto_item *
4048proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4049 const unsigned start, unsigned length,
4050 const unsigned encoding, float *retval)
4051{
4052 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4053 field_info *new_fi;
4054 float value;
4055
4056 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", 4056,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4057
4058 if (hfinfo->type != FT_FLOAT) {
4059 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)
;
4060 }
4061
4062 if (length != 4) {
4063 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
4064 }
4065
4066 /* treat any nonzero encoding as little endian for backwards compatibility */
4067 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
4068 if (retval) {
4069 *retval = value;
4070 }
4071
4072 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4073
4074 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", 4074
, __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", 4074, "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", 4074, "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", 4074, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4075
4076 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4077 if (encoding) {
4078 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4079 }
4080
4081 proto_tree_set_float(new_fi, value);
4082
4083 return proto_tree_add_node(tree, new_fi);
4084}
4085
4086proto_item *
4087proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4088 const unsigned start, unsigned length,
4089 const unsigned encoding, double *retval)
4090{
4091 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4092 field_info *new_fi;
4093 double value;
4094
4095 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", 4095,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4096
4097 if (hfinfo->type != FT_DOUBLE) {
4098 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)
;
4099 }
4100
4101 if (length != 8) {
4102 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4103 }
4104
4105 /* treat any nonzero encoding as little endian for backwards compatibility */
4106 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4107 if (retval) {
4108 *retval = value;
4109 }
4110
4111 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4112
4113 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", 4113
, __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", 4113, "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", 4113, "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", 4113, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4114
4115 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4116 if (encoding) {
4117 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4118 }
4119
4120 proto_tree_set_double(new_fi, value);
4121
4122 return proto_tree_add_node(tree, new_fi);
4123}
4124
4125proto_item *
4126proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4127 const unsigned start, unsigned length,
4128 const unsigned encoding, ws_in4_addr *retval)
4129{
4130 header_field_info *hfinfo;
4131 field_info *new_fi;
4132 ws_in4_addr value;
4133
4134 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", 4134, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4134,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4134, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4135
4136 switch (hfinfo->type) {
4137 case FT_IPv4:
4138 break;
4139 default:
4140 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)
4141 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4142 }
4143
4144 if (length != FT_IPv4_LEN4)
4145 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)
4146 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4147
4148 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4149 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4150 }
4151
4152 /*
4153 * NOTE: to support code written when proto_tree_add_item() took
4154 * a bool as its last argument, with false meaning "big-endian"
4155 * and true meaning "little-endian", we treat any non-zero value
4156 * of "encoding" as meaning "little-endian".
4157 */
4158 value = tvb_get_ipv4(tvb, start);
4159 if (encoding)
4160 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))))
;
4161
4162 if (retval) {
4163 *retval = value;
4164 }
4165
4166 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4167
4168 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", 4168
, __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", 4168, "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", 4168, "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", 4168, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4169
4170 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4171
4172 proto_tree_set_ipv4(new_fi, value);
4173
4174 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4175 return proto_tree_add_node(tree, new_fi);
4176}
4177
4178proto_item *
4179proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4180 const unsigned start, unsigned length,
4181 const unsigned encoding, ws_in6_addr *addr)
4182{
4183 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4184 field_info *new_fi;
4185
4186 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", 4186,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4187
4188 switch (hfinfo->type) {
4189 case FT_IPv6:
4190 break;
4191 default:
4192 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)
4193 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4194 }
4195
4196 if (length != FT_IPv6_LEN16)
4197 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)
4198 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4199
4200 if (encoding) {
4201 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"
)
;
4202 }
4203
4204 tvb_get_ipv6(tvb, start, addr);
4205
4206 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4207
4208 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", 4208
, __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", 4208, "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", 4208, "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", 4208, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4209
4210 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4211
4212 proto_tree_set_ipv6(new_fi, addr);
4213
4214 return proto_tree_add_node(tree, new_fi);
4215}
4216
4217proto_item *
4218proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4219 const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4220
4221 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4222 field_info *new_fi;
4223
4224 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", 4224,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4225
4226 switch (hfinfo->type) {
4227 case FT_ETHER:
4228 break;
4229 default:
4230 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)
4231 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4232 }
4233
4234 if (length != FT_ETHER_LEN6)
4235 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)
4236 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4237
4238 if (encoding) {
4239 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"
)
;
4240 }
4241
4242 tvb_memcpy(tvb, retval, start, length);
4243
4244 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4245
4246 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", 4246
, __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", 4246, "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", 4246, "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", 4246, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4247
4248 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4249
4250 proto_tree_set_ether(new_fi, retval);
4251
4252 return proto_tree_add_node(tree, new_fi);
4253}
4254
4255
4256proto_item *
4257proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4258 tvbuff_t *tvb,
4259 const unsigned start, int length,
4260 const unsigned encoding,
4261 wmem_allocator_t *scope,
4262 const uint8_t **retval,
4263 unsigned *lenretval)
4264{
4265 proto_item *pi;
4266 header_field_info *hfinfo;
4267 field_info *new_fi;
4268 const uint8_t *value;
4269
4270 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", 4270, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4270,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4270, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4271
4272 switch (hfinfo->type) {
4273 case FT_STRING:
4274 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4275 break;
4276 case FT_STRINGZ:
4277 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4278 break;
4279 case FT_UINT_STRING:
4280 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4281 break;
4282 case FT_STRINGZPAD:
4283 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4284 break;
4285 case FT_STRINGZTRUNC:
4286 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4287 break;
4288 default:
4289 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)
4290 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)
;
4291 }
4292
4293 if (retval)
4294 *retval = value;
4295
4296 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4297
4298 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4298
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4298, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4298, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4298, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4299
4300 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4301
4302 proto_tree_set_string(new_fi, (const char*)value);
4303
4304 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4305
4306 pi = proto_tree_add_node(tree, new_fi);
4307
4308 switch (hfinfo->type) {
4309
4310 case FT_STRINGZ:
4311 case FT_STRINGZPAD:
4312 case FT_STRINGZTRUNC:
4313 case FT_UINT_STRING:
4314 break;
4315
4316 case FT_STRING:
4317 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4318 break;
4319
4320 default:
4321 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4321
, __func__, "assertion \"not reached\" failed")
;
4322 }
4323
4324 return pi;
4325}
4326
4327proto_item *
4328proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4329 const unsigned start, int length,
4330 const unsigned encoding, wmem_allocator_t *scope,
4331 const uint8_t **retval)
4332{
4333 unsigned item_length; // Param cannot be NULL in function below
4334 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4335 tvb, start, length, encoding, scope, retval, &item_length);
4336}
4337
4338proto_item *
4339proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4340 tvbuff_t *tvb,
4341 const unsigned start, int length,
4342 const unsigned encoding,
4343 wmem_allocator_t *scope,
4344 char **retval,
4345 unsigned *lenretval)
4346{
4347 proto_item *pi;
4348 header_field_info *hfinfo;
4349 field_info *new_fi;
4350 const uint8_t *value;
4351 uint32_t n = 0;
4352
4353 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", 4353, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4353,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4353, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4354
4355 switch (hfinfo->type) {
4356 case FT_STRING:
4357 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4358 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4359 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4360 break;
4361 case FT_STRINGZ:
4362 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4363 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4364 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4365 break;
4366 case FT_UINT_STRING:
4367 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4368 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4369 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4370 break;
4371 case FT_STRINGZPAD:
4372 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4373 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4374 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4375 break;
4376 case FT_STRINGZTRUNC:
4377 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4378 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4379 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4380 break;
4381 case FT_BYTES:
4382 tvb_ensure_bytes_exist(tvb, start, length);
4383 value = tvb_get_ptr(tvb, start, length);
4384 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4385 *lenretval = length;
4386 break;
4387 case FT_UINT_BYTES:
4388 n = get_uint_value(tree, tvb, start, length, encoding);
4389 tvb_ensure_bytes_exist(tvb, start + length, n);
4390 value = tvb_get_ptr(tvb, start + length, n);
4391 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4392 *lenretval = length + n;
4393 break;
4394 default:
4395 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)
4396 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)
;
4397 }
4398
4399 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4400
4401 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", 4401
, __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", 4401, "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", 4401, "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", 4401, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4402
4403 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4404
4405 switch (hfinfo->type) {
4406
4407 case FT_STRING:
4408 case FT_STRINGZ:
4409 case FT_UINT_STRING:
4410 case FT_STRINGZPAD:
4411 case FT_STRINGZTRUNC:
4412 proto_tree_set_string(new_fi, (const char*)value);
4413 break;
4414
4415 case FT_BYTES:
4416 proto_tree_set_bytes(new_fi, value, length);
4417 break;
4418
4419 case FT_UINT_BYTES:
4420 proto_tree_set_bytes(new_fi, value, n);
4421 break;
4422
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 pi = proto_tree_add_node(tree, new_fi);
4430
4431 switch (hfinfo->type) {
4432
4433 case FT_STRINGZ:
4434 case FT_STRINGZPAD:
4435 case FT_STRINGZTRUNC:
4436 case FT_UINT_STRING:
4437 break;
4438
4439 case FT_STRING:
4440 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4441 break;
4442
4443 case FT_BYTES:
4444 case FT_UINT_BYTES:
4445 break;
4446
4447 default:
4448 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4448
, __func__, "assertion \"not reached\" failed")
;
4449 }
4450
4451 return pi;
4452}
4453
4454proto_item *
4455proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4456 tvbuff_t *tvb,
4457 const unsigned start, int length,
4458 const unsigned encoding,
4459 wmem_allocator_t *scope,
4460 char **retval)
4461{
4462 unsigned item_length; // Param cannot be NULL in function below
4463 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4464 tvb, start, length, encoding, scope, retval, &item_length);
4465}
4466
4467proto_item *
4468proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4469 tvbuff_t *tvb,
4470 const unsigned start, int length, const unsigned encoding,
4471 wmem_allocator_t *scope, char **retval)
4472{
4473 header_field_info *hfinfo;
4474 field_info *new_fi;
4475 nstime_t time_stamp;
4476 int flags;
4477
4478 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", 4478, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4478,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4478, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4479
4480 switch (hfinfo->type) {
4481 case FT_ABSOLUTE_TIME:
4482 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4483 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4484 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4485 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4486 }
4487 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4488 break;
4489 case FT_RELATIVE_TIME:
4490 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4491 *retval = rel_time_to_secs_str(scope, &time_stamp);
4492 break;
4493 default:
4494 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)
4495 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4496 }
4497
4498 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4499
4500 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4500
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4500, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4500, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4500, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4501
4502 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4503
4504 switch (hfinfo->type) {
4505
4506 case FT_ABSOLUTE_TIME:
4507 case FT_RELATIVE_TIME:
4508 proto_tree_set_time(new_fi, &time_stamp);
4509 break;
4510 default:
4511 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4511
, __func__, "assertion \"not reached\" failed")
;
4512 }
4513
4514 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4515
4516 return proto_tree_add_node(tree, new_fi);
4517}
4518
4519/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4520 and returns proto_item* */
4521proto_item *
4522ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4523 const unsigned encoding)
4524{
4525 field_info *new_fi;
4526 header_field_info *hfinfo;
4527 int item_length;
4528 unsigned offset;
4529
4530 offset = ptvc->offset;
4531 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", 4531, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4531,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4531, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4532 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4533 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4534
4535 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4536
4537 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4538
4539 /* Coast clear. Try and fake it */
4540 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", 4540
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4540, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4540, "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", 4540, __func__, "Adding %s would put more than %d 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); } } }
;
4541
4542 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4543
4544 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4545 offset, length, encoding);
4546}
4547
4548/* Add an item to a proto_tree, using the text label registered to that item;
4549 the item is extracted from the tvbuff handed to it. */
4550proto_item *
4551proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4552 const unsigned start, int length, const unsigned encoding)
4553{
4554 field_info *new_fi;
4555 int item_length;
4556
4557 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", 4557,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4558
4559 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4560 test_length(hfinfo, tvb, start, item_length, encoding);
4561
4562 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4563
4564 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", 4564
, __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", 4564, "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", 4564, "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", 4564, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4565
4566 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4567
4568 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4569}
4570
4571proto_item *
4572proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4573 const unsigned start, int length, const unsigned encoding)
4574{
4575 register header_field_info *hfinfo;
4576
4577 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", 4577, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4577,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4577, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4578 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4579}
4580
4581/* Add an item to a proto_tree, using the text label registered to that item;
4582 the item is extracted from the tvbuff handed to it.
4583
4584 Return the length of the item through the pointer. */
4585proto_item *
4586proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4587 tvbuff_t *tvb, const unsigned start,
4588 int length, const unsigned encoding,
4589 unsigned *lenretval)
4590{
4591 field_info *new_fi;
4592 int item_length;
4593 proto_item *item;
4594
4595 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", 4595,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4596
4597 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4598 test_length(hfinfo, tvb, start, item_length, encoding);
4599
4600 if (!tree) {
4601 /*
4602 * We need to get the correct item length here.
4603 * That's normally done by proto_tree_new_item(),
4604 * but we won't be calling it.
4605 */
4606 *lenretval = get_full_length(hfinfo, tvb, start, length,
4607 item_length, encoding);
4608 return NULL((void*)0);
4609 }
4610
4611 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4612 /*((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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4613 * 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4614 * 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4615 */((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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4616 *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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4617 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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4618 })((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", 4618
, __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", 4618, "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", 4618, "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", 4618
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4619
4620 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4621
4622 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4623 *lenretval = new_fi->length;
4624 return item;
4625}
4626
4627proto_item *
4628proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4629 const unsigned start, int length,
4630 const unsigned encoding, unsigned *lenretval)
4631{
4632 register header_field_info *hfinfo;
4633
4634 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", 4634, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4634,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4634, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4635 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4636}
4637
4638/* which FT_ types can use proto_tree_add_bytes_item() */
4639static inline bool_Bool
4640validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4641{
4642 return (type == FT_BYTES ||
4643 type == FT_UINT_BYTES ||
4644 type == FT_OID ||
4645 type == FT_REL_OID ||
4646 type == FT_SYSTEM_ID );
4647}
4648
4649/* Note: this does no validation that the byte array of an FT_OID or
4650 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4651 so I think it's ok to continue not validating it?
4652 */
4653proto_item *
4654proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4655 const unsigned start, unsigned length,
4656 const unsigned encoding,
4657 GByteArray *retval, unsigned *endoff, int *err)
4658{
4659 field_info *new_fi;
4660 GByteArray *bytes = retval;
4661 GByteArray *created_bytes = NULL((void*)0);
4662 bool_Bool failed = false0;
4663 uint32_t n = 0;
4664 header_field_info *hfinfo;
4665 bool_Bool generate = (bytes || tree) ? true1 : false0;
4666
4667 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", 4667, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4667,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4667, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4668
4669 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", 4669,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4670
4671 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", 4672, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4672 "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", 4672, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4673
4674 if (length == 0) {
4675 return NULL((void*)0);
4676 }
4677
4678 if (encoding & ENC_STR_NUM0x01000000) {
4679 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"
)
;
4680 }
4681
4682 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4683 if (hfinfo->type == FT_UINT_BYTES) {
4684 /* can't decode FT_UINT_BYTES from strings */
4685 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")
4686 "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")
;
4687 }
4688
4689 unsigned hex_encoding = encoding;
4690 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4691 /* If none of the separator values are used,
4692 * assume no separator (the common case). */
4693 hex_encoding |= ENC_SEP_NONE0x00010000;
4694#if 0
4695 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")
4696 "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")
;
4697#endif
4698 }
4699
4700 if (!bytes) {
4701 /* caller doesn't care about return value, but we need it to
4702 call tvb_get_string_bytes() and set the tree later */
4703 bytes = created_bytes = g_byte_array_new();
4704 }
4705
4706 /*
4707 * bytes might be NULL after this, but can't add expert
4708 * error until later; if it's NULL, just note that
4709 * it failed.
4710 */
4711 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4712 if (bytes == NULL((void*)0))
4713 failed = true1;
4714 }
4715 else if (generate) {
4716 tvb_ensure_bytes_exist(tvb, start, length);
4717
4718 if (hfinfo->type == FT_UINT_BYTES) {
4719 n = length; /* n is now the "header" length */
4720 length = get_uint_value(tree, tvb, start, n, encoding);
4721 /* length is now the value's length; only store the value in the array */
4722 tvb_ensure_bytes_exist(tvb, start + n, length);
4723 if (!bytes) {
4724 /* caller doesn't care about return value, but
4725 * we may need it to set the tree later */
4726 bytes = created_bytes = g_byte_array_new();
4727 }
4728 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4729 }
4730 else if (length > 0) {
4731 if (!bytes) {
4732 /* caller doesn't care about return value, but
4733 * we may need it to set the tree later */
4734 bytes = created_bytes = g_byte_array_new();
4735 }
4736 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4737 }
4738
4739 if (endoff)
4740 *endoff = start + n + length;
4741 }
4742
4743 if (err)
4744 *err = failed ? EINVAL22 : 0;
4745
4746 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); }
4747 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4748 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); }
4749 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); }
4750 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); }
4751 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4752 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4753
4754 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", 4760
, __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", 4760, "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", 4760, "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", 4760
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4755 {((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", 4760
, __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", 4760, "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", 4760, "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", 4760
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4756 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", 4760
, __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", 4760, "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", 4760, "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", 4760
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4757 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", 4760
, __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", 4760, "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", 4760, "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", 4760
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4758 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", 4760
, __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", 4760, "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", 4760, "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", 4760
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4759 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", 4760
, __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", 4760, "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", 4760, "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", 4760
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4760 } )((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", 4760
, __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", 4760, "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", 4760, "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", 4760
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4761
4762 /* n will be zero except when it's a FT_UINT_BYTES */
4763 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4764
4765 if (encoding & ENC_STRING0x07000000) {
4766 if (failed)
4767 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4768
4769 if (bytes)
4770 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4771 else
4772 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4773
4774 if (created_bytes)
4775 g_byte_array_free(created_bytes, true1);
4776 }
4777 else {
4778 /* n will be zero except when it's a FT_UINT_BYTES */
4779 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4780
4781 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4782 * use the byte array created above in this case.
4783 */
4784 if (created_bytes)
4785 g_byte_array_free(created_bytes, true1);
4786
4787 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4788 (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)
;
4789 }
4790
4791 return proto_tree_add_node(tree, new_fi);
4792}
4793
4794
4795proto_item *
4796proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4797 const unsigned start, const unsigned length,
4798 const unsigned encoding,
4799 nstime_t *retval, unsigned *endoff, int *err)
4800{
4801 field_info *new_fi;
4802 nstime_t time_stamp;
4803 int saved_err = 0;
4804 header_field_info *hfinfo;
4805
4806 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", 4806, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4806,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4806, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4807
4808 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", 4808,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4809
4810 if (length == 0) {
4811 if(retval) {
4812 nstime_set_zero(retval);
4813 }
4814 return NULL((void*)0);
4815 }
4816
4817 nstime_set_zero(&time_stamp);
4818
4819 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4820 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", 4820, ((hfinfo))->abbrev))))
;
4821 /* The only string format that could be a relative time is
4822 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4823 * relative to "now" currently.
4824 */
4825 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4826 saved_err = EINVAL22;
4827 }
4828 else {
4829 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", 4829, ((hfinfo))->abbrev))))
;
4830 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4831
4832 tvb_ensure_bytes_exist(tvb, start, length);
4833 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4834 if (endoff) *endoff = start + length;
4835 }
4836
4837 if (err) *err = saved_err;
4838
4839 if (retval) {
4840 retval->secs = time_stamp.secs;
4841 retval->nsecs = time_stamp.nsecs;
4842 }
4843
4844 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4845
4846 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", 4846
, __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", 4846, "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", 4846, "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", 4846, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4847
4848 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4849
4850 proto_tree_set_time(new_fi, &time_stamp);
4851
4852 if (encoding & ENC_STRING0x07000000) {
4853 if (saved_err)
4854 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4855 }
4856 else {
4857 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4858 (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)
;
4859 }
4860
4861 return proto_tree_add_node(tree, new_fi);
4862}
4863
4864/* Add a FT_NONE to a proto_tree */
4865proto_item *
4866proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4867 const unsigned start, int length, const char *format,
4868 ...)
4869{
4870 proto_item *pi;
4871 va_list ap;
4872 header_field_info *hfinfo;
4873
4874 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4875
4876 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", 4876
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4876, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4876, "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", 4876, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4877
4878 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", 4878
, ((hfinfo))->abbrev))))
;
4879
4880 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4881
4882 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4882, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4883
4884 va_start(ap, format)__builtin_va_start(ap, format);
4885 proto_tree_set_representation(pi, format, ap);
4886 va_end(ap)__builtin_va_end(ap);
4887
4888 /* no value to set for FT_NONE */
4889 return pi;
4890}
4891
4892/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4893 * offset, and returns proto_item* */
4894proto_item *
4895ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4896 const unsigned encoding)
4897{
4898 proto_item *item;
4899
4900 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4901 length, encoding);
4902
4903 return item;
4904}
4905
4906/* Advance the ptvcursor's offset within its tvbuff without
4907 * adding anything to the proto_tree. */
4908void
4909ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4910{
4911 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4912 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4913 }
4914}
4915
4916
4917static void
4918proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4919{
4920 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4920, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4921 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4922}
4923
4924/* Add a FT_PROTOCOL to a proto_tree */
4925proto_item *
4926proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4927 unsigned start, int length, const char *format, ...)
4928{
4929 proto_item *pi;
4930 field_info *new_fi;
4931 tvbuff_t *protocol_tvb;
4932 va_list ap;
4933 header_field_info *hfinfo;
4934 char* protocol_rep;
4935
4936 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4937
4938 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", 4938
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4938, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4938, "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", 4938, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4939
4940 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"
, 4940, ((hfinfo))->abbrev))))
;
4941
4942 /*
4943 * This can throw an exception when it calls get_hfi_length before
4944 * it allocates anything, if length is nonzero and start is past
4945 * the end of the tvb. Afterwards it can't throw an exception,
4946 * as length is clamped to the captured length remaining.
4947 */
4948 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4949 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4950 /* Start the protocol_tvb at the correct start offset, but allow it
4951 * to be lengthened later via finfo_set_len. */
4952 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4953
4954 va_start(ap, format)__builtin_va_start(ap, format);
4955 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4956 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4957 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)
;
4958 va_end(ap)__builtin_va_end(ap);
4959
4960 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4960, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4961
4962 va_start(ap, format)__builtin_va_start(ap, format);
4963 proto_tree_set_representation(pi, format, ap);
4964 va_end(ap)__builtin_va_end(ap);
4965
4966 return pi;
4967}
4968
4969/* Add a FT_BYTES to a proto_tree */
4970proto_item *
4971proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4972 int length, const uint8_t *start_ptr)
4973{
4974 proto_item *pi;
4975 header_field_info *hfinfo;
4976 int item_length;
4977
4978 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", 4978, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4978,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4978, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4979 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4980 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4981
4982 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4983
4984 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", 4984
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4984, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4984, "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", 4984, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4985
4986 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",
4986, ((hfinfo))->abbrev))))
;
4987
4988 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4989 start_ptr = tvb_get_ptr(tvb, start, length);
4990
4991 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4992 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4993
4994 return pi;
4995}
4996
4997/* Add a FT_BYTES to a proto_tree */
4998proto_item *
4999proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5000 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
5001{
5002 proto_item *pi;
5003 header_field_info *hfinfo;
5004 int item_length;
5005
5006 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", 5006, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5006,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5006, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5007 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
5008 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5009
5010 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5011
5012 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", 5012
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5012, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5012, "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", 5012, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5013
5014 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",
5014, ((hfinfo))->abbrev))))
;
5015
5016 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
5017 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
5018
5019 return pi;
5020}
5021
5022proto_item *
5023proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5024 unsigned start, int length,
5025 const uint8_t *start_ptr,
5026 const char *format, ...)
5027{
5028 proto_item *pi;
5029 va_list ap;
5030
5031 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5032
5033 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; }
;
5034
5035 va_start(ap, format)__builtin_va_start(ap, format);
5036 proto_tree_set_representation_value(pi, format, ap);
5037 va_end(ap)__builtin_va_end(ap);
5038
5039 return pi;
5040}
5041
5042proto_item *
5043proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5044 unsigned start, int length, const uint8_t *start_ptr,
5045 const char *format, ...)
5046{
5047 proto_item *pi;
5048 va_list ap;
5049
5050 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5051
5052 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; }
;
5053
5054 va_start(ap, format)__builtin_va_start(ap, format);
5055 proto_tree_set_representation(pi, format, ap);
5056 va_end(ap)__builtin_va_end(ap);
5057
5058 return pi;
5059}
5060
5061static void
5062proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
5063{
5064 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5064, "length >= 0"
))))
;
5065 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", 5065, "start_ptr != ((void*)0) || length == 0"
))))
;
5066
5067 fvalue_set_bytes_data(fi->value, start_ptr, length);
5068}
5069
5070
5071static void
5072proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5073{
5074 tvb_ensure_bytes_exist(tvb, offset, length);
5075 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5076}
5077
5078static void
5079proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5080{
5081 GByteArray *bytes;
5082
5083 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5083, "value != ((void*)0)"
))))
;
5084
5085 bytes = byte_array_dup(value);
5086
5087 fvalue_set_byte_array(fi->value, bytes);
5088}
5089
5090/* Add a FT_*TIME to a proto_tree */
5091proto_item *
5092proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5093 unsigned length, const nstime_t *value_ptr)
5094{
5095 proto_item *pi;
5096 header_field_info *hfinfo;
5097
5098 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5099
5100 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", 5100
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5100, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5100, "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", 5100, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5101
5102 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", 5102, ((hfinfo))->abbrev))))
;
5103
5104 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5105 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5106
5107 return pi;
5108}
5109
5110proto_item *
5111proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5112 unsigned start, unsigned length, nstime_t *value_ptr,
5113 const char *format, ...)
5114{
5115 proto_item *pi;
5116 va_list ap;
5117
5118 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5119 if (pi != tree) {
5120 va_start(ap, format)__builtin_va_start(ap, format);
5121 proto_tree_set_representation_value(pi, format, ap);
5122 va_end(ap)__builtin_va_end(ap);
5123 }
5124
5125 return pi;
5126}
5127
5128proto_item *
5129proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5130 unsigned start, unsigned length, nstime_t *value_ptr,
5131 const char *format, ...)
5132{
5133 proto_item *pi;
5134 va_list ap;
5135
5136 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5137 if (pi != tree) {
5138 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5138, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5139
5140 va_start(ap, format)__builtin_va_start(ap, format);
5141 proto_tree_set_representation(pi, format, ap);
5142 va_end(ap)__builtin_va_end(ap);
5143 }
5144
5145 return pi;
5146}
5147
5148/* Set the FT_*TIME value */
5149static void
5150proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5151{
5152 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5152, "value_ptr != ((void*)0)"
))))
;
5153
5154 fvalue_set_time(fi->value, value_ptr);
5155}
5156
5157/* Add a FT_IPXNET to a proto_tree */
5158proto_item *
5159proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5160 unsigned length, uint32_t value)
5161{
5162 proto_item *pi;
5163 header_field_info *hfinfo;
5164
5165 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5166
5167 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", 5167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5167, "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", 5167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5168
5169 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"
, 5169, ((hfinfo))->abbrev))))
;
5170
5171 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5172 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5173
5174 return pi;
5175}
5176
5177proto_item *
5178proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5179 unsigned start, unsigned length, uint32_t value,
5180 const char *format, ...)
5181{
5182 proto_item *pi;
5183 va_list ap;
5184
5185 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5186 if (pi != tree) {
5187 va_start(ap, format)__builtin_va_start(ap, format);
5188 proto_tree_set_representation_value(pi, format, ap);
5189 va_end(ap)__builtin_va_end(ap);
5190 }
5191
5192 return pi;
5193}
5194
5195proto_item *
5196proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5197 unsigned start, unsigned length, uint32_t value,
5198 const char *format, ...)
5199{
5200 proto_item *pi;
5201 va_list ap;
5202
5203 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5204 if (pi != tree) {
5205 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5205, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5206
5207 va_start(ap, format)__builtin_va_start(ap, format);
5208 proto_tree_set_representation(pi, format, ap);
5209 va_end(ap)__builtin_va_end(ap);
5210 }
5211
5212 return pi;
5213}
5214
5215/* Set the FT_IPXNET value */
5216static void
5217proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5218{
5219 fvalue_set_uinteger(fi->value, value);
5220}
5221
5222/* Add a FT_IPv4 to a proto_tree */
5223proto_item *
5224proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5225 unsigned length, ws_in4_addr value)
5226{
5227 proto_item *pi;
5228 header_field_info *hfinfo;
5229
5230 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5231
5232 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", 5232
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5232, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5232, "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", 5232, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5233
5234 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", 5234
, ((hfinfo))->abbrev))))
;
5235
5236 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5237 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5238
5239 return pi;
5240}
5241
5242proto_item *
5243proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5244 unsigned start, unsigned length, ws_in4_addr value,
5245 const char *format, ...)
5246{
5247 proto_item *pi;
5248 va_list ap;
5249
5250 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5251 if (pi != tree) {
5252 va_start(ap, format)__builtin_va_start(ap, format);
5253 proto_tree_set_representation_value(pi, format, ap);
5254 va_end(ap)__builtin_va_end(ap);
5255 }
5256
5257 return pi;
5258}
5259
5260proto_item *
5261proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5262 unsigned start, unsigned length, ws_in4_addr value,
5263 const char *format, ...)
5264{
5265 proto_item *pi;
5266 va_list ap;
5267
5268 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5269 if (pi != tree) {
5270 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5270, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5271
5272 va_start(ap, format)__builtin_va_start(ap, format);
5273 proto_tree_set_representation(pi, format, ap);
5274 va_end(ap)__builtin_va_end(ap);
5275 }
5276
5277 return pi;
5278}
5279
5280/* Set the FT_IPv4 value */
5281static void
5282proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5283{
5284 ipv4_addr_and_mask ipv4;
5285 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5286 fvalue_set_ipv4(fi->value, &ipv4);
5287}
5288
5289/* Add a FT_IPv6 to a proto_tree */
5290proto_item *
5291proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5292 unsigned length, const ws_in6_addr *value)
5293{
5294 proto_item *pi;
5295 header_field_info *hfinfo;
5296
5297 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5298
5299 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", 5299
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5299, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5299, "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", 5299, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5300
5301 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", 5301
, ((hfinfo))->abbrev))))
;
5302
5303 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5304 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5305
5306 return pi;
5307}
5308
5309proto_item *
5310proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5311 unsigned start, unsigned length,
5312 const ws_in6_addr *value_ptr,
5313 const char *format, ...)
5314{
5315 proto_item *pi;
5316 va_list ap;
5317
5318 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5319 if (pi != tree) {
5320 va_start(ap, format)__builtin_va_start(ap, format);
5321 proto_tree_set_representation_value(pi, format, ap);
5322 va_end(ap)__builtin_va_end(ap);
5323 }
5324
5325 return pi;
5326}
5327
5328proto_item *
5329proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5330 unsigned start, unsigned length,
5331 const ws_in6_addr *value_ptr,
5332 const char *format, ...)
5333{
5334 proto_item *pi;
5335 va_list ap;
5336
5337 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5338 if (pi != tree) {
5339 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5339, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5340
5341 va_start(ap, format)__builtin_va_start(ap, format);
5342 proto_tree_set_representation(pi, format, ap);
5343 va_end(ap)__builtin_va_end(ap);
5344 }
5345
5346 return pi;
5347}
5348
5349/* Set the FT_IPv6 value */
5350static void
5351proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5352{
5353 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5353, "value != ((void*)0)"
))))
;
5354 ipv6_addr_and_prefix ipv6;
5355 ipv6.addr = *value;
5356 ipv6.prefix = 128;
5357 fvalue_set_ipv6(fi->value, &ipv6);
5358}
5359
5360static void
5361proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5362{
5363 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5364}
5365
5366/* Set the FT_FCWWN value */
5367static void
5368proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5369{
5370 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5370, "value_ptr != ((void*)0)"
))))
;
5371 fvalue_set_fcwwn(fi->value, value_ptr);
5372}
5373
5374static void
5375proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5376{
5377 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5378}
5379
5380/* Add a FT_GUID to a proto_tree */
5381proto_item *
5382proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5383 unsigned length, const e_guid_t *value_ptr)
5384{
5385 proto_item *pi;
5386 header_field_info *hfinfo;
5387
5388 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5389
5390 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", 5390
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5390, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5390, "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", 5390, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5391
5392 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", 5392
, ((hfinfo))->abbrev))))
;
5393
5394 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5395 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5396
5397 return pi;
5398}
5399
5400proto_item *
5401proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5402 unsigned start, unsigned length,
5403 const e_guid_t *value_ptr,
5404 const char *format, ...)
5405{
5406 proto_item *pi;
5407 va_list ap;
5408
5409 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5410 if (pi != tree) {
5411 va_start(ap, format)__builtin_va_start(ap, format);
5412 proto_tree_set_representation_value(pi, format, ap);
5413 va_end(ap)__builtin_va_end(ap);
5414 }
5415
5416 return pi;
5417}
5418
5419proto_item *
5420proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5421 unsigned start, unsigned length, const e_guid_t *value_ptr,
5422 const char *format, ...)
5423{
5424 proto_item *pi;
5425 va_list ap;
5426
5427 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5428 if (pi != tree) {
5429 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5429, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5430
5431 va_start(ap, format)__builtin_va_start(ap, format);
5432 proto_tree_set_representation(pi, format, ap);
5433 va_end(ap)__builtin_va_end(ap);
5434 }
5435
5436 return pi;
5437}
5438
5439/* Set the FT_GUID value */
5440static void
5441proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5442{
5443 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5443, "value_ptr != ((void*)0)"
))))
;
5444 fvalue_set_guid(fi->value, value_ptr);
5445}
5446
5447static void
5448proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5449 const unsigned encoding)
5450{
5451 e_guid_t guid;
5452
5453 tvb_get_guid(tvb, start, &guid, encoding);
5454 proto_tree_set_guid(fi, &guid);
5455}
5456
5457/* Add a FT_OID to a proto_tree */
5458proto_item *
5459proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5460 unsigned length, const uint8_t* value_ptr)
5461{
5462 proto_item *pi;
5463 header_field_info *hfinfo;
5464
5465 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5466
5467 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", 5467
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5467, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5467, "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", 5467, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5468
5469 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", 5469
, ((hfinfo))->abbrev))))
;
5470
5471 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5472 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5473
5474 return pi;
5475}
5476
5477proto_item *
5478proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5479 unsigned start, unsigned length,
5480 const uint8_t* value_ptr,
5481 const char *format, ...)
5482{
5483 proto_item *pi;
5484 va_list ap;
5485
5486 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5487 if (pi != tree) {
5488 va_start(ap, format)__builtin_va_start(ap, format);
5489 proto_tree_set_representation_value(pi, format, ap);
5490 va_end(ap)__builtin_va_end(ap);
5491 }
5492
5493 return pi;
5494}
5495
5496proto_item *
5497proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5498 unsigned start, unsigned length, const uint8_t* value_ptr,
5499 const char *format, ...)
5500{
5501 proto_item *pi;
5502 va_list ap;
5503
5504 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5505 if (pi != tree) {
5506 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5506, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5507
5508 va_start(ap, format)__builtin_va_start(ap, format);
5509 proto_tree_set_representation(pi, format, ap);
5510 va_end(ap)__builtin_va_end(ap);
5511 }
5512
5513 return pi;
5514}
5515
5516/* Set the FT_OID value */
5517static void
5518proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5519{
5520 GByteArray *bytes;
5521
5522 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", 5522, "value_ptr != ((void*)0) || length == 0"
))))
;
5523
5524 bytes = g_byte_array_new();
5525 if (length > 0) {
5526 g_byte_array_append(bytes, value_ptr, length);
5527 }
5528 fvalue_set_byte_array(fi->value, bytes);
5529}
5530
5531static void
5532proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5533{
5534 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5535}
5536
5537/* Set the FT_SYSTEM_ID value */
5538static void
5539proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5540{
5541 GByteArray *bytes;
5542
5543 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", 5543, "value_ptr != ((void*)0) || length == 0"
))))
;
5544
5545 bytes = g_byte_array_new();
5546 if (length > 0) {
5547 g_byte_array_append(bytes, value_ptr, length);
5548 }
5549 fvalue_set_byte_array(fi->value, bytes);
5550}
5551
5552static void
5553proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5554{
5555 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5556}
5557
5558/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5559 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5560 * is destroyed. */
5561proto_item *
5562proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5563 int length, const char* value)
5564{
5565 proto_item *pi;
5566 header_field_info *hfinfo;
5567 int item_length;
5568
5569 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", 5569, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5569,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5569, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5570 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5571 /*
5572 * Special case - if the length is 0, skip the test, so that
5573 * we can have an empty string right after the end of the
5574 * packet. (This handles URL-encoded forms where the last field
5575 * has no value so the form ends right after the =.)
5576 *
5577 * XXX - length zero makes sense for FT_STRING, and more or less
5578 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5579 * for FT_STRINGZ (except that a number of fields that should be
5580 * one of the others are actually registered as FT_STRINGZ.)
5581 */
5582 if (item_length != 0)
5583 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5584
5585 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5586
5587 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", 5587
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5587, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5587, "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", 5587, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5588
5589 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", 5589, ((hfinfo))->abbrev))))
;
5590
5591 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5592 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5592, "length >= 0"
))))
;
5593
5594 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", 5594, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5595 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5596
5597 return pi;
5598}
5599
5600proto_item *
5601proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5602 unsigned start, int length, const char* value,
5603 const char *format,
5604 ...)
5605{
5606 proto_item *pi;
5607 va_list ap;
5608
5609 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5610 if (pi != tree) {
5611 va_start(ap, format)__builtin_va_start(ap, format);
5612 proto_tree_set_representation_value(pi, format, ap);
5613 va_end(ap)__builtin_va_end(ap);
5614 }
5615
5616 return pi;
5617}
5618
5619proto_item *
5620proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5621 unsigned start, int length, const char* value,
5622 const char *format, ...)
5623{
5624 proto_item *pi;
5625 va_list ap;
5626
5627 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5628 if (pi != tree) {
5629 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5629, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5630
5631 va_start(ap, format)__builtin_va_start(ap, format);
5632 proto_tree_set_representation(pi, format, ap);
5633 va_end(ap)__builtin_va_end(ap);
5634 }
5635
5636 return pi;
5637}
5638
5639/* Set the FT_STRING value */
5640static void
5641proto_tree_set_string(field_info *fi, const char* value)
5642{
5643 if (value) {
5644 fvalue_set_string(fi->value, value);
5645 } else {
5646 /*
5647 * XXX - why is a null value for a string field
5648 * considered valid?
5649 */
5650 fvalue_set_string(fi->value, "[ Null ]");
5651 }
5652}
5653
5654/* Set the FT_AX25 value */
5655static void
5656proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5657{
5658 fvalue_set_ax25(fi->value, value);
5659}
5660
5661static void
5662proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5663{
5664 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5665}
5666
5667/* Set the FT_VINES value */
5668static void
5669proto_tree_set_vines(field_info *fi, const uint8_t* value)
5670{
5671 fvalue_set_vines(fi->value, value);
5672}
5673
5674static void
5675proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5676{
5677 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5678}
5679
5680/* Add a FT_ETHER to a proto_tree */
5681proto_item *
5682proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5683 unsigned length, const uint8_t* value)
5684{
5685 proto_item *pi;
5686 header_field_info *hfinfo;
5687
5688 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5689
5690 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", 5690
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5690, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5690, "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", 5690, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5691
5692 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",
5692, ((hfinfo))->abbrev))))
;
5693
5694 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5695 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5696
5697 return pi;
5698}
5699
5700proto_item *
5701proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5702 unsigned start, unsigned length, const uint8_t* value,
5703 const char *format, ...)
5704{
5705 proto_item *pi;
5706 va_list ap;
5707
5708 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5709 if (pi != tree) {
5710 va_start(ap, format)__builtin_va_start(ap, format);
5711 proto_tree_set_representation_value(pi, format, ap);
5712 va_end(ap)__builtin_va_end(ap);
5713 }
5714
5715 return pi;
5716}
5717
5718proto_item *
5719proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5720 unsigned start, unsigned length, const uint8_t* value,
5721 const char *format, ...)
5722{
5723 proto_item *pi;
5724 va_list ap;
5725
5726 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5727 if (pi != tree) {
5728 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5728, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5729
5730 va_start(ap, format)__builtin_va_start(ap, format);
5731 proto_tree_set_representation(pi, format, ap);
5732 va_end(ap)__builtin_va_end(ap);
5733 }
5734
5735 return pi;
5736}
5737
5738/* Set the FT_ETHER value */
5739static void
5740proto_tree_set_ether(field_info *fi, const uint8_t* value)
5741{
5742 fvalue_set_ether(fi->value, value);
5743}
5744
5745static void
5746proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5747{
5748 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5749}
5750
5751/* Add a FT_BOOLEAN to a proto_tree */
5752proto_item *
5753proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5754 unsigned length, uint64_t value)
5755{
5756 proto_item *pi;
5757 header_field_info *hfinfo;
5758
5759 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5760
5761 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", 5761
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5761, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5761, "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", 5761, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5762
5763 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"
, 5763, ((hfinfo))->abbrev))))
;
5764
5765 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5766 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5767
5768 return pi;
5769}
5770
5771proto_item *
5772proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5773 tvbuff_t *tvb, unsigned start, unsigned length,
5774 uint64_t value, const char *format, ...)
5775{
5776 proto_item *pi;
5777 va_list ap;
5778
5779 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5780 if (pi != tree) {
5781 va_start(ap, format)__builtin_va_start(ap, format);
5782 proto_tree_set_representation_value(pi, format, ap);
5783 va_end(ap)__builtin_va_end(ap);
5784 }
5785
5786 return pi;
5787}
5788
5789proto_item *
5790proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5791 unsigned start, unsigned length, uint64_t value,
5792 const char *format, ...)
5793{
5794 proto_item *pi;
5795 va_list ap;
5796
5797 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5798 if (pi != tree) {
5799 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5799, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5800
5801 va_start(ap, format)__builtin_va_start(ap, format);
5802 proto_tree_set_representation(pi, format, ap);
5803 va_end(ap)__builtin_va_end(ap);
5804 }
5805
5806 return pi;
5807}
5808
5809/* Set the FT_BOOLEAN value */
5810static void
5811proto_tree_set_boolean(field_info *fi, uint64_t value)
5812{
5813 proto_tree_set_uint64(fi, value);
5814}
5815
5816/* Generate, into "buf", a string showing the bits of a bitfield.
5817 Return a pointer to the character after that string. */
5818static char *
5819other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5820{
5821 int i = 0;
5822 uint64_t bit;
5823 char *p;
5824
5825 p = buf;
5826
5827 /* This is a devel error. It is safer to stop here. */
5828 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5828, "width >= 1"
))))
;
5829
5830 bit = UINT64_C(1)1UL << (width - 1);
5831 for (;;) {
5832 if (mask & bit) {
5833 /* This bit is part of the field. Show its value. */
5834 if (val & bit)
5835 *p++ = '1';
5836 else
5837 *p++ = '0';
5838 } else {
5839 /* This bit is not part of the field. */
5840 *p++ = '.';
5841 }
5842 bit >>= 1;
5843 i++;
5844 if (i >= width)
5845 break;
5846 if (i % 4 == 0)
5847 *p++ = ' ';
5848 }
5849 *p = '\0';
5850 return p;
5851}
5852
5853static char *
5854decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5855{
5856 char *p;
5857
5858 p = other_decode_bitfield_value(buf, val, mask, width);
5859 p = g_stpcpy(p, " = ");
5860
5861 return p;
5862}
5863
5864static char *
5865other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5866{
5867 int i = 0;
5868 uint64_t bit;
5869 char *p;
5870
5871 p = buf;
5872
5873 /* This is a devel error. It is safer to stop here. */
5874 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5874, "width >= 1"
))))
;
5875
5876 bit = UINT64_C(1)1UL << (width - 1);
5877 for (;;) {
5878 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5879 (mask & bit)) {
5880 /* This bit is part of the field. Show its value. */
5881 if (val & bit)
5882 *p++ = '1';
5883 else
5884 *p++ = '0';
5885 } else {
5886 /* This bit is not part of the field. */
5887 *p++ = '.';
5888 }
5889 bit >>= 1;
5890 i++;
5891 if (i >= width)
5892 break;
5893 if (i % 4 == 0)
5894 *p++ = ' ';
5895 }
5896
5897 *p = '\0';
5898 return p;
5899}
5900
5901static char *
5902decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5903{
5904 char *p;
5905
5906 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5907 p = g_stpcpy(p, " = ");
5908
5909 return p;
5910}
5911
5912/* Add a FT_FLOAT to a proto_tree */
5913proto_item *
5914proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5915 unsigned length, float value)
5916{
5917 proto_item *pi;
5918 header_field_info *hfinfo;
5919
5920 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5921
5922 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", 5922
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5922, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5922, "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", 5922, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5923
5924 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",
5924, ((hfinfo))->abbrev))))
;
5925
5926 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5927 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5928
5929 return pi;
5930}
5931
5932proto_item *
5933proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5934 unsigned start, unsigned length, float value,
5935 const char *format, ...)
5936{
5937 proto_item *pi;
5938 va_list ap;
5939
5940 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5941 if (pi != tree) {
5942 va_start(ap, format)__builtin_va_start(ap, format);
5943 proto_tree_set_representation_value(pi, format, ap);
5944 va_end(ap)__builtin_va_end(ap);
5945 }
5946
5947 return pi;
5948}
5949
5950proto_item *
5951proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5952 unsigned start, unsigned length, float value,
5953 const char *format, ...)
5954{
5955 proto_item *pi;
5956 va_list ap;
5957
5958 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5959 if (pi != tree) {
5960 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5960, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5961
5962 va_start(ap, format)__builtin_va_start(ap, format);
5963 proto_tree_set_representation(pi, format, ap);
5964 va_end(ap)__builtin_va_end(ap);
5965 }
5966
5967 return pi;
5968}
5969
5970/* Set the FT_FLOAT value */
5971static void
5972proto_tree_set_float(field_info *fi, float value)
5973{
5974 fvalue_set_floating(fi->value, value);
5975}
5976
5977/* Add a FT_DOUBLE to a proto_tree */
5978proto_item *
5979proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5980 unsigned length, double value)
5981{
5982 proto_item *pi;
5983 header_field_info *hfinfo;
5984
5985 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5986
5987 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", 5987
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5987, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5987, "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", 5987, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5988
5989 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"
, 5989, ((hfinfo))->abbrev))))
;
5990
5991 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5992 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5993
5994 return pi;
5995}
5996
5997proto_item *
5998proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5999 unsigned start, unsigned length, double value,
6000 const char *format, ...)
6001{
6002 proto_item *pi;
6003 va_list ap;
6004
6005 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6006 if (pi != tree) {
6007 va_start(ap, format)__builtin_va_start(ap, format);
6008 proto_tree_set_representation_value(pi, format, ap);
6009 va_end(ap)__builtin_va_end(ap);
6010 }
6011
6012 return pi;
6013}
6014
6015proto_item *
6016proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6017 unsigned start, unsigned length, double value,
6018 const char *format, ...)
6019{
6020 proto_item *pi;
6021 va_list ap;
6022
6023 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6024 if (pi != tree) {
6025 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6025, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6026
6027 va_start(ap, format)__builtin_va_start(ap, format);
6028 proto_tree_set_representation(pi, format, ap);
6029 va_end(ap)__builtin_va_end(ap);
6030 }
6031
6032 return pi;
6033}
6034
6035/* Set the FT_DOUBLE value */
6036static void
6037proto_tree_set_double(field_info *fi, double value)
6038{
6039 fvalue_set_floating(fi->value, value);
6040}
6041
6042/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
6043proto_item *
6044proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6045 unsigned length, uint32_t value)
6046{
6047 proto_item *pi = NULL((void*)0);
6048 header_field_info *hfinfo;
6049
6050 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6051
6052 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", 6052
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6052, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6052, "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", 6052, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6053
6054 switch (hfinfo->type) {
6055 case FT_CHAR:
6056 case FT_UINT8:
6057 case FT_UINT16:
6058 case FT_UINT24:
6059 case FT_UINT32:
6060 case FT_FRAMENUM:
6061 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6062 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
6063 break;
6064
6065 default:
6066 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)
6067 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)
;
6068 }
6069
6070 return pi;
6071}
6072
6073proto_item *
6074proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6075 unsigned start, unsigned length, uint32_t value,
6076 const char *format, ...)
6077{
6078 proto_item *pi;
6079 va_list ap;
6080
6081 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6082 if (pi != tree) {
6083 va_start(ap, format)__builtin_va_start(ap, format);
6084 proto_tree_set_representation_value(pi, format, ap);
6085 va_end(ap)__builtin_va_end(ap);
6086 }
6087
6088 return pi;
6089}
6090
6091proto_item *
6092proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6093 unsigned start, unsigned length, uint32_t value,
6094 const char *format, ...)
6095{
6096 proto_item *pi;
6097 va_list ap;
6098
6099 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6100 if (pi != tree) {
6101 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6101, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6102
6103 va_start(ap, format)__builtin_va_start(ap, format);
6104 proto_tree_set_representation(pi, format, ap);
6105 va_end(ap)__builtin_va_end(ap);
6106 }
6107
6108 return pi;
6109}
6110
6111/* Set the FT_UINT{8,16,24,32} value */
6112static void
6113proto_tree_set_uint(field_info *fi, uint32_t value)
6114{
6115 const header_field_info *hfinfo;
6116 uint32_t integer;
6117
6118 hfinfo = fi->hfinfo;
6119 integer = value;
6120
6121 if (hfinfo->bitmask) {
6122 /* Mask out irrelevant portions */
6123 integer &= (uint32_t)(hfinfo->bitmask);
6124
6125 /* Shift bits */
6126 integer >>= hfinfo_bitshift(hfinfo);
6127
6128 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6129 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)
;
6130 }
6131
6132 fvalue_set_uinteger(fi->value, integer);
6133}
6134
6135/* Add FT_UINT{40,48,56,64} to a proto_tree */
6136proto_item *
6137proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6138 unsigned length, uint64_t value)
6139{
6140 proto_item *pi = NULL((void*)0);
6141 header_field_info *hfinfo;
6142
6143 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6144
6145 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", 6145
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6145, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6145, "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", 6145, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6146
6147 switch (hfinfo->type) {
6148 case FT_UINT40:
6149 case FT_UINT48:
6150 case FT_UINT56:
6151 case FT_UINT64:
6152 case FT_FRAMENUM:
6153 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6154 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6155 break;
6156
6157 default:
6158 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)
6159 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)
;
6160 }
6161
6162 return pi;
6163}
6164
6165proto_item *
6166proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6167 unsigned start, unsigned length, uint64_t value,
6168 const char *format, ...)
6169{
6170 proto_item *pi;
6171 va_list ap;
6172
6173 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6174 if (pi != tree) {
6175 va_start(ap, format)__builtin_va_start(ap, format);
6176 proto_tree_set_representation_value(pi, format, ap);
6177 va_end(ap)__builtin_va_end(ap);
6178 }
6179
6180 return pi;
6181}
6182
6183proto_item *
6184proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6185 unsigned start, unsigned length, uint64_t value,
6186 const char *format, ...)
6187{
6188 proto_item *pi;
6189 va_list ap;
6190
6191 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6192 if (pi != tree) {
6193 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6193, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6194
6195 va_start(ap, format)__builtin_va_start(ap, format);
6196 proto_tree_set_representation(pi, format, ap);
6197 va_end(ap)__builtin_va_end(ap);
6198 }
6199
6200 return pi;
6201}
6202
6203/* Set the FT_UINT{40,48,56,64} value */
6204static void
6205proto_tree_set_uint64(field_info *fi, uint64_t value)
6206{
6207 const header_field_info *hfinfo;
6208 uint64_t integer;
6209
6210 hfinfo = fi->hfinfo;
6211 integer = value;
6212
6213 if (hfinfo->bitmask) {
6214 /* Mask out irrelevant portions */
6215 integer &= hfinfo->bitmask;
6216
6217 /* Shift bits */
6218 integer >>= hfinfo_bitshift(hfinfo);
6219
6220 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6221 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)
;
6222 }
6223
6224 fvalue_set_uinteger64(fi->value, integer);
6225}
6226
6227/* Add FT_INT{8,16,24,32} to a proto_tree */
6228proto_item *
6229proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6230 unsigned length, int32_t value)
6231{
6232 proto_item *pi = NULL((void*)0);
6233 header_field_info *hfinfo;
6234
6235 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6236
6237 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", 6237
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6237, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6237, "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", 6237, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6238
6239 switch (hfinfo->type) {
6240 case FT_INT8:
6241 case FT_INT16:
6242 case FT_INT24:
6243 case FT_INT32:
6244 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6245 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6246 break;
6247
6248 default:
6249 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)
6250 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6251 }
6252
6253 return pi;
6254}
6255
6256proto_item *
6257proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6258 unsigned start, unsigned length, int32_t value,
6259 const char *format, ...)
6260{
6261 proto_item *pi;
6262 va_list ap;
6263
6264 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6265 if (pi != tree) {
6266 va_start(ap, format)__builtin_va_start(ap, format);
6267 proto_tree_set_representation_value(pi, format, ap);
6268 va_end(ap)__builtin_va_end(ap);
6269 }
6270
6271 return pi;
6272}
6273
6274proto_item *
6275proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6276 unsigned start, unsigned length, int32_t value,
6277 const char *format, ...)
6278{
6279 proto_item *pi;
6280 va_list ap;
6281
6282 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6283 if (pi != tree) {
6284 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6284, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6285
6286 va_start(ap, format)__builtin_va_start(ap, format);
6287 proto_tree_set_representation(pi, format, ap);
6288 va_end(ap)__builtin_va_end(ap);
6289 }
6290
6291 return pi;
6292}
6293
6294/* Set the FT_INT{8,16,24,32} value */
6295static void
6296proto_tree_set_int(field_info *fi, int32_t value)
6297{
6298 const header_field_info *hfinfo;
6299 uint32_t integer;
6300 int no_of_bits;
6301
6302 hfinfo = fi->hfinfo;
6303 integer = (uint32_t) value;
6304
6305 if (hfinfo->bitmask) {
6306 /* Mask out irrelevant portions */
6307 integer &= (uint32_t)(hfinfo->bitmask);
6308
6309 /* Shift bits */
6310 integer >>= hfinfo_bitshift(hfinfo);
6311
6312 no_of_bits = ws_count_ones(hfinfo->bitmask);
6313 integer = ws_sign_ext32(integer, no_of_bits);
6314
6315 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6316 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6317 }
6318
6319 fvalue_set_sinteger(fi->value, integer);
6320}
6321
6322/* Add FT_INT{40,48,56,64} to a proto_tree */
6323proto_item *
6324proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6325 unsigned length, int64_t value)
6326{
6327 proto_item *pi = NULL((void*)0);
6328 header_field_info *hfinfo;
6329
6330 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6331
6332 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", 6332
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6332, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6332, "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", 6332, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6333
6334 switch (hfinfo->type) {
6335 case FT_INT40:
6336 case FT_INT48:
6337 case FT_INT56:
6338 case FT_INT64:
6339 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6340 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6341 break;
6342
6343 default:
6344 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)
6345 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6346 }
6347
6348 return pi;
6349}
6350
6351proto_item *
6352proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6353 unsigned start, unsigned length, int64_t value,
6354 const char *format, ...)
6355{
6356 proto_item *pi;
6357 va_list ap;
6358
6359 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6360 if (pi != tree) {
6361 va_start(ap, format)__builtin_va_start(ap, format);
6362 proto_tree_set_representation_value(pi, format, ap);
6363 va_end(ap)__builtin_va_end(ap);
6364 }
6365
6366 return pi;
6367}
6368
6369/* Set the FT_INT{40,48,56,64} value */
6370static void
6371proto_tree_set_int64(field_info *fi, int64_t value)
6372{
6373 const header_field_info *hfinfo;
6374 uint64_t integer;
6375 int no_of_bits;
6376
6377 hfinfo = fi->hfinfo;
6378 integer = value;
6379
6380 if (hfinfo->bitmask) {
6381 /* Mask out irrelevant portions */
6382 integer &= hfinfo->bitmask;
6383
6384 /* Shift bits */
6385 integer >>= hfinfo_bitshift(hfinfo);
6386
6387 no_of_bits = ws_count_ones(hfinfo->bitmask);
6388 integer = ws_sign_ext64(integer, no_of_bits);
6389
6390 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6391 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)
;
6392 }
6393
6394 fvalue_set_sinteger64(fi->value, integer);
6395}
6396
6397proto_item *
6398proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6399 unsigned start, unsigned length, int64_t value,
6400 const char *format, ...)
6401{
6402 proto_item *pi;
6403 va_list ap;
6404
6405 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6406 if (pi != tree) {
6407 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6407, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6408
6409 va_start(ap, format)__builtin_va_start(ap, format);
6410 proto_tree_set_representation(pi, format, ap);
6411 va_end(ap)__builtin_va_end(ap);
6412 }
6413
6414 return pi;
6415}
6416
6417/* Add a FT_EUI64 to a proto_tree */
6418proto_item *
6419proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6420 unsigned length, const uint64_t value)
6421{
6422 proto_item *pi;
6423 header_field_info *hfinfo;
6424
6425 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6426
6427 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", 6427
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6427, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6427, "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", 6427, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6428
6429 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",
6429, ((hfinfo))->abbrev))))
;
6430
6431 pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6432 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6433
6434 return pi;
6435}
6436
6437proto_item *
6438proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6439 unsigned start, unsigned length, const uint64_t value,
6440 const char *format, ...)
6441{
6442 proto_item *pi;
6443 va_list ap;
6444
6445 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6446 if (pi != tree) {
6447 va_start(ap, format)__builtin_va_start(ap, format);
6448 proto_tree_set_representation_value(pi, format, ap);
6449 va_end(ap)__builtin_va_end(ap);
6450 }
6451
6452 return pi;
6453}
6454
6455proto_item *
6456proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6457 unsigned start, unsigned length, const uint64_t value,
6458 const char *format, ...)
6459{
6460 proto_item *pi;
6461 va_list ap;
6462
6463 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6464 if (pi != tree) {
6465 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6465, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6466
6467 va_start(ap, format)__builtin_va_start(ap, format);
6468 proto_tree_set_representation(pi, format, ap);
6469 va_end(ap)__builtin_va_end(ap);
6470 }
6471
6472 return pi;
6473}
6474
6475/* Set the FT_EUI64 value */
6476static void
6477proto_tree_set_eui64(field_info *fi, const uint64_t value)
6478{
6479 uint8_t v[FT_EUI64_LEN8];
6480 phtonu64(v, value);
6481 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6482}
6483
6484static void
6485proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6486{
6487 if (encoding)
6488 {
6489 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6490 } else {
6491 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6492 }
6493}
6494
6495proto_item *
6496proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6497 const mac_hf_list_t *list_generic,
6498 int idx, tvbuff_t *tvb,
6499 proto_tree *tree, unsigned offset)
6500{
6501 uint8_t addr[6];
6502 const char *addr_name = NULL((void*)0);
6503 const char *oui_name = NULL((void*)0);
6504 proto_item *addr_item = NULL((void*)0);
6505 proto_tree *addr_tree = NULL((void*)0);
6506 proto_item *ret_val = NULL((void*)0);
6507
6508 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6509 return NULL((void*)0);
6510 }
6511
6512 /* Resolve what we can of the address */
6513 tvb_memcpy(tvb, addr, offset, sizeof addr);
6514 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6515 addr_name = get_ether_name(addr);
6516 }
6517 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6518 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6519 }
6520
6521 /* Add the item for the specific address type */
6522 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6523 if (idx >= 0) {
6524 addr_tree = proto_item_add_subtree(ret_val, idx);
6525 }
6526 else {
6527 addr_tree = tree;
6528 }
6529
6530 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6531 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6532 tvb, offset, 6, addr_name);
6533 proto_item_set_generated(addr_item);
6534 proto_item_set_hidden(addr_item);
6535 }
6536
6537 if (list_specific->hf_oui != NULL((void*)0)) {
6538 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6539 proto_item_set_generated(addr_item);
6540 proto_item_set_hidden(addr_item);
6541
6542 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6543 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6544 proto_item_set_generated(addr_item);
6545 proto_item_set_hidden(addr_item);
6546 }
6547 }
6548
6549 if (list_specific->hf_lg != NULL((void*)0)) {
6550 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6551 }
6552 if (list_specific->hf_ig != NULL((void*)0)) {
6553 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6554 }
6555
6556 /* Were we given a list for generic address fields? If not, stop here */
6557 if (list_generic == NULL((void*)0)) {
6558 return ret_val;
6559 }
6560
6561 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6562 proto_item_set_hidden(addr_item);
6563
6564 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6565 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6566 tvb, offset, 6, addr_name);
6567 proto_item_set_generated(addr_item);
6568 proto_item_set_hidden(addr_item);
6569 }
6570
6571 if (list_generic->hf_oui != NULL((void*)0)) {
6572 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6573 proto_item_set_generated(addr_item);
6574 proto_item_set_hidden(addr_item);
6575
6576 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6577 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6578 proto_item_set_generated(addr_item);
6579 proto_item_set_hidden(addr_item);
6580 }
6581 }
6582
6583 if (list_generic->hf_lg != NULL((void*)0)) {
6584 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6585 proto_item_set_hidden(addr_item);
6586 }
6587 if (list_generic->hf_ig != NULL((void*)0)) {
6588 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6589 proto_item_set_hidden(addr_item);
6590 }
6591 return ret_val;
6592}
6593
6594static proto_item *
6595proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6596{
6597 proto_node *pnode, *tnode, *sibling;
6598 field_info *tfi;
6599 unsigned depth = 1;
6600
6601 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6601, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6602
6603 /*
6604 * Restrict our depth. proto_tree_traverse_pre_order and
6605 * proto_tree_traverse_post_order (and possibly others) are recursive
6606 * so we need to be mindful of our stack size.
6607 */
6608 if (tree->first_child == NULL((void*)0)) {
6609 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6610 depth++;
6611 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6612 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__)), 6615)))
6613 "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__)), 6615)))
6614 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__)), 6615)))
6615 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__)), 6615)))
;
6616 }
6617 }
6618 }
6619
6620 /*
6621 * Make sure "tree" is ready to have subtrees under it, by
6622 * checking whether it's been given an ett_ value.
6623 *
6624 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6625 * node of the protocol tree. That node is not displayed,
6626 * so it doesn't need an ett_ value to remember whether it
6627 * was expanded.
6628 */
6629 tnode = tree;
6630 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6631 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6632 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"
, 6633)
6633 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"
, 6633)
;
6634 /* XXX - is it safe to continue here? */
6635 }
6636
6637 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6638 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6639 pnode->parent = tnode;
6640 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6641 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6642 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6643
6644 if (tnode->last_child != NULL((void*)0)) {
6645 sibling = tnode->last_child;
6646 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6646, "sibling->next == ((void*)0)"
))))
;
6647 sibling->next = pnode;
6648 } else
6649 tnode->first_child = pnode;
6650 tnode->last_child = pnode;
6651
6652 /* We should not be adding a fake node for an interesting field */
6653 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", 6653, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6654
6655 /* XXX - Should the proto_item have a header_field_info member, at least
6656 * for faked items, to know what hfi was faked? (Some dissectors look at
6657 * the tree items directly.)
6658 */
6659 return (proto_item *)pnode;
6660}
6661
6662/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6663static proto_item *
6664proto_tree_add_node(proto_tree *tree, field_info *fi)
6665{
6666 proto_node *pnode, *tnode, *sibling;
6667 field_info *tfi;
6668 unsigned depth = 1;
6669
6670 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6670, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6671
6672 /*
6673 * Restrict our depth. proto_tree_traverse_pre_order and
6674 * proto_tree_traverse_post_order (and possibly others) are recursive
6675 * so we need to be mindful of our stack size.
6676 */
6677 if (tree->first_child == NULL((void*)0)) {
6678 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6679 depth++;
6680 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6681 /* The fvalue_t is pool-allocated; just release the
6682 * type-specific data it owns (see new_field_info()). */
6683 fvalue_cleanup(fi->value);
6684 fi->value = NULL((void*)0);
6685 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__)), 6688)))
6686 "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__)), 6688)))
6687 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__)), 6688)))
6688 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__)), 6688)))
;
6689 }
6690 }
6691 }
6692
6693 /*
6694 * Make sure "tree" is ready to have subtrees under it, by
6695 * checking whether it's been given an ett_ value.
6696 *
6697 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6698 * node of the protocol tree. That node is not displayed,
6699 * so it doesn't need an ett_ value to remember whether it
6700 * was expanded.
6701 */
6702 tnode = tree;
6703 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6704 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6705 /* Since we are not adding fi to a node, its fvalue won't get
6706 * cleaned up by proto_tree_free_node(), so release the
6707 * type-specific data it owns now. The fvalue_t structure itself
6708 * is pool-allocated (see new_field_info()).
6709 */
6710 fvalue_cleanup(fi->value);
6711 fi->value = NULL((void*)0);
6712 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", 6713)
6713 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", 6713)
;
6714 /* XXX - is it safe to continue here? */
6715 }
6716
6717 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6718 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6719 pnode->parent = tnode;
6720 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6721 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6722 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6723
6724 if (tnode->last_child != NULL((void*)0)) {
6725 sibling = tnode->last_child;
6726 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6726, "sibling->next == ((void*)0)"
))))
;
6727 sibling->next = pnode;
6728 } else
6729 tnode->first_child = pnode;
6730 tnode->last_child = pnode;
6731
6732 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6733
6734 return (proto_item *)pnode;
6735}
6736
6737
6738/* Generic way to allocate field_info and add to proto_tree.
6739 * Sets *pfi to address of newly-allocated field_info struct */
6740static proto_item *
6741proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6742 int *length)
6743{
6744 proto_item *pi;
6745 field_info *fi;
6746 int item_length;
6747
6748 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6749 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6750 pi = proto_tree_add_node(tree, fi);
6751
6752 return pi;
6753}
6754
6755/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6756 * Eventually this should replace the other function.
6757 * Sets *pfi to address of newly-allocated field_info struct */
6758static proto_item *
6759proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6760 unsigned *length)
6761{
6762 proto_item *pi;
6763 field_info *fi;
6764 unsigned item_length;
6765
6766 get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6767 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6768 pi = proto_tree_add_node(tree, fi);
6769
6770 return pi;
6771}
6772
6773static void
6774get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6775 int *item_length, const unsigned encoding)
6776{
6777 int length_remaining;
6778
6779 /*
6780 * We only allow a null tvbuff if the item has a zero length,
6781 * i.e. if there's no data backing it.
6782 */
6783 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", 6783, "tvb != ((void*)0) || *length == 0"
))))
;
6784
6785 /*
6786 * XXX - in some protocols, there are 32-bit unsigned length
6787 * fields, so lengths in protocol tree and tvbuff routines
6788 * should really be unsigned. We should have, for those
6789 * field types for which "to the end of the tvbuff" makes sense,
6790 * additional routines that take no length argument and
6791 * add fields that run to the end of the tvbuff.
6792 */
6793 if (*length == -1) {
6794 /*
6795 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6796 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6797 * of -1 means "set the length to what remains in the
6798 * tvbuff".
6799 *
6800 * The assumption is either that
6801 *
6802 * 1) the length of the item can only be determined
6803 * by dissection (typically true of items with
6804 * subitems, which are probably FT_NONE or
6805 * FT_PROTOCOL)
6806 *
6807 * or
6808 *
6809 * 2) if the tvbuff is "short" (either due to a short
6810 * snapshot length or due to lack of reassembly of
6811 * fragments/segments/whatever), we want to display
6812 * what's available in the field (probably FT_BYTES
6813 * or FT_STRING) and then throw an exception later
6814 *
6815 * or
6816 *
6817 * 3) the field is defined to be "what's left in the
6818 * packet"
6819 *
6820 * so we set the length to what remains in the tvbuff so
6821 * that, if we throw an exception while dissecting, it
6822 * has what is probably the right value.
6823 *
6824 * For FT_STRINGZ, it means "the string is null-terminated,
6825 * not null-padded; set the length to the actual length
6826 * of the string", and if the tvbuff if short, we just
6827 * throw an exception.
6828 *
6829 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6830 * it means "find the end of the string",
6831 * and if the tvbuff if short, we just throw an exception.
6832 *
6833 * It's not valid for any other type of field. For those
6834 * fields, we treat -1 the same way we treat other
6835 * negative values - we assume the length is a Really
6836 * Big Positive Number, and throw a ReportedBoundsError
6837 * exception, under the assumption that the Really Big
6838 * Length would run past the end of the packet.
6839 */
6840 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
))
)) {
6841 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6842 /*
6843 * Leave the length as -1, so our caller knows
6844 * it was -1.
6845 */
6846 *item_length = *length;
6847 return;
6848 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6849 switch (tvb_get_uint8(tvb, start) >> 6)
6850 {
6851 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6852 *item_length = 1;
6853 break;
6854 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6855 *item_length = 2;
6856 break;
6857 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6858 *item_length = 4;
6859 break;
6860 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6861 *item_length = 8;
6862 break;
6863 }
6864 }
6865 }
6866
6867 switch (hfinfo->type) {
6868
6869 case FT_PROTOCOL:
6870 case FT_NONE:
6871 case FT_BYTES:
6872 case FT_STRING:
6873 case FT_STRINGZPAD:
6874 case FT_STRINGZTRUNC:
6875 /*
6876 * We allow FT_PROTOCOLs to be zero-length -
6877 * for example, an ONC RPC NULL procedure has
6878 * neither arguments nor reply, so the
6879 * payload for that protocol is empty.
6880 *
6881 * We also allow the others to be zero-length -
6882 * because that's the way the code has been for a
6883 * long, long time.
6884 *
6885 * However, we want to ensure that the start
6886 * offset is not *past* the byte past the end
6887 * of the tvbuff: we throw an exception in that
6888 * case.
6889 */
6890 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6891 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6891, "*length >= 0"
))))
;
6892 break;
6893
6894 case FT_STRINGZ:
6895 /*
6896 * Leave the length as -1, so our caller knows
6897 * it was -1.
6898 */
6899 break;
6900
6901 default:
6902 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6903 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6903))
;
6904 }
6905 *item_length = *length;
6906 } else {
6907 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6908 /*
6909 * These types are for interior nodes of the
6910 * tree, and don't have data associated with
6911 * them; if the length is negative (XXX - see
6912 * above) or goes past the end of the tvbuff,
6913 * cut it short at the end of the tvbuff.
6914 * That way, if this field is selected in
6915 * Wireshark, we don't highlight stuff past
6916 * the end of the data.
6917 *
6918 * If we don't have a tvb, then length must be zero,
6919 * per the DISSECTOR_ASSERT() above.
6920 *
6921 * If we do have a tvb, and the length requested is
6922 * nonzero, we want to ensure that the start offset
6923 * is not *past* the byte past the end of the tvbuff
6924 * data: we throw an exception in that case as above.
6925 */
6926 if (tvb && *length) {
6927 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6928 if (*length < 0 ||
6929 (*length > 0 &&
6930 (length_remaining < *length)))
6931 *length = length_remaining;
6932 }
6933 }
6934 *item_length = *length;
6935 if (*item_length < 0) {
6936 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6937 }
6938 }
6939}
6940
6941static void
6942get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6943 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6944{
6945 unsigned length_remaining;
6946
6947 /*
6948 * We only allow a null tvbuff if the item has a zero length,
6949 * i.e. if there's no data backing it.
6950 */
6951 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", 6951, "tvb != ((void*)0) || *length == 0"
))))
;
6952
6953
6954 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6955 /*
6956 * These types are for interior nodes of the
6957 * tree, and don't have data associated with
6958 * them; if the length is negative (XXX - see
6959 * above) or goes past the end of the tvbuff,
6960 * cut it short at the end of the tvbuff.
6961 * That way, if this field is selected in
6962 * Wireshark, we don't highlight stuff past
6963 * the end of the data.
6964 *
6965 * If we don't have a tvb, then length must be zero,
6966 * per the DISSECTOR_ASSERT() above.
6967 *
6968 * If we do have a tvb, and the length requested is
6969 * nonzero, we want to ensure that the start offset
6970 * is not *past* the byte past the end of the tvbuff
6971 * data: we throw an exception in that case as above.
6972 * (If the length requested is zero, then it's quite
6973 * likely that the start offset is the byte past the
6974 * end, but that's ok.)
6975 */
6976 if (tvb && *length) {
6977 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6978 if (length_remaining < *length) {
6979 *length = length_remaining;
6980 }
6981 }
6982 }
6983 *item_length = *length;
6984}
6985
6986static int
6987get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6988 int length, unsigned item_length, const int encoding)
6989{
6990 uint32_t n;
6991
6992 /*
6993 * We need to get the correct item length here.
6994 * That's normally done by proto_tree_new_item(),
6995 * but we won't be calling it.
6996 */
6997 switch (hfinfo->type) {
6998
6999 case FT_NONE:
7000 case FT_PROTOCOL:
7001 case FT_BYTES:
7002 /*
7003 * The length is the specified length.
7004 */
7005 break;
7006
7007 case FT_UINT_BYTES:
7008 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
7009 item_length += n;
7010 if ((int)item_length < length) {
7011 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7012 }
7013 break;
7014
7015 /* XXX - make these just FT_UINT? */
7016 case FT_UINT8:
7017 case FT_UINT16:
7018 case FT_UINT24:
7019 case FT_UINT32:
7020 case FT_UINT40:
7021 case FT_UINT48:
7022 case FT_UINT56:
7023 case FT_UINT64:
7024 /* XXX - make these just FT_INT? */
7025 case FT_INT8:
7026 case FT_INT16:
7027 case FT_INT24:
7028 case FT_INT32:
7029 case FT_INT40:
7030 case FT_INT48:
7031 case FT_INT56:
7032 case FT_INT64:
7033 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
7034 if (length < -1) {
7035 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
7036 }
7037 if (length == -1) {
7038 uint64_t dummy;
7039 /* This can throw an exception */
7040 /* XXX - do this without fetching the varint? */
7041 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
7042 if (length == 0) {
7043 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7044 }
7045 }
7046 item_length = length;
7047 break;
7048 }
7049
7050 /*
7051 * The length is the specified length.
7052 */
7053 break;
7054
7055 case FT_BOOLEAN:
7056 case FT_CHAR:
7057 case FT_IPv4:
7058 case FT_IPXNET:
7059 case FT_IPv6:
7060 case FT_FCWWN:
7061 case FT_AX25:
7062 case FT_VINES:
7063 case FT_ETHER:
7064 case FT_EUI64:
7065 case FT_GUID:
7066 case FT_OID:
7067 case FT_REL_OID:
7068 case FT_SYSTEM_ID:
7069 case FT_FLOAT:
7070 case FT_DOUBLE:
7071 case FT_STRING:
7072 /*
7073 * The length is the specified length.
7074 */
7075 break;
7076
7077 case FT_STRINGZ:
7078 if (length < -1) {
7079 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7080 }
7081 if (length == -1) {
7082 /* This can throw an exception */
7083 item_length = tvb_strsize_enc(tvb, start, encoding);
7084 }
7085 break;
7086
7087 case FT_UINT_STRING:
7088 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7089 item_length += n;
7090 if ((int)item_length < length) {
7091 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7092 }
7093 break;
7094
7095 case FT_STRINGZPAD:
7096 case FT_STRINGZTRUNC:
7097 case FT_ABSOLUTE_TIME:
7098 case FT_RELATIVE_TIME:
7099 case FT_IEEE_11073_SFLOAT:
7100 case FT_IEEE_11073_FLOAT:
7101 /*
7102 * The length is the specified length.
7103 */
7104 break;
7105
7106 default:
7107 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
))
7108 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
))
7109 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
))
7110 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
))
;
7111 break;
7112 }
7113 return item_length;
7114}
7115
7116// This was arbitrarily chosen, but if you're adding 50K items to the tree
7117// without advancing the offset you should probably take a long, hard look
7118// at what you're doing.
7119// We *could* make this a configurable option, but I (Gerald) would like to
7120// avoid adding yet another nerd knob.
7121# define PROTO_TREE_MAX_IDLE50000 50000
7122static field_info *
7123new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7124 const unsigned start, const int item_length)
7125{
7126 field_info *fi;
7127
7128 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7129
7130 fi->hfinfo = hfinfo;
7131 fi->start = start;
7132 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7133 /* add the data source tvbuff */
7134 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7135
7136 // If our start offset hasn't advanced after adding many items it probably
7137 // means we're in a large or infinite loop.
7138 if (fi->start > 0) {
7139 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7140 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7141 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7142 if (wireshark_abort_on_too_many_items) {
7143 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", 7144
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7144 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7144
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7145 }
7146 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7147 * but if not, we should hit the max item error earlier,
7148 * so we shouldn't need to reset the tree count to
7149 * ensure that the exception handler can add the item. */
7150 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)))
7151 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)))
7152 "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)))
7153 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)))
;
7154 }
7155 } else {
7156 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7157 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7158 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7159 }
7160 }
7161 fi->length = item_length;
7162 fi->tree_type = -1;
7163 fi->flags = 0;
7164 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7165 /* If the tree is not visible, set the item hidden, unless we
7166 * need the representation or length and can't fake them.
7167 */
7168 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7169 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7170 }
7171 }
7172 fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7173 fi->rep = NULL((void*)0);
7174
7175 fi->appendix_start = 0;
7176 fi->appendix_length = 0;
7177
7178 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7179 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7180
7181 return fi;
7182}
7183
7184static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7185{
7186 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7187 return 0;
7188 }
7189
7190 /* Search for field name */
7191 char *ptr = strstr(representation, hfinfo->name);
7192 if (!ptr) {
7193 return 0;
7194 }
7195
7196 /* Check if field name ends with the ": " delimiter */
7197 ptr += strlen(hfinfo->name);
7198 if (strncmp(ptr, ": ", 2) == 0) {
7199 ptr += 2;
7200 }
7201
7202 /* Return offset to after field name */
7203 return ptr - representation;
7204}
7205
7206static size_t label_find_name_pos(const item_label_t *rep)
7207{
7208 size_t name_pos = 0;
7209
7210 /* If the value_pos is too small or too large, we can't find the expected format */
7211 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7212 return 0;
7213 }
7214
7215 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7216 if (rep->representation[rep->value_pos-2] == ':') {
7217 name_pos = rep->value_pos - 2;
7218 }
7219
7220 return name_pos;
7221}
7222
7223/* If the protocol tree is to be visible, set the representation of a
7224 proto_tree entry with the name of the field for the item and with
7225 the value formatted with the supplied printf-style format and
7226 argument list. */
7227static void
7228proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7229{
7230 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7230, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7231
7232 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7233 * items string representation */
7234 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7235 size_t name_pos, ret = 0;
7236 char *str;
7237 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7238 const header_field_info *hf;
7239
7240 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7240, "fi"))))
;
7241
7242 hf = fi->hfinfo;
7243
7244 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;
;
7245 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))
)) {
7246 uint64_t val;
7247 char *p;
7248
7249 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)
)
7250 val = fvalue_get_uinteger(fi->value);
7251 else
7252 val = fvalue_get_uinteger64(fi->value);
7253
7254 val <<= hfinfo_bitshift(hf);
7255
7256 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7257 ret = (p - fi->rep->representation);
7258 }
7259
7260 /* put in the hf name */
7261 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)
;
7262
7263 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7264 /* If possible, Put in the value of the string */
7265 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7266 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"
, 7266, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7267 fi->rep->value_pos = ret;
7268 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7269 if (ret >= ITEM_LABEL_LENGTH240) {
7270 /* Uh oh, we don't have enough room. Tell the user
7271 * that the field is truncated.
7272 */
7273 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7274 }
7275 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7276 }
7277}
7278
7279/* If the protocol tree is to be visible, set the representation of a
7280 proto_tree entry with the representation formatted with the supplied
7281 printf-style format and argument list. */
7282static void
7283proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7284{
7285 size_t ret; /*tmp return value */
7286 char *str;
7287 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7288
7289 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7289, "fi"))))
;
7290
7291 if (!proto_item_is_hidden(pi)) {
7292 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;
;
7293
7294 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7295 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"
, 7295, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7296 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7297 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7298 if (ret >= ITEM_LABEL_LENGTH240) {
7299 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7300 size_t name_pos = label_find_name_pos(fi->rep);
7301 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7302 }
7303 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7304 }
7305}
7306
7307static int
7308proto_strlcpy(char *dest, const char *src, size_t dest_size)
7309{
7310 if (dest_size == 0) return 0;
7311
7312 size_t res = g_strlcpy(dest, src, dest_size);
7313
7314 /* At most dest_size - 1 characters will be copied
7315 * (unless dest_size is 0). */
7316 if (res >= dest_size)
7317 res = dest_size - 1;
7318 return (int) res;
7319}
7320
7321static header_field_info *
7322hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7323{
7324 header_field_info *dup_hfinfo;
7325
7326 if (hfinfo->same_name_prev_id == -1)
7327 return NULL((void*)0);
7328 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", 7328
, __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", 7328, "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", 7328,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7329 return dup_hfinfo;
7330}
7331
7332static void
7333hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7334{
7335 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)
;
7336 last_field_name = NULL((void*)0);
7337
7338 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7339 /* No hfinfo with the same name */
7340 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7341 return;
7342 }
7343
7344 if (hfinfo->same_name_next) {
7345 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7346 }
7347
7348 if (hfinfo->same_name_prev_id != -1) {
7349 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7350 same_name_prev->same_name_next = hfinfo->same_name_next;
7351 if (!hfinfo->same_name_next) {
7352 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7353 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7354 }
7355 }
7356}
7357
7358int
7359proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7360{
7361 const header_field_info *hfinfo = finfo->hfinfo;
7362 int label_len = 0;
7363 char *tmp_str;
7364 const char *str;
7365 const uint8_t *bytes;
7366 uint32_t number;
7367 uint64_t number64;
7368 const char *hf_str_val;
7369 char number_buf[NUMBER_LABEL_LENGTH80];
7370 const char *number_out;
7371 address addr;
7372 const ipv4_addr_and_mask *ipv4;
7373 const ipv6_addr_and_prefix *ipv6;
7374
7375 switch (hfinfo->type) {
7376
7377 case FT_NONE:
7378 case FT_PROTOCOL:
7379 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7380
7381 case FT_UINT_BYTES:
7382 case FT_BYTES:
7383 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7384 hfinfo,
7385 fvalue_get_bytes_data(finfo->value),
7386 (unsigned)fvalue_length2(finfo->value),
7387 label_str_size);
7388 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7389 wmem_free(NULL((void*)0), tmp_str);
7390 break;
7391
7392 case FT_ABSOLUTE_TIME:
7393 {
7394 const nstime_t *value = fvalue_get_time(finfo->value);
7395 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7396 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7397 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7398 }
7399 if (hfinfo->strings) {
7400 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7401 if (time_string != NULL((void*)0)) {
7402 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7403 break;
7404 }
7405 }
7406 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7407 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7408 wmem_free(NULL((void*)0), tmp_str);
7409 break;
7410 }
7411
7412 case FT_RELATIVE_TIME:
7413 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7414 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7415 wmem_free(NULL((void*)0), tmp_str);
7416 break;
7417
7418 case FT_BOOLEAN:
7419 number64 = fvalue_get_uinteger64(finfo->value);
7420 label_len = proto_strlcpy(display_label_str,
7421 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7422 break;
7423
7424 case FT_CHAR:
7425 number = fvalue_get_uinteger(finfo->value);
7426
7427 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7428 char tmp[ITEM_LABEL_LENGTH240];
7429 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7430
7431 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7431, "fmtfunc"))))
;
7432 fmtfunc(tmp, number);
7433
7434 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7435
7436 } else if (hfinfo->strings) {
7437 number_out = hf_try_val_to_str(number, hfinfo);
7438
7439 if (!number_out) {
7440 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7441 }
7442
7443 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7444
7445 } else {
7446 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7447
7448 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7449 }
7450
7451 break;
7452
7453 /* XXX - make these just FT_NUMBER? */
7454 case FT_INT8:
7455 case FT_INT16:
7456 case FT_INT24:
7457 case FT_INT32:
7458 case FT_UINT8:
7459 case FT_UINT16:
7460 case FT_UINT24:
7461 case FT_UINT32:
7462 case FT_FRAMENUM:
7463 hf_str_val = NULL((void*)0);
7464 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
))
?
7465 (uint32_t) fvalue_get_sinteger(finfo->value) :
7466 fvalue_get_uinteger(finfo->value);
7467
7468 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7469 char tmp[ITEM_LABEL_LENGTH240];
7470 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7471
7472 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7472, "fmtfunc"))))
;
7473 fmtfunc(tmp, number);
7474
7475 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7476
7477 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7478 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7479 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7480 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7481 hf_str_val = hf_try_val_to_str(number, hfinfo);
7482 if (hf_str_val)
7483 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7484 } else {
7485 number_out = hf_try_val_to_str(number, hfinfo);
7486
7487 if (!number_out) {
7488 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7489 }
7490
7491 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7492 }
7493 } else {
7494 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7495
7496 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7497 }
7498
7499 break;
7500
7501 case FT_INT40:
7502 case FT_INT48:
7503 case FT_INT56:
7504 case FT_INT64:
7505 case FT_UINT40:
7506 case FT_UINT48:
7507 case FT_UINT56:
7508 case FT_UINT64:
7509 hf_str_val = NULL((void*)0);
7510 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
))
?
7511 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7512 fvalue_get_uinteger64(finfo->value);
7513
7514 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7515 char tmp[ITEM_LABEL_LENGTH240];
7516 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7517
7518 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7518, "fmtfunc64"
))))
;
7519 fmtfunc64(tmp, number64);
7520
7521 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7522 } else if (hfinfo->strings) {
7523 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7524 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7525 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7526 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7527 if (hf_str_val)
7528 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7529 } else {
7530 number_out = hf_try_val64_to_str(number64, hfinfo);
7531
7532 if (!number_out)
7533 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7534
7535 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7536 }
7537 } else {
7538 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7539
7540 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7541 }
7542
7543 break;
7544
7545 case FT_EUI64:
7546 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7547 tmp_str = address_to_display(NULL((void*)0), &addr);
7548 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7549 wmem_free(NULL((void*)0), tmp_str);
7550 break;
7551
7552 case FT_IPv4:
7553 ipv4 = fvalue_get_ipv4(finfo->value);
7554 //XXX: Should we ignore the mask?
7555 set_address_ipv4(&addr, ipv4);
7556 tmp_str = address_to_display(NULL((void*)0), &addr);
7557 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7558 wmem_free(NULL((void*)0), tmp_str);
7559 free_address(&addr);
7560 break;
7561
7562 case FT_IPv6:
7563 ipv6 = fvalue_get_ipv6(finfo->value);
7564 set_address_ipv6(&addr, ipv6);
7565 tmp_str = address_to_display(NULL((void*)0), &addr);
7566 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7567 wmem_free(NULL((void*)0), tmp_str);
7568 free_address(&addr);
7569 break;
7570
7571 case FT_FCWWN:
7572 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7573 tmp_str = address_to_display(NULL((void*)0), &addr);
7574 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7575 wmem_free(NULL((void*)0), tmp_str);
7576 break;
7577
7578 case FT_ETHER:
7579 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7580 tmp_str = address_to_display(NULL((void*)0), &addr);
7581 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7582 wmem_free(NULL((void*)0), tmp_str);
7583 break;
7584
7585 case FT_GUID:
7586 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7587 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7588 wmem_free(NULL((void*)0), tmp_str);
7589 break;
7590
7591 case FT_REL_OID:
7592 bytes = fvalue_get_bytes_data(finfo->value);
7593 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7594 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7595 wmem_free(NULL((void*)0), tmp_str);
7596 break;
7597
7598 case FT_OID:
7599 bytes = fvalue_get_bytes_data(finfo->value);
7600 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7601 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7602 wmem_free(NULL((void*)0), tmp_str);
7603 break;
7604
7605 case FT_SYSTEM_ID:
7606 bytes = fvalue_get_bytes_data(finfo->value);
7607 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7608 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7609 wmem_free(NULL((void*)0), tmp_str);
7610 break;
7611
7612 case FT_FLOAT:
7613 case FT_DOUBLE:
7614 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7615 break;
7616
7617 case FT_IEEE_11073_SFLOAT:
7618 case FT_IEEE_11073_FLOAT:
7619 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7620 break;
7621
7622 case FT_STRING:
7623 case FT_STRINGZ:
7624 case FT_UINT_STRING:
7625 case FT_STRINGZPAD:
7626 case FT_STRINGZTRUNC:
7627 str = fvalue_get_string(finfo->value);
7628 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7629 if (label_len >= label_str_size) {
7630 /* Truncation occurred. Get the real length
7631 * copied (not including '\0') */
7632 label_len = label_str_size ? label_str_size - 1 : 0;
7633 }
7634 break;
7635
7636 default:
7637 /* First try ftype string representation */
7638 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7639 if (!tmp_str) {
7640 /* Default to show as bytes */
7641 bytes = fvalue_get_bytes_data(finfo->value);
7642 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7643 }
7644 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7645 wmem_free(NULL((void*)0), tmp_str);
7646 break;
7647 }
7648 return label_len;
7649}
7650
7651const char *
7652proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7653 char *result, char *expr, const int size)
7654{
7655 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7656 GPtrArray *finfos;
7657 field_info *finfo = NULL((void*)0);
7658 header_field_info* hfinfo;
7659 const char *abbrev = NULL((void*)0);
7660
7661 char *str;
7662 col_custom_t *field_idx;
7663 int field_id;
7664 int ii = 0;
7665
7666 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7666, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7667 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7668 field_id = field_idx->field_id;
7669 if (field_id == 0) {
7670 GPtrArray *fvals = NULL((void*)0);
7671 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7672 if (fvals != NULL((void*)0)) {
7673
7674 // XXX - Handling occurrences is unusual when more
7675 // than one field is involved, e.g. there's four
7676 // results for tcp.port + tcp.port. We may really
7677 // want to apply it to the operands, not the output.
7678 // Note that occurrences are not quite the same as
7679 // the layer operator (should the grammar support
7680 // both?)
7681 /* Calculate single index or set outer boundaries */
7682 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7683 if (occurrence < 0) {
7684 i = occurrence + len;
7685 last = i;
7686 } else if (occurrence > 0) {
7687 i = occurrence - 1;
7688 last = i;
7689 } else {
7690 i = 0;
7691 last = len - 1;
7692 }
7693 if (i < 0 || i >= len) {
7694 g_ptr_array_unref(fvals);
7695 continue;
7696 }
7697 for (; i <= last; i++) {
7698 /* XXX - We could have a "resolved" result
7699 * for types where the value depends only
7700 * on the type, e.g. FT_IPv4, and not on
7701 * hfinfo->strings. Supporting the latter
7702 * requires knowing which hfinfo matched
7703 * if there are multiple with the same
7704 * abbreviation. In any case, we need to
7705 * know the expected return type of the
7706 * field expression.
7707 */
7708 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7709 if (offset_r && (offset_r < (size - 1)))
7710 result[offset_r++] = ',';
7711 if (offset_e && (offset_e < (size - 1)))
7712 expr[offset_e++] = ',';
7713 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7714 // col_{add,append,set}_* calls ws_label_strcpy
7715 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7716
7717 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7718 }
7719 g_ptr_array_unref(fvals);
7720 } else if (passed) {
7721 // XXX - Occurrence doesn't make sense for a test
7722 // output, it should be applied to the operands.
7723 if (offset_r && (offset_r < (size - 1)))
7724 result[offset_r++] = ',';
7725 if (offset_e && (offset_e < (size - 1)))
7726 expr[offset_e++] = ',';
7727 /* Prevent multiple check marks */
7728 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7729 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7730 } else {
7731 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7732 }
7733 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7734 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7735 } else {
7736 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7737 }
7738 }
7739 continue;
7740 }
7741 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", 7741
, __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", 7741,
"(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", 7741,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7742
7743 /* do we need to rewind ? */
7744 if (!hfinfo)
7745 return "";
7746
7747 if (occurrence < 0) {
7748 /* Search other direction */
7749 while (hfinfo->same_name_prev_id != -1) {
7750 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", 7750
, __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", 7750, "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", 7750,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7751 }
7752 }
7753
7754 prev_len = 0; /* Reset handled occurrences */
7755
7756 while (hfinfo) {
7757 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7758
7759 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7760 if (occurrence < 0) {
7761 hfinfo = hfinfo->same_name_next;
7762 } else {
7763 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7764 }
7765 continue;
7766 }
7767
7768 /* Are there enough occurrences of the field? */
7769 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7770 if (occurrence < 0) {
7771 hfinfo = hfinfo->same_name_next;
7772 } else {
7773 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7774 }
7775 prev_len += len;
7776 continue;
7777 }
7778
7779 /* Calculate single index or set outer boundaries */
7780 if (occurrence < 0) {
7781 i = occurrence + len + prev_len;
7782 last = i;
7783 } else if (occurrence > 0) {
7784 i = occurrence - 1 - prev_len;
7785 last = i;
7786 } else {
7787 i = 0;
7788 last = len - 1;
7789 }
7790
7791 prev_len += len; /* Count handled occurrences */
7792
7793 while (i <= last) {
7794 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7795
7796 if (offset_r && (offset_r < (size - 1)))
7797 result[offset_r++] = ',';
7798
7799 if (display_details) {
7800 char representation[ITEM_LABEL_LENGTH240];
7801 size_t offset = 0;
7802
7803 if (finfo->rep && finfo->rep->value_len) {
7804 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7805 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7806 } else {
7807 proto_item_fill_label(finfo, representation, &offset);
7808 }
7809 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7810 } else {
7811 switch (hfinfo->type) {
7812
7813 case FT_NONE:
7814 case FT_PROTOCOL:
7815 /* Prevent multiple check marks */
7816 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7817 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7818 } else {
7819 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7820 }
7821 break;
7822
7823 default:
7824 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7825 break;
7826 }
7827 }
7828
7829 if (offset_e && (offset_e < (size - 1)))
7830 expr[offset_e++] = ',';
7831
7832 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
))
)) {
7833 const char *hf_str_val;
7834 /* Integer types with BASE_NONE never get the numeric value. */
7835 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7836 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7837 } 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
)
) {
7838 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7839 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7840 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7841 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7842 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7843 }
7844 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7845 offset_e = (int)strlen(expr);
7846 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7847 /* Prevent multiple check marks */
7848 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7849 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7850 } else {
7851 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7852 }
7853 } else {
7854 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7855 // col_{add,append,set}_* calls ws_label_strcpy
7856 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7857 wmem_free(NULL((void*)0), str);
7858 }
7859 i++;
7860 }
7861
7862 /* XXX: Why is only the first abbreviation returned for a multifield
7863 * custom column? */
7864 if (!abbrev) {
7865 /* Store abbrev for return value */
7866 abbrev = hfinfo->abbrev;
7867 }
7868
7869 if (occurrence == 0) {
7870 /* Fetch next hfinfo with same name (abbrev) */
7871 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7872 } else {
7873 hfinfo = NULL((void*)0);
7874 }
7875 }
7876 }
7877
7878 if (offset_r >= (size - 1)) {
7879 mark_truncated(result, 0, size, NULL((void*)0));
7880 }
7881 if (offset_e >= (size - 1)) {
7882 mark_truncated(expr, 0, size, NULL((void*)0));
7883 }
7884 return abbrev ? abbrev : "";
7885}
7886
7887char *
7888proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7889{
7890 int len, prev_len, last, i;
7891 GPtrArray *finfos;
7892 field_info *finfo = NULL((void*)0);
7893 header_field_info* hfinfo;
7894
7895 char *filter = NULL((void*)0);
7896 GPtrArray *filter_array;
7897
7898 col_custom_t *col_custom;
7899 int field_id;
7900
7901 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7901, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7902 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7903 for (GSList *iter = field_ids; iter; iter = iter->next) {
7904 col_custom = (col_custom_t*)iter->data;
7905 field_id = col_custom->field_id;
7906 if (field_id == 0) {
7907 GPtrArray *fvals = NULL((void*)0);
7908 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7909 if (fvals != NULL((void*)0)) {
7910 // XXX - Handling occurrences is unusual when more
7911 // than one field is involved, e.g. there's four
7912 // results for tcp.port + tcp.port. We really
7913 // want to apply it to the operands, not the output.
7914 /* Calculate single index or set outer boundaries */
7915 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7916 if (occurrence < 0) {
7917 i = occurrence + len;
7918 last = i;
7919 } else if (occurrence > 0) {
7920 i = occurrence - 1;
7921 last = i;
7922 } else {
7923 i = 0;
7924 last = len - 1;
7925 }
7926 if (i < 0 || i >= len) {
7927 g_ptr_array_unref(fvals);
7928 continue;
7929 }
7930 for (; i <= last; i++) {
7931 /* XXX - Should multiple values for one
7932 * field use set membership to reduce
7933 * verbosity, here and below? */
7934 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7935 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7936 wmem_free(NULL((void*)0), str);
7937 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7938 g_ptr_array_add(filter_array, filter);
7939 }
7940 }
7941 g_ptr_array_unref(fvals);
7942 } else if (passed) {
7943 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7944 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7945 g_ptr_array_add(filter_array, filter);
7946 }
7947 } else {
7948 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7949 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7950 g_ptr_array_add(filter_array, filter);
7951 }
7952 }
7953 continue;
7954 }
7955
7956 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", 7956
, __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", 7956,
"(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", 7956,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7957
7958 /* do we need to rewind ? */
7959 if (!hfinfo)
7960 return NULL((void*)0);
7961
7962 if (occurrence < 0) {
7963 /* Search other direction */
7964 while (hfinfo->same_name_prev_id != -1) {
7965 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", 7965
, __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", 7965, "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", 7965,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7966 }
7967 }
7968
7969 prev_len = 0; /* Reset handled occurrences */
7970
7971 while (hfinfo) {
7972 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7973
7974 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7975 if (occurrence < 0) {
7976 hfinfo = hfinfo->same_name_next;
7977 } else {
7978 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7979 }
7980 continue;
7981 }
7982
7983 /* Are there enough occurrences of the field? */
7984 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7985 if (occurrence < 0) {
7986 hfinfo = hfinfo->same_name_next;
7987 } else {
7988 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7989 }
7990 prev_len += len;
7991 continue;
7992 }
7993
7994 /* Calculate single index or set outer boundaries */
7995 if (occurrence < 0) {
7996 i = occurrence + len + prev_len;
7997 last = i;
7998 } else if (occurrence > 0) {
7999 i = occurrence - 1 - prev_len;
8000 last = i;
8001 } else {
8002 i = 0;
8003 last = len - 1;
8004 }
8005
8006 prev_len += len; /* Count handled occurrences */
8007
8008 while (i <= last) {
8009 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
8010
8011 filter = proto_construct_match_selected_string(finfo, edt);
8012 if (filter) {
8013 /* Only add the same expression once (especially for FT_PROTOCOL).
8014 * The ptr array doesn't have NULL entries so g_str_equal is fine.
8015 */
8016 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
8017 g_ptr_array_add(filter_array, filter);
8018 }
8019 }
8020 i++;
8021 }
8022
8023 if (occurrence == 0) {
8024 /* Fetch next hfinfo with same name (abbrev) */
8025 hfinfo = hfinfo_same_name_get_prev(hfinfo);
8026 } else {
8027 hfinfo = NULL((void*)0);
8028 }
8029 }
8030 }
8031
8032 g_ptr_array_add(filter_array, NULL((void*)0));
8033
8034 /* XXX: Should this be || or && ? */
8035 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
8036
8037 g_ptr_array_free(filter_array, true1);
8038
8039 return output;
8040}
8041
8042/* Set text of proto_item after having already been created. */
8043void
8044proto_item_set_text(proto_item *pi, const char *format, ...)
8045{
8046 field_info *fi = NULL((void*)0);
8047 va_list ap;
8048
8049 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8050
8051 fi = PITEM_FINFO(pi)((pi)->finfo);
8052 if (fi == NULL((void*)0))
8053 return;
8054
8055 if (fi->rep) {
8056 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
8057 fi->rep = NULL((void*)0);
8058 }
8059
8060 va_start(ap, format)__builtin_va_start(ap, format);
8061 proto_tree_set_representation(pi, format, ap);
8062 va_end(ap)__builtin_va_end(ap);
8063}
8064
8065/* Append to text of proto_item after having already been created. */
8066void
8067proto_item_append_text(proto_item *pi, const char *format, ...)
8068{
8069 field_info *fi = NULL((void*)0);
8070 size_t curlen;
8071 char *str;
8072 va_list ap;
8073
8074 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8075
8076 fi = PITEM_FINFO(pi)((pi)->finfo);
8077 if (fi == NULL((void*)0)) {
8078 return;
8079 }
8080
8081 if (!proto_item_is_hidden(pi)) {
8082 /*
8083 * If we don't already have a representation,
8084 * generate the default representation.
8085 */
8086 if (fi->rep == NULL((void*)0)) {
8087 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;
;
8088 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8089 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8090 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8091 (strncmp(format, ": ", 2) == 0)) {
8092 fi->rep->value_pos += 2;
8093 }
8094 }
8095 if (fi->rep) {
8096 curlen = strlen(fi->rep->representation);
8097 /* curlen doesn't include the \0 byte.
8098 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8099 * the representation has already been truncated (of an up
8100 * to 4 byte UTF-8 character) or is just at the maximum length
8101 * unless we search for " [truncated]" (which may not be
8102 * at the start.)
8103 * It's safer to do nothing.
8104 */
8105 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8106 va_start(ap, format)__builtin_va_start(ap, format);
8107 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8108 va_end(ap)__builtin_va_end(ap);
8109 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"
, 8109, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8110 /* Keep fi->rep->value_pos */
8111 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8112 if (curlen >= ITEM_LABEL_LENGTH240) {
8113 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8114 size_t name_pos = label_find_name_pos(fi->rep);
8115 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8116 }
8117 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8118 }
8119 }
8120 }
8121}
8122
8123/* Prepend to text of proto_item after having already been created. */
8124void
8125proto_item_prepend_text(proto_item *pi, const char *format, ...)
8126{
8127 field_info *fi = NULL((void*)0);
8128 size_t pos;
8129 char representation[ITEM_LABEL_LENGTH240];
8130 char *str;
8131 va_list ap;
8132
8133 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8134
8135 fi = PITEM_FINFO(pi)((pi)->finfo);
8136 if (fi == NULL((void*)0)) {
8137 return;
8138 }
8139
8140 if (!proto_item_is_hidden(pi)) {
8141 /*
8142 * If we don't already have a representation,
8143 * generate the default representation.
8144 */
8145 if (fi->rep == NULL((void*)0)) {
8146 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;
;
8147 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8148 } else
8149 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8150
8151 va_start(ap, format)__builtin_va_start(ap, format);
8152 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8153 va_end(ap)__builtin_va_end(ap);
8154 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"
, 8154, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8155 fi->rep->value_pos += strlen(str);
8156 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8157 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8158 /* XXX: As above, if the old representation is close to the label
8159 * length, it might already be marked as truncated. */
8160 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8161 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8162 size_t name_pos = label_find_name_pos(fi->rep);
8163 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8164 }
8165 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8166 }
8167}
8168
8169static void
8170finfo_set_len(field_info *fi, const unsigned length)
8171{
8172 unsigned length_remaining;
8173
8174 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8175 if (length > length_remaining)
8176 fi->length = length_remaining;
8177 else
8178 fi->length = length;
8179
8180 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8181 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8182 fvalue_set_protocol_length(fi->value, fi->length);
8183 }
8184
8185 /*
8186 * You cannot just make the "len" field of a GByteArray
8187 * larger, if there's no data to back that length;
8188 * you can only make it smaller.
8189 */
8190 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8191 GBytes *bytes = fvalue_get_bytes(fi->value);
8192 size_t size;
8193 const void *data = g_bytes_get_data(bytes, &size);
8194 if ((size_t)fi->length <= size) {
8195 fvalue_set_bytes_data(fi->value, data, fi->length);
8196 }
8197 g_bytes_unref(bytes);
8198 }
8199}
8200
8201void
8202proto_item_set_len(proto_item *pi, const unsigned length)
8203{
8204 field_info *fi;
8205
8206 if (pi == NULL((void*)0))
8207 return;
8208
8209 fi = PITEM_FINFO(pi)((pi)->finfo);
8210 if (fi == NULL((void*)0))
8211 return;
8212
8213 finfo_set_len(fi, length);
8214}
8215
8216/*
8217 * Sets the length of the item based on its start and on the specified
8218 * offset, which is the offset past the end of the item; as the start
8219 * in the item is relative to the beginning of the data source tvbuff,
8220 * we need to pass in a tvbuff - the end offset is relative to the beginning
8221 * of that tvbuff.
8222 */
8223void
8224proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8225{
8226 field_info *fi;
8227 unsigned length;
8228
8229 if (pi == NULL((void*)0))
8230 return;
8231
8232 fi = PITEM_FINFO(pi)((pi)->finfo);
8233 if (fi == NULL((void*)0))
8234 return;
8235
8236 if (G_LIKELY(tvb)(tvb)) {
8237 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"
, 8237, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8238 end += tvb_raw_offset(tvb);
8239 } else {
8240 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", 8240, "((void*)0) == fi->ds_tvb"
))))
;
8241 }
8242 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8242, "end >= fi->start"
))))
;
8243 length = end - fi->start;
8244
8245 finfo_set_len(fi, length);
8246}
8247
8248unsigned
8249proto_item_get_len(const proto_item *pi)
8250{
8251 /* XXX - The only use case where this is really guaranteed to work is
8252 * increasing the length of an item (which has no effect if the item
8253 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8254 *
8255 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8256 *
8257 * Should there be a macro or function to do that, and possibly this
8258 * be deprecated? As a bonus, we could handle overflow.
8259 */
8260 field_info *fi;
8261
8262 if (!pi)
8263 return 0;
8264 fi = PITEM_FINFO(pi)((pi)->finfo);
8265 if (fi) {
8266 return fi->length;
8267 }
8268 return 0;
8269}
8270
8271void
8272proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8273 if (!ti) {
8274 return;
8275 }
8276 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)
;
8277 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)
;
8278}
8279
8280char *
8281proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8282{
8283 field_info *fi;
8284
8285 if (!pi)
8286 return wmem_strdup(scope, "");
8287 fi = PITEM_FINFO(pi)((pi)->finfo);
8288 if (!fi)
8289 return wmem_strdup(scope, "");
8290 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8290, "fi->hfinfo != ((void*)0)"
))))
;
8291 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8292}
8293
8294proto_tree *
8295proto_tree_create_root(packet_info *pinfo)
8296{
8297 proto_node *pnode;
8298
8299 /* Initialize the proto_node */
8300 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8301 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8302 pnode->parent = NULL((void*)0);
8303 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8304 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)))
;
8305
8306 /* Make sure we can access pinfo everywhere */
8307 pnode->tree_data->pinfo = pinfo;
8308
8309 /* Don't initialize the tree_data_t. Wait until we know we need it */
8310 pnode->tree_data->interesting_hfids = NULL((void*)0);
8311
8312 /* Set the default to false so it's easier to
8313 * find errors; if we expect to see the protocol tree
8314 * but for some reason the default 'visible' is not
8315 * changed, then we'll find out very quickly. */
8316 pnode->tree_data->visible = false0;
8317
8318 /* Make sure that we fake protocols (if possible) */
8319 pnode->tree_data->fake_protocols = true1;
8320
8321 /* Keep track of the number of children */
8322 pnode->tree_data->count = 0;
8323
8324 /* Initialize our loop checks */
8325 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8326 pnode->tree_data->max_start = 0;
8327 pnode->tree_data->start_idle_count = 0;
8328
8329 return (proto_tree *)pnode;
8330}
8331
8332
8333/* "prime" a proto_tree with a single hfid that a dfilter
8334 * is interested in. */
8335void
8336proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8337{
8338 header_field_info *hfinfo;
8339
8340 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", 8340, __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", 8340, "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", 8340, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8341 /* this field is referenced by a filter so increase the refcount.
8342 also increase the refcount for the parent, i.e the protocol.
8343 Don't increase the refcount if we're already printing the
8344 type, as that is a superset of direct reference.
8345 */
8346 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8347 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8348 }
8349 /* only increase the refcount if there is a parent.
8350 if this is a protocol and not a field then parent will be -1
8351 and there is no parent to add any refcounting for.
8352 */
8353 if (hfinfo->parent != -1) {
8354 header_field_info *parent_hfinfo;
8355 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", 8355
, __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", 8355,
"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", 8355,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8356
8357 /* Mark parent as indirectly referenced unless it is already directly
8358 * referenced, i.e. the user has specified the parent in a filter.
8359 */
8360 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8361 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8362 }
8363}
8364
8365/* "prime" a proto_tree with a single hfid that a dfilter
8366 * is interested in. */
8367void
8368proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8369{
8370 header_field_info *hfinfo;
8371
8372 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", 8372, __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", 8372, "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", 8372, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8373 /* this field is referenced by an (output) filter so increase the refcount.
8374 also increase the refcount for the parent, i.e the protocol.
8375 */
8376 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8377 /* only increase the refcount if there is a parent.
8378 if this is a protocol and not a field then parent will be -1
8379 and there is no parent to add any refcounting for.
8380 */
8381 if (hfinfo->parent != -1) {
8382 header_field_info *parent_hfinfo;
8383 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", 8383
, __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", 8383,
"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", 8383,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8384
8385 /* Mark parent as indirectly referenced unless it is already directly
8386 * referenced, i.e. the user has specified the parent in a filter.
8387 */
8388 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8389 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8390 }
8391}
8392
8393proto_tree *
8394proto_item_add_subtree(proto_item *pi, const int idx) {
8395 field_info *fi;
8396
8397 if (!pi)
8398 return NULL((void*)0);
8399
8400 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", 8400, "idx >= 0 && idx < num_tree_types"
))))
;
8401
8402 fi = PITEM_FINFO(pi)((pi)->finfo);
8403 if (!fi)
8404 return (proto_tree *)pi;
8405
8406 fi->tree_type = idx;
8407
8408 return (proto_tree *)pi;
8409}
8410
8411proto_tree *
8412proto_item_get_subtree(proto_item *pi) {
8413 field_info *fi;
8414
8415 if (!pi)
8416 return NULL((void*)0);
8417 fi = PITEM_FINFO(pi)((pi)->finfo);
8418 if ( (fi) && (fi->tree_type == -1) )
8419 return NULL((void*)0);
8420 return (proto_tree *)pi;
8421}
8422
8423proto_item *
8424proto_item_get_parent(const proto_item *ti) {
8425 if (!ti)
8426 return NULL((void*)0);
8427 return ti->parent;
8428}
8429
8430proto_item *
8431proto_item_get_parent_nth(proto_item *ti, int gen) {
8432 if (!ti)
8433 return NULL((void*)0);
8434 while (gen--) {
8435 ti = ti->parent;
8436 if (!ti)
8437 return NULL((void*)0);
8438 }
8439 return ti;
8440}
8441
8442
8443proto_item *
8444proto_tree_get_parent(proto_tree *tree) {
8445 if (!tree)
8446 return NULL((void*)0);
8447 return (proto_item *)tree;
8448}
8449
8450proto_tree *
8451proto_tree_get_parent_tree(proto_tree *tree) {
8452 if (!tree)
8453 return NULL((void*)0);
8454
8455 /* we're the root tree, there's no parent
8456 return ourselves so the caller has at least a tree to attach to */
8457 if (!tree->parent)
8458 return tree;
8459
8460 return (proto_tree *)tree->parent;
8461}
8462
8463proto_tree *
8464proto_tree_get_root(proto_tree *tree) {
8465 if (!tree)
8466 return NULL((void*)0);
8467 while (tree->parent) {
8468 tree = tree->parent;
8469 }
8470 return tree;
8471}
8472
8473void
8474proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8475 proto_item *item_to_move)
8476{
8477 /* This function doesn't generate any values. It only reorganizes the protocol tree
8478 * so we can bail out immediately if it isn't visible. */
8479 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8480 return;
8481
8482 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", 8482, "item_to_move->parent == tree"
))))
;
8483 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", 8483, "fixed_item->parent == tree"
))))
;
8484
8485 /*** cut item_to_move out ***/
8486
8487 /* is item_to_move the first? */
8488 if (tree->first_child == item_to_move) {
8489 /* simply change first child to next */
8490 tree->first_child = item_to_move->next;
8491
8492 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", 8492, "tree->last_child != item_to_move"
))))
;
8493 } else {
8494 proto_item *curr_item;
8495 /* find previous and change it's next */
8496 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8497 if (curr_item->next == item_to_move) {
8498 break;
8499 }
8500 }
8501
8502 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8502, "curr_item"
))))
;
8503
8504 curr_item->next = item_to_move->next;
8505
8506 /* fix last_child if required */
8507 if (tree->last_child == item_to_move) {
8508 tree->last_child = curr_item;
8509 }
8510 }
8511
8512 /*** insert to_move after fixed ***/
8513 item_to_move->next = fixed_item->next;
8514 fixed_item->next = item_to_move;
8515 if (tree->last_child == fixed_item) {
8516 tree->last_child = item_to_move;
8517 }
8518}
8519
8520void
8521proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8522 const unsigned length)
8523{
8524 field_info *fi;
8525
8526 if (tree == NULL((void*)0))
8527 return;
8528
8529 fi = PTREE_FINFO(tree)((tree)->finfo);
8530 if (fi == NULL((void*)0))
8531 return;
8532
8533 /* We don't store a separate data source tvb for the appendix, so
8534 * it must be from the same data source. (XXX - Are there any
8535 * situations where it makes sense to have an appendix from a
8536 * different data source?) */
8537 if (G_LIKELY(tvb)(tvb)) {
8538 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"
, 8538, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8539 start += tvb_raw_offset(tvb);
8540 } else {
8541 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", 8541, "((void*)0) == fi->ds_tvb"
))))
;
8542 }
8543
8544 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8545 * main body? */
8546
8547 fi->appendix_start = start;
8548 fi->appendix_length = length;
8549}
8550
8551static void
8552check_protocol_filter_name_or_fail(const char *filter_name)
8553{
8554 /* Require at least two characters. */
8555 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8556 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)
;
8557 }
8558
8559 if (proto_check_field_name(filter_name) != '\0') {
8560 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)
8561 " 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)
8562 " 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)
;
8563 }
8564
8565 /* Check that it doesn't match some very common numeric forms. */
8566 if (filter_name[0] == '0' &&
8567 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8568 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8569 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])
8570 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])
;
8571 }
8572
8573 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8574
8575 /* Check that it contains at least one letter. */
8576 bool_Bool have_letter = false0;
8577 for (const char *s = filter_name; *s != '\0'; s++) {
8578 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8579 have_letter = true1;
8580 break;
8581 }
8582 }
8583 if (!have_letter) {
8584 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)
8585 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8586 }
8587
8588 /* Check for reserved keywords. */
8589 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8590 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)
8591 " 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)
;
8592 }
8593}
8594
8595int
8596proto_register_protocol(const char *name, const char *short_name,
8597 const char *filter_name)
8598{
8599 protocol_t *protocol;
8600 header_field_info *hfinfo;
8601
8602 check_protocol_filter_name_or_fail(filter_name);
8603
8604 /*
8605 * Add this protocol to the list of known protocols;
8606 * the list is sorted by protocol short name.
8607 */
8608 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8609 protocol->name = name;
8610 protocol->short_name = short_name;
8611 protocol->filter_name = filter_name;
8612 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8613 protocol->is_enabled = true1; /* protocol is enabled by default */
8614 protocol->enabled_by_default = true1; /* see previous comment */
8615 protocol->can_toggle = true1;
8616 protocol->parent_proto_id = -1;
8617 protocol->heur_list = NULL((void*)0);
8618
8619 /* List will be sorted later by name, when all protocols completed registering */
8620 protocols = g_list_prepend(protocols, protocol);
8621 /*
8622 * Make sure there's not already a protocol with any of those
8623 * names. Crash if there is, as that's an error in the code
8624 * or an inappropriate plugin.
8625 * This situation has to be fixed to not register more than one
8626 * protocol with the same name.
8627 */
8628 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8629 /* ws_error will terminate the program */
8630 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)
8631 " 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)
;
8632 }
8633 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8634 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)
8635 " 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)
;
8636 }
8637 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8638 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)
8639 " 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)
;
8640 }
8641
8642 /* Here we allocate a new header_field_info struct */
8643 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8644 hfinfo->name = name;
8645 hfinfo->abbrev = filter_name;
8646 hfinfo->type = FT_PROTOCOL;
8647 hfinfo->display = BASE_NONE;
8648 hfinfo->strings = protocol;
8649 hfinfo->bitmask = 0;
8650 hfinfo->ref_type = HF_REF_TYPE_NONE;
8651 hfinfo->blurb = NULL((void*)0);
8652 hfinfo->parent = -1; /* This field differentiates protos and fields */
8653
8654 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8655 return protocol->proto_id;
8656}
8657
8658int
8659proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8660{
8661 protocol_t *protocol;
8662 header_field_info *hfinfo;
8663
8664 /*
8665 * Helper protocols don't need the strict rules as a "regular" protocol
8666 * Just register it in a list and make a hf_ field from it
8667 */
8668 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8669 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)
;
8670 }
8671
8672 if (parent_proto <= 0) {
8673 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)
8674 " 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)
;
8675 }
8676
8677 check_protocol_filter_name_or_fail(filter_name);
8678
8679 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8680 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8681 protocol->name = name;
8682 protocol->short_name = short_name;
8683 protocol->filter_name = filter_name;
8684 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8685
8686 /* Enabling and toggling is really determined by parent protocol,
8687 but provide default values here */
8688 protocol->is_enabled = true1;
8689 protocol->enabled_by_default = true1;
8690 protocol->can_toggle = true1;
8691
8692 protocol->parent_proto_id = parent_proto;
8693 protocol->heur_list = NULL((void*)0);
8694
8695 /* List will be sorted later by name, when all protocols completed registering */
8696 protocols = g_list_prepend(protocols, protocol);
8697
8698 /* Here we allocate a new header_field_info struct */
8699 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8700 hfinfo->name = name;
8701 hfinfo->abbrev = filter_name;
8702 hfinfo->type = field_type;
8703 hfinfo->display = BASE_NONE;
8704 if (field_type == FT_BYTES) {
8705 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8706 }
8707 hfinfo->strings = protocol;
8708 hfinfo->bitmask = 0;
8709 hfinfo->ref_type = HF_REF_TYPE_NONE;
8710 hfinfo->blurb = NULL((void*)0);
8711 hfinfo->parent = -1; /* This field differentiates protos and fields */
8712
8713 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8714 return protocol->proto_id;
8715}
8716
8717bool_Bool
8718proto_deregister_protocol(const char *short_name)
8719{
8720 protocol_t *protocol;
8721 header_field_info *hfinfo;
8722 int proto_id;
8723 unsigned i;
8724
8725 proto_id = proto_get_id_by_short_name(short_name);
8726 protocol = find_protocol_by_id(proto_id);
8727 if (protocol == NULL((void*)0))
8728 return false0;
8729
8730 g_hash_table_remove(proto_names, protocol->name);
8731 g_hash_table_remove(proto_short_names, (void *)short_name);
8732 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8733
8734 if (protocol->fields) {
8735 for (i = 0; i < protocol->fields->len; i++) {
8736 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8737 hfinfo_remove_from_gpa_name_map(hfinfo);
8738 expert_deregister_expertinfo(hfinfo->abbrev);
8739 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8740 }
8741 g_ptr_array_free(protocol->fields, true1);
8742 protocol->fields = NULL((void*)0);
8743 }
8744
8745 g_list_free(protocol->heur_list);
8746
8747 /* Remove this protocol from the list of known protocols */
8748 protocols = g_list_remove(protocols, protocol);
8749
8750 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8751 wmem_map_remove(gpa_name_map, protocol->filter_name);
8752
8753 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)
;
8754 last_field_name = NULL((void*)0);
8755
8756 return true1;
8757}
8758
8759void
8760proto_register_alias(const int proto_id, const char *alias_name)
8761{
8762 protocol_t *protocol;
8763
8764 protocol = find_protocol_by_id(proto_id);
8765 if (alias_name && protocol) {
8766 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8767 }
8768}
8769
8770/*
8771 * Routines to use to iterate over the protocols.
8772 * The argument passed to the iterator routines is an opaque cookie to
8773 * their callers; it's the GList pointer for the current element in
8774 * the list.
8775 * The ID of the protocol is returned, or -1 if there is no protocol.
8776 */
8777int
8778proto_get_first_protocol(void **cookie)
8779{
8780 protocol_t *protocol;
8781
8782 if (protocols == NULL((void*)0))
8783 return -1;
8784 *cookie = protocols;
8785 protocol = (protocol_t *)protocols->data;
8786 return protocol->proto_id;
8787}
8788
8789int
8790proto_get_data_protocol(void *cookie)
8791{
8792 GList *list_item = (GList *)cookie;
8793
8794 protocol_t *protocol = (protocol_t *)list_item->data;
8795 return protocol->proto_id;
8796}
8797
8798int
8799proto_get_next_protocol(void **cookie)
8800{
8801 GList *list_item = (GList *)*cookie;
8802 protocol_t *protocol;
8803
8804 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8805 if (list_item == NULL((void*)0))
8806 return -1;
8807 *cookie = list_item;
8808 protocol = (protocol_t *)list_item->data;
8809 return protocol->proto_id;
8810}
8811
8812header_field_info *
8813proto_get_first_protocol_field(const int proto_id, void **cookie)
8814{
8815 protocol_t *protocol = find_protocol_by_id(proto_id);
8816
8817 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8818 return NULL((void*)0);
8819
8820 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8821 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8822}
8823
8824header_field_info *
8825proto_get_next_protocol_field(const int proto_id, void **cookie)
8826{
8827 protocol_t *protocol = find_protocol_by_id(proto_id);
8828 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8829
8830 i++;
8831
8832 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8833 return NULL((void*)0);
8834
8835 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8836 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8837}
8838
8839protocol_t *
8840find_protocol_by_id(const int proto_id)
8841{
8842 header_field_info *hfinfo;
8843
8844 if (proto_id <= 0)
8845 return NULL((void*)0);
8846
8847 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", 8847, __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", 8847,
"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", 8847, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8848 if (hfinfo->type != FT_PROTOCOL) {
8849 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", 8849, "hfinfo->display & 0x00004000"
))))
;
8850 }
8851 return (protocol_t *)hfinfo->strings;
8852}
8853
8854int
8855proto_get_id(const protocol_t *protocol)
8856{
8857 return protocol->proto_id;
8858}
8859
8860bool_Bool
8861proto_name_already_registered(const char *name)
8862{
8863 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8863, "name", "No name present"))))
;
8864
8865 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8866 return true1;
8867 return false0;
8868}
8869
8870int
8871proto_get_id_by_filter_name(const char *filter_name)
8872{
8873 const protocol_t *protocol = NULL((void*)0);
8874
8875 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", 8875,
"filter_name", "No filter name present"))))
;
8876
8877 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8878
8879 if (protocol == NULL((void*)0))
8880 return -1;
8881 return protocol->proto_id;
8882}
8883
8884int
8885proto_get_id_by_short_name(const char *short_name)
8886{
8887 const protocol_t *protocol = NULL((void*)0);
8888
8889 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", 8889,
"short_name", "No short name present"))))
;
8890
8891 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8892
8893 if (protocol == NULL((void*)0))
8894 return -1;
8895 return protocol->proto_id;
8896}
8897
8898const char *
8899proto_get_protocol_name(const int proto_id)
8900{
8901 protocol_t *protocol;
8902
8903 protocol = find_protocol_by_id(proto_id);
8904
8905 if (protocol == NULL((void*)0))
8906 return NULL((void*)0);
8907 return protocol->name;
8908}
8909
8910const char *
8911proto_get_protocol_short_name(const protocol_t *protocol)
8912{
8913 if (protocol == NULL((void*)0))
8914 return "(none)";
8915 return protocol->short_name;
8916}
8917
8918const char *
8919proto_get_protocol_long_name(const protocol_t *protocol)
8920{
8921 if (protocol == NULL((void*)0))
8922 return "(none)";
8923 return protocol->name;
8924}
8925
8926const char *
8927proto_get_protocol_filter_name(const int proto_id)
8928{
8929 protocol_t *protocol;
8930
8931 protocol = find_protocol_by_id(proto_id);
8932 if (protocol == NULL((void*)0))
8933 return "(none)";
8934 return protocol->filter_name;
8935}
8936
8937void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8938{
8939 heur_dtbl_entry_t* heuristic_dissector;
8940
8941 if (protocol == NULL((void*)0))
8942 return;
8943
8944 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8945 if (heuristic_dissector != NULL((void*)0))
8946 {
8947 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8948 }
8949}
8950
8951void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8952{
8953 if (protocol == NULL((void*)0))
8954 return;
8955
8956 g_list_foreach(protocol->heur_list, func, user_data);
8957}
8958
8959void
8960proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8961 bool_Bool *is_tcp, bool_Bool *is_udp,
8962 bool_Bool *is_sctp, bool_Bool *is_tls,
8963 bool_Bool *is_rtp,
8964 bool_Bool *is_lte_rlc)
8965{
8966 wmem_list_frame_t *protos = wmem_list_head(layers);
8967 int proto_id;
8968 const char *proto_name;
8969
8970 /* Walk the list of a available protocols in the packet and
8971 attempt to find "major" ones. */
8972 /* It might make more sense to assemble and return a bitfield. */
8973 while (protos != NULL((void*)0))
8974 {
8975 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8976 proto_name = proto_get_protocol_filter_name(proto_id);
8977
8978 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8979 (!strcmp(proto_name, "ipv6")))) {
8980 *is_ip = true1;
8981 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8982 *is_tcp = true1;
8983 } else if (is_udp && !strcmp(proto_name, "udp")) {
8984 *is_udp = true1;
8985 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8986 *is_sctp = true1;
8987 } else if (is_tls && !strcmp(proto_name, "tls")) {
8988 *is_tls = true1;
8989 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8990 *is_rtp = true1;
8991 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8992 *is_lte_rlc = true1;
8993 }
8994
8995 protos = wmem_list_frame_next(protos);
8996 }
8997}
8998
8999bool_Bool
9000proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
9001{
9002 wmem_list_frame_t *protos = wmem_list_head(layers);
9003 int proto_id;
9004 const char *name;
9005
9006 /* Walk the list of a available protocols in the packet and
9007 attempt to find the specified protocol. */
9008 while (protos != NULL((void*)0))
9009 {
9010 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
9011 name = proto_get_protocol_filter_name(proto_id);
9012
9013 if (!strcmp(name, proto_name))
9014 {
9015 return true1;
9016 }
9017
9018 protos = wmem_list_frame_next(protos);
9019 }
9020
9021 return false0;
9022}
9023
9024char *
9025proto_list_layers(const packet_info *pinfo)
9026{
9027 wmem_strbuf_t *buf;
9028 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
9029
9030 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
9031
9032 /* Walk the list of layers in the packet and
9033 return a string of all entries. */
9034 while (layers != NULL((void*)0))
9035 {
9036 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
9037
9038 layers = wmem_list_frame_next(layers);
9039 if (layers != NULL((void*)0)) {
9040 wmem_strbuf_append_c(buf, ':');
9041 }
9042 }
9043
9044 return wmem_strbuf_finalize(buf);
9045}
9046
9047uint8_t
9048proto_get_layer_num(const packet_info *pinfo, const int proto_id)
9049{
9050 int *proto_layer_num_ptr;
9051
9052 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
9053 if (proto_layer_num_ptr == NULL((void*)0)) {
9054 return 0;
9055 }
9056
9057 return (uint8_t)*proto_layer_num_ptr;
9058}
9059
9060bool_Bool
9061proto_is_pino(const protocol_t *protocol)
9062{
9063 return (protocol->parent_proto_id != -1);
9064}
9065
9066bool_Bool
9067proto_is_bytes_pino(const protocol_t *protocol)
9068{
9069 header_field_info *hfinfo;
9070
9071 if (!proto_is_pino(protocol))
9072 return false0;
9073
9074 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", 9074
, __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", 9074,
"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", 9074,
"gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[protocol->proto_id];
;
9075 return hfinfo->type != FT_PROTOCOL;
9076}
9077
9078bool_Bool
9079// NOLINTNEXTLINE(misc-no-recursion)
9080proto_is_protocol_enabled(const protocol_t *protocol)
9081{
9082 if (protocol == NULL((void*)0))
9083 return false0;
9084
9085 //parent protocol determines enable/disable for helper dissectors
9086 if (proto_is_pino(protocol))
9087 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9088
9089 return protocol->is_enabled;
9090}
9091
9092bool_Bool
9093// NOLINTNEXTLINE(misc-no-recursion)
9094proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9095{
9096 //parent protocol determines enable/disable for helper dissectors
9097 if (proto_is_pino(protocol))
9098 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9099
9100 return protocol->enabled_by_default;
9101}
9102
9103bool_Bool
9104// NOLINTNEXTLINE(misc-no-recursion)
9105proto_can_toggle_protocol(const int proto_id)
9106{
9107 protocol_t *protocol;
9108
9109 protocol = find_protocol_by_id(proto_id);
9110 //parent protocol determines toggling for helper dissectors
9111 if (proto_is_pino(protocol))
9112 return proto_can_toggle_protocol(protocol->parent_proto_id);
9113
9114 return protocol->can_toggle;
9115}
9116
9117void
9118proto_disable_by_default(const int proto_id)
9119{
9120 protocol_t *protocol;
9121
9122 protocol = find_protocol_by_id(proto_id);
9123 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9123, "protocol->can_toggle"
))))
;
9124 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", 9124, "proto_is_pino(protocol) == 0"
))))
;
9125 protocol->is_enabled = false0;
9126 protocol->enabled_by_default = false0;
9127}
9128
9129void
9130proto_set_decoding(const int proto_id, const bool_Bool enabled)
9131{
9132 protocol_t *protocol;
9133
9134 protocol = find_protocol_by_id(proto_id);
9135 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9135, "protocol->can_toggle"
))))
;
9136 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", 9136, "proto_is_pino(protocol) == 0"
))))
;
9137 protocol->is_enabled = enabled;
9138}
9139
9140void
9141proto_disable_all(void)
9142{
9143 /* This doesn't explicitly disable heuristic protocols,
9144 * but the heuristic doesn't get called if the parent
9145 * protocol isn't enabled.
9146 */
9147 protocol_t *protocol;
9148 GList *list_item = protocols;
9149
9150 if (protocols == NULL((void*)0))
9151 return;
9152
9153 while (list_item) {
9154 protocol = (protocol_t *)list_item->data;
9155 if (protocol->can_toggle) {
9156 protocol->is_enabled = false0;
9157 }
9158 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9159 }
9160}
9161
9162static void
9163heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9164{
9165 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9166
9167 heur->enabled = heur->enabled_by_default;
9168}
9169
9170void
9171proto_reenable_all(void)
9172{
9173 protocol_t *protocol;
9174 GList *list_item = protocols;
9175
9176 if (protocols == NULL((void*)0))
9177 return;
9178
9179 while (list_item) {
9180 protocol = (protocol_t *)list_item->data;
9181 if (protocol->can_toggle)
9182 protocol->is_enabled = protocol->enabled_by_default;
9183 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9184 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9185 }
9186}
9187
9188void
9189proto_set_cant_toggle(const int proto_id)
9190{
9191 protocol_t *protocol;
9192
9193 protocol = find_protocol_by_id(proto_id);
9194 protocol->can_toggle = false0;
9195}
9196
9197static int
9198proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9199{
9200 g_ptr_array_add(proto->fields, hfi);
9201
9202 return proto_register_field_init(hfi, parent);
9203}
9204
9205/* for use with static arrays only, since we don't allocate our own copies
9206of the header_field_info struct contained within the hf_register_info struct */
9207void
9208proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9209{
9210 hf_register_info *ptr = hf;
9211 protocol_t *proto;
9212 int i;
9213
9214 proto = find_protocol_by_id(parent);
9215
9216 /* if (proto == NULL) - error or return? */
9217
9218 if (proto->fields == NULL((void*)0)) {
9219 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9220 * GLib introduced g_ptr_array_new_from_array, which might have
9221 * given a reason to actually use it. (#17774)
9222 */
9223 proto->fields = g_ptr_array_sized_new(num_records);
9224 }
9225
9226 for (i = 0; i < num_records; i++, ptr++) {
9227 /*
9228 * Make sure we haven't registered this yet.
9229 * Most fields have variables associated with them that
9230 * are initialized to 0; some are initialized to -1 (which
9231 * was the standard before 4.4).
9232 *
9233 * XXX - Since this is called almost 300000 times at startup,
9234 * it might be nice to compare to only 0 and require
9235 * dissectors to pass in zero for unregistered fields.
9236 */
9237 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9238 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9239 "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)
9240 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9241 return;
9242 }
9243
9244 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9245 }
9246}
9247
9248/* deregister already registered fields */
9249void
9250proto_deregister_field (const int parent, int hf_id)
9251{
9252 header_field_info *hfi;
9253 protocol_t *proto;
9254 unsigned i;
9255
9256 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)
;
9257 last_field_name = NULL((void*)0);
9258
9259 if (hf_id == -1 || hf_id == 0)
9260 return;
9261
9262 proto = find_protocol_by_id (parent);
9263 if (!proto || proto->fields == NULL((void*)0)) {
9264 return;
9265 }
9266
9267 for (i = 0; i < proto->fields->len; i++) {
9268 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9269 if (hfi->id == hf_id) {
9270 /* Found the hf_id in this protocol */
9271 wmem_map_remove(gpa_name_map, hfi->abbrev);
9272 g_ptr_array_remove_index_fast(proto->fields, i);
9273 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9274 return;
9275 }
9276 }
9277}
9278
9279/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9280void
9281proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9282{
9283 header_field_info *hfinfo;
9284 protocol_t *proto;
9285
9286 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)
;
9287 last_field_name = NULL((void*)0);
9288
9289 proto = find_protocol_by_id(parent);
9290 if (proto && proto->fields && proto->fields->len > 0) {
9291 unsigned i = proto->fields->len;
9292 do {
9293 i--;
9294
9295 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9296 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) )
) {
9297 hfinfo_remove_from_gpa_name_map(hfinfo);
9298 expert_deregister_expertinfo(hfinfo->abbrev);
9299 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9300 g_ptr_array_remove_index_fast(proto->fields, i);
9301 }
9302 } while (i > 0);
9303 }
9304}
9305
9306void
9307proto_add_deregistered_data (void *data)
9308{
9309 g_ptr_array_add(deregistered_data, data);
9310}
9311
9312void
9313proto_add_deregistered_slice (size_t block_size, void *mem_block)
9314{
9315 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)))
;
9316
9317 slice_data->block_size = block_size;
9318 slice_data->mem_block = mem_block;
9319
9320 g_ptr_array_add(deregistered_slice, slice_data);
9321}
9322
9323void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9324{
9325 if (field_strings == NULL((void*)0)) {
9326 return;
9327 }
9328
9329 switch (field_type) {
9330 case FT_FRAMENUM:
9331 /* This is just an integer represented as a pointer */
9332 break;
9333 case FT_PROTOCOL: {
9334 protocol_t *protocol = (protocol_t *)field_strings;
9335 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)
;
9336 break;
9337 }
9338 case FT_BOOLEAN: {
9339 true_false_string *tf = (true_false_string *)field_strings;
9340 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)
;
9341 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)
;
9342 break;
9343 }
9344 case FT_UINT40:
9345 case FT_INT40:
9346 case FT_UINT48:
9347 case FT_INT48:
9348 case FT_UINT56:
9349 case FT_INT56:
9350 case FT_UINT64:
9351 case FT_INT64: {
9352 if (field_display & BASE_UNIT_STRING0x00001000) {
9353 unit_name_string *unit = (unit_name_string *)field_strings;
9354 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)
;
9355 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)
;
9356 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9357 range_string *rs = (range_string *)field_strings;
9358 while (rs->strptr) {
9359 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
)
;
9360 rs++;
9361 }
9362 } else if (field_display & BASE_EXT_STRING0x00000200) {
9363 val64_string_ext *vse = (val64_string_ext *)field_strings;
9364 val64_string *vs = (val64_string *)vse->_vs_p;
9365 while (vs->strptr) {
9366 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
)
;
9367 vs++;
9368 }
9369 val64_string_ext_free(vse);
9370 field_strings = NULL((void*)0);
9371 } else if (field_display == BASE_CUSTOM) {
9372 /* this will be a pointer to a function, don't free that */
9373 field_strings = NULL((void*)0);
9374 } else {
9375 val64_string *vs64 = (val64_string *)field_strings;
9376 while (vs64->strptr) {
9377 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)
;
9378 vs64++;
9379 }
9380 }
9381 break;
9382 }
9383 case FT_CHAR:
9384 case FT_UINT8:
9385 case FT_INT8:
9386 case FT_UINT16:
9387 case FT_INT16:
9388 case FT_UINT24:
9389 case FT_INT24:
9390 case FT_UINT32:
9391 case FT_INT32:
9392 case FT_FLOAT:
9393 case FT_DOUBLE: {
9394 if (field_display & BASE_UNIT_STRING0x00001000) {
9395 unit_name_string *unit = (unit_name_string *)field_strings;
9396 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)
;
9397 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)
;
9398 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9399 range_string *rs = (range_string *)field_strings;
9400 while (rs->strptr) {
9401 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
)
;
9402 rs++;
9403 }
9404 } else if (field_display & BASE_EXT_STRING0x00000200) {
9405 value_string_ext *vse = (value_string_ext *)field_strings;
9406 value_string *vs = (value_string *)vse->_vs_p;
9407 while (vs->strptr) {
9408 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
)
;
9409 vs++;
9410 }
9411 value_string_ext_free(vse);
9412 field_strings = NULL((void*)0);
9413 } else if (field_display == BASE_CUSTOM) {
9414 /* this will be a pointer to a function, don't free that */
9415 field_strings = NULL((void*)0);
9416 } else {
9417 value_string *vs = (value_string *)field_strings;
9418 while (vs->strptr) {
9419 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
)
;
9420 vs++;
9421 }
9422 }
9423 break;
9424 default:
9425 break;
9426 }
9427 }
9428
9429 if (field_type != FT_FRAMENUM) {
9430 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
)
;
9431 }
9432}
9433
9434static void
9435free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9436{
9437 header_field_info *hfi = (header_field_info *) data;
9438 int hf_id = hfi->id;
9439
9440 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
)
;
9441 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
)
;
9442 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
)
;
9443
9444 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9445
9446 if (hfi->parent == -1)
9447 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)
;
9448
9449 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9450}
9451
9452static void
9453free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9454{
9455 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9456}
9457
9458static void
9459free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9460{
9461 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9462
9463 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9464 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)
;
9465}
9466
9467/* free deregistered fields and data */
9468void
9469proto_free_deregistered_fields (void)
9470{
9471 expert_free_deregistered_expertinfos();
9472
9473 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9474 g_ptr_array_free(deregistered_fields, true1);
9475 deregistered_fields = g_ptr_array_new();
9476
9477 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9478 g_ptr_array_free(deregistered_data, true1);
9479 deregistered_data = g_ptr_array_new();
9480
9481 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9482 g_ptr_array_free(deregistered_slice, true1);
9483 deregistered_slice = g_ptr_array_new();
9484}
9485
9486static const value_string hf_display[] = {
9487 { BASE_NONE, "BASE_NONE" },
9488 { BASE_DEC, "BASE_DEC" },
9489 { BASE_HEX, "BASE_HEX" },
9490 { BASE_OCT, "BASE_OCT" },
9491 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9492 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9493 { BASE_CUSTOM, "BASE_CUSTOM" },
9494 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9495 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9496 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9497 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9498 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9499 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9500 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9501 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9502 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9503 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9504 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9505 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9506 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9507 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9508 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9509 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9510 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9511 { BASE_PT_UDP, "BASE_PT_UDP" },
9512 { BASE_PT_TCP, "BASE_PT_TCP" },
9513 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9514 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9515 { BASE_OUI, "BASE_OUI" },
9516 { 0, NULL((void*)0) } };
9517
9518const char* proto_field_display_to_string(int field_display)
9519{
9520 return val_to_str_const(field_display, hf_display, "Unknown");
9521}
9522
9523static inline port_type
9524display_to_port_type(field_display_e e)
9525{
9526 switch (e) {
9527 case BASE_PT_UDP:
9528 return PT_UDP;
9529 case BASE_PT_TCP:
9530 return PT_TCP;
9531 case BASE_PT_DCCP:
9532 return PT_DCCP;
9533 case BASE_PT_SCTP:
9534 return PT_SCTP;
9535 default:
9536 break;
9537 }
9538 return PT_NONE;
9539}
9540
9541/* temporary function containing assert part for easier profiling */
9542static void
9543tmp_fld_check_assert(header_field_info *hfinfo)
9544{
9545 char* tmp_str;
9546
9547 /* The field must have a name (with length > 0) */
9548 if (!hfinfo->name || !hfinfo->name[0]) {
9549 if (hfinfo->abbrev)
9550 /* Try to identify the field */
9551 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)
9552 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9553 else
9554 /* Hum, no luck */
9555 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)"
)
;
9556 }
9557
9558 /* fields with an empty string for an abbreviation aren't filterable */
9559 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9560 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)
;
9561
9562 /* TODO: This check is a significant percentage of startup time (~10%),
9563 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9564 It might be nice to have a way to disable this check when, e.g.,
9565 running TShark many times with the same configuration. */
9566 /* Check that the filter name (abbreviation) is legal;
9567 * it must contain only alphanumerics, '-', "_", and ".". */
9568 unsigned char c;
9569 c = module_check_valid_name(hfinfo->abbrev, false0);
9570 if (c) {
9571 if (c == '.') {
9572 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)
;
9573 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9574 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)
;
9575 } else {
9576 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)
;
9577 }
9578 }
9579
9580 /* These types of fields are allowed to have value_strings,
9581 * true_false_strings or a protocol_t struct
9582 */
9583 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9584 switch (hfinfo->type) {
9585
9586 /*
9587 * These types are allowed to support display value_strings,
9588 * value64_strings, the extended versions of the previous
9589 * two, range strings, or unit strings.
9590 */
9591 case FT_CHAR:
9592 case FT_UINT8:
9593 case FT_UINT16:
9594 case FT_UINT24:
9595 case FT_UINT32:
9596 case FT_UINT40:
9597 case FT_UINT48:
9598 case FT_UINT56:
9599 case FT_UINT64:
9600 case FT_INT8:
9601 case FT_INT16:
9602 case FT_INT24:
9603 case FT_INT32:
9604 case FT_INT40:
9605 case FT_INT48:
9606 case FT_INT56:
9607 case FT_INT64:
9608 case FT_BOOLEAN:
9609 case FT_PROTOCOL:
9610 break;
9611
9612 /*
9613 * This is allowed to have a value of type
9614 * enum ft_framenum_type to indicate what relationship
9615 * the frame in question has to the frame in which
9616 * the field is put.
9617 */
9618 case FT_FRAMENUM:
9619 break;
9620
9621 /*
9622 * These types are allowed to support only unit strings.
9623 */
9624 case FT_FLOAT:
9625 case FT_DOUBLE:
9626 case FT_IEEE_11073_SFLOAT:
9627 case FT_IEEE_11073_FLOAT:
9628 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9629 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))
9630 " (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))
9631 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))
;
9632 }
9633 break;
9634
9635 /*
9636 * These types are allowed to support display
9637 * time_value_strings.
9638 */
9639 case FT_ABSOLUTE_TIME:
9640 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9641 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9642 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9643 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9644 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))
9645 " (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))
9646 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))
;
9647 }
9648 break;
9649
9650 /*
9651 * This type is only allowed to support a string if it's
9652 * a protocol (for pinos).
9653 */
9654 case FT_BYTES:
9655 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9656 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))
9657 " (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))
9658 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))
;
9659 }
9660 break;
9661
9662 default:
9663 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))
9664 " (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))
9665 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))
;
9666 }
9667 }
9668
9669 /* TODO: This check may slow down startup, and output quite a few warnings.
9670 It would be good to be able to enable this (and possibly other checks?)
9671 in non-release builds. */
9672#ifdef ENABLE_CHECK_FILTER
9673 /* Check for duplicate value_string values.
9674 There are lots that have the same value *and* string, so for now only
9675 report those that have same value but different string. */
9676 if ((hfinfo->strings != NULL((void*)0)) &&
9677 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9678 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9679 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9680 (
9681 (hfinfo->type == FT_CHAR) ||
9682 (hfinfo->type == FT_UINT8) ||
9683 (hfinfo->type == FT_UINT16) ||
9684 (hfinfo->type == FT_UINT24) ||
9685 (hfinfo->type == FT_UINT32) ||
9686 (hfinfo->type == FT_INT8) ||
9687 (hfinfo->type == FT_INT16) ||
9688 (hfinfo->type == FT_INT24) ||
9689 (hfinfo->type == FT_INT32) )) {
9690
9691 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9692 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9693 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9694 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9695 } else {
9696 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9697 CHECK_HF_VALUE(value_string, "u", start_values);
9698 }
9699 } else {
9700 const value_string *start_values = (const value_string*)hfinfo->strings;
9701 CHECK_HF_VALUE(value_string, "u", start_values);
9702 }
9703 }
9704
9705 if (hfinfo->type == FT_BOOLEAN) {
9706 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9707 if (tfs) {
9708 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9709 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9711
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9710 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9711
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9711 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9711
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9712 }
9713 }
9714 }
9715
9716 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9717 const range_string *rs = (const range_string*)(hfinfo->strings);
9718 if (rs) {
9719 const range_string *this_it = rs;
9720
9721 do {
9722 if (this_it->value_max < this_it->value_min) {
9723 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"
, 9727, __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)
9724 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9727, __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)
9725 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9727, __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)
9726 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9727, __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)
9727 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9727, __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)
;
9728 ++this_it;
9729 continue;
9730 }
9731
9732 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9733 /* Not OK if this one is completely hidden by an earlier one! */
9734 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9735 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"
, 9741, __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)
9736 "(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"
, 9741, __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)
9737 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9741, __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)
9738 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9741, __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)
9739 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9741, __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)
9740 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9741, __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)
9741 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9741, __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)
;
9742 }
9743 }
9744 ++this_it;
9745 } while (this_it->strptr);
9746 }
9747 }
9748#endif
9749
9750 switch (hfinfo->type) {
9751
9752 case FT_CHAR:
9753 /* Require the char type to have BASE_HEX, BASE_OCT,
9754 * BASE_CUSTOM, or BASE_NONE as its base.
9755 *
9756 * If the display value is BASE_NONE and there is a
9757 * strings conversion then the dissector writer is
9758 * telling us that the field's numerical value is
9759 * meaningless; we'll avoid showing the value to the
9760 * user.
9761 */
9762 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9763 case BASE_HEX:
9764 case BASE_OCT:
9765 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9766 break;
9767 case BASE_NONE:
9768 if (hfinfo->strings == NULL((void*)0))
9769 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
))
9770 " 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
))
9771 " 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
))
9772 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
))
9773 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
))
;
9774 break;
9775 default:
9776 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9777 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)
9778 " 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)
9779 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)
9780 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)
;
9781 //wmem_free(NULL, tmp_str);
9782 }
9783 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9784 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
))
9785 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
))
9786 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
))
;
9787 }
9788 break;
9789 case FT_INT8:
9790 case FT_INT16:
9791 case FT_INT24:
9792 case FT_INT32:
9793 case FT_INT40:
9794 case FT_INT48:
9795 case FT_INT56:
9796 case FT_INT64:
9797 /* Hexadecimal and octal are, in printf() and everywhere
9798 * else, unsigned so don't allow dissectors to register a
9799 * signed field to be displayed unsigned. (Else how would
9800 * we display negative values?)
9801 */
9802 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9803 case BASE_HEX:
9804 case BASE_OCT:
9805 case BASE_DEC_HEX:
9806 case BASE_HEX_DEC:
9807 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9808 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)
9809 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)
9810 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)
;
9811 //wmem_free(NULL, tmp_str);
9812 }
9813 /* FALL THROUGH */
9814 case FT_UINT8:
9815 case FT_UINT16:
9816 case FT_UINT24:
9817 case FT_UINT32:
9818 case FT_UINT40:
9819 case FT_UINT48:
9820 case FT_UINT56:
9821 case FT_UINT64:
9822 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
))
) {
9823 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9824 if (hfinfo->type != FT_UINT16) {
9825 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))
9826 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))
9827 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))
;
9828 }
9829 if (hfinfo->strings != NULL((void*)0)) {
9830 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)
9831 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)
9832 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)
;
9833 }
9834 if (hfinfo->bitmask != 0) {
9835 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)
9836 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)
9837 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)
;
9838 }
9839 wmem_free(NULL((void*)0), tmp_str);
9840 break;
9841 }
9842
9843 if (hfinfo->display == BASE_OUI) {
9844 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9845 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) {
9846 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))
9847 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))
9848 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))
;
9849 }
9850 if (hfinfo->strings != NULL((void*)0)) {
9851 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)
9852 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)
9853 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)
;
9854 }
9855 /* It can be a FT_UINT24 with a 0 bitmask, or
9856 * larger with a bitmask with 24 bits set. */
9857 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9858 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)
9859 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)
9860 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)
;
9861 }
9862 wmem_free(NULL((void*)0), tmp_str);
9863 break;
9864 }
9865
9866 /* Require integral types (other than frame number,
9867 * which is always displayed in decimal) to have a
9868 * number base.
9869 *
9870 * If the display value is BASE_NONE and there is a
9871 * strings conversion then the dissector writer is
9872 * telling us that the field's numerical value is
9873 * meaningless; we'll avoid showing the value to the
9874 * user.
9875 */
9876 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9877 case BASE_DEC:
9878 case BASE_HEX:
9879 case BASE_OCT:
9880 case BASE_DEC_HEX:
9881 case BASE_HEX_DEC:
9882 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9883 break;
9884 case BASE_NONE:
9885 if (hfinfo->strings == NULL((void*)0)) {
9886 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
))
9887 " 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
))
9888 " 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
))
9889 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
))
9890 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
))
;
9891 }
9892 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9893 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
))
9894 " 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
))
9895 " 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
))
9896 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
))
9897 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
))
;
9898 }
9899 break;
9900
9901 default:
9902 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9903 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)
9904 " 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)
9905 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)
9906 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)
;
9907 //wmem_free(NULL, tmp_str);
9908 }
9909 break;
9910 case FT_BYTES:
9911 case FT_UINT_BYTES:
9912 /* Require bytes to have a "display type" that could
9913 * add a character between displayed bytes.
9914 */
9915 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9916 case BASE_NONE:
9917 case SEP_DOT:
9918 case SEP_DASH:
9919 case SEP_COLON:
9920 case SEP_SPACE:
9921 break;
9922 default:
9923 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9924 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)
9925 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)
;
9926 //wmem_free(NULL, tmp_str);
9927 }
9928 if (hfinfo->bitmask != 0)
9929 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
))
9930 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
))
9931 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
))
;
9932 //allowed to support string if its a protocol (for pinos)
9933 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
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
9939 case FT_PROTOCOL:
9940 case FT_FRAMENUM:
9941 if (hfinfo->display != BASE_NONE) {
9942 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9943 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)
9944 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)
9945 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)
;
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 break;
9953
9954 case FT_BOOLEAN:
9955 break;
9956
9957 case FT_ABSOLUTE_TIME:
9958 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9959 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9960 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)
9961 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)
;
9962 //wmem_free(NULL, tmp_str);
9963 }
9964 if (hfinfo->bitmask != 0)
9965 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9966 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9967 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9968 break;
9969
9970 case FT_STRING:
9971 case FT_STRINGZ:
9972 case FT_UINT_STRING:
9973 case FT_STRINGZPAD:
9974 case FT_STRINGZTRUNC:
9975 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9976 case BASE_NONE:
9977 case BASE_STR_WSP:
9978 break;
9979
9980 default:
9981 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9982 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)
9983 " 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)
9984 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)
9985 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)
;
9986 //wmem_free(NULL, tmp_str);
9987 }
9988
9989 if (hfinfo->bitmask != 0)
9990 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
))
9991 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
))
9992 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
))
;
9993 if (hfinfo->strings != NULL((void*)0))
9994 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
))
9995 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
))
9996 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
))
;
9997 break;
9998
9999 case FT_IPv4:
10000 switch (hfinfo->display) {
10001 case BASE_NONE:
10002 case BASE_NETMASK:
10003 break;
10004
10005 default:
10006 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10007 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)
10008 " 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)
10009 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)
10010 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)
;
10011 //wmem_free(NULL, tmp_str);
10012 break;
10013 }
10014 break;
10015 case FT_FLOAT:
10016 case FT_DOUBLE:
10017 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
10018 case BASE_NONE:
10019 case BASE_DEC:
10020 case BASE_HEX:
10021 case BASE_EXP:
10022 case BASE_CUSTOM:
10023 break;
10024 default:
10025 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10026 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)
10027 " 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)
10028 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)
10029 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)
;
10030 //wmem_free(NULL, tmp_str);
10031 }
10032 if (hfinfo->bitmask != 0)
10033 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
))
10034 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
))
10035 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
))
;
10036 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10037 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
))
10038 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
))
10039 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
))
;
10040 break;
10041 case FT_IEEE_11073_SFLOAT:
10042 case FT_IEEE_11073_FLOAT:
10043 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
10044 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10045 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)
10046 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)
10047 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)
10048 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)
;
10049 //wmem_free(NULL, tmp_str);
10050 }
10051 if (hfinfo->bitmask != 0)
10052 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
))
10053 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
))
10054 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
))
;
10055 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10056 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
))
10057 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
))
10058 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
))
;
10059 break;
10060 default:
10061 if (hfinfo->display != BASE_NONE) {
10062 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10063 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)
10064 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)
10065 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)
10066 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)
;
10067 //wmem_free(NULL, tmp_str);
10068 }
10069 if (hfinfo->bitmask != 0)
10070 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
))
10071 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
))
10072 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
))
;
10073 if (hfinfo->strings != NULL((void*)0))
10074 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
))
10075 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
))
10076 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
))
;
10077 break;
10078 }
10079}
10080
10081static void
10082register_type_length_mismatch(void)
10083{
10084 static ei_register_info ei[] = {
10085 { &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)}}
}},
10086 { &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)}}
}},
10087 };
10088
10089 expert_module_t* expert_type_length_mismatch;
10090
10091 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10092
10093 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10094 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10095
10096 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10097 disabling them makes no sense. */
10098 proto_set_cant_toggle(proto_type_length_mismatch);
10099}
10100
10101static void
10102register_byte_array_string_decodinws_error(void)
10103{
10104 static ei_register_info ei[] = {
10105 { &ei_byte_array_string_decoding_failed_error,
10106 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10107 "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)}}
10108 }
10109 },
10110 };
10111
10112 expert_module_t* expert_byte_array_string_decoding_error;
10113
10114 proto_byte_array_string_decoding_error =
10115 proto_register_protocol("Byte Array-String Decoding Error",
10116 "Byte Array-string decoding error",
10117 "_ws.byte_array_string.decoding_error");
10118
10119 expert_byte_array_string_decoding_error =
10120 expert_register_protocol(proto_byte_array_string_decoding_error);
10121 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10122
10123 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10124 disabling them makes no sense. */
10125 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10126}
10127
10128static void
10129register_date_time_string_decodinws_error(void)
10130{
10131 static ei_register_info ei[] = {
10132 { &ei_date_time_string_decoding_failed_error,
10133 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10134 "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)}}
10135 }
10136 },
10137 };
10138
10139 expert_module_t* expert_date_time_string_decoding_error;
10140
10141 proto_date_time_string_decoding_error =
10142 proto_register_protocol("Date and Time-String Decoding Error",
10143 "Date and Time-string decoding error",
10144 "_ws.date_time_string.decoding_error");
10145
10146 expert_date_time_string_decoding_error =
10147 expert_register_protocol(proto_date_time_string_decoding_error);
10148 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10149
10150 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10151 disabling them makes no sense. */
10152 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10153}
10154
10155static void
10156register_string_errors(void)
10157{
10158 static ei_register_info ei[] = {
10159 { &ei_string_trailing_characters,
10160 { "_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)}}
}
10161 },
10162 };
10163
10164 expert_module_t* expert_string_errors;
10165
10166 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10167
10168 expert_string_errors = expert_register_protocol(proto_string_errors);
10169 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10170
10171 /* "String Errors" isn't really a protocol, it's an error indication;
10172 disabling them makes no sense. */
10173 proto_set_cant_toggle(proto_string_errors);
10174}
10175
10176static void
10177register_varint_errors(void)
10178{
10179 static ei_register_info ei[] = {
10180 { &ei_varint_decoding_failed_error,
10181 { "_ws.varint.decoding_failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Varint decoding failed", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}
10182 },
10183 };
10184
10185 expert_module_t* expert_varint_errors;
10186
10187 proto_varint_errors = proto_register_protocol("Varint Errors", "Varint errors", "_ws.varint");
10188
10189 expert_varint_errors = expert_register_protocol(proto_varint_errors);
10190 expert_register_field_array(expert_varint_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10191
10192 /* "Varint Errors" isn't really a protocol, it's an error indication;
10193 disabling them makes no sense. */
10194 proto_set_cant_toggle(proto_varint_errors);
10195}
10196
10197static int
10198proto_register_field_init(header_field_info *hfinfo, const int parent)
10199{
10200
10201 tmp_fld_check_assert(hfinfo);
10202
10203 hfinfo->parent = parent;
10204 hfinfo->same_name_next = NULL((void*)0);
10205 hfinfo->same_name_prev_id = -1;
10206
10207 /* if we always add and never delete, then id == len - 1 is correct */
10208 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10209 if (!gpa_hfinfo.hfi) {
10210 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10211 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10212 /* The entry with index 0 is not used. */
10213 gpa_hfinfo.hfi[0] = NULL((void*)0);
10214 gpa_hfinfo.len = 1;
10215 } else {
10216 gpa_hfinfo.allocated_len += 1000;
10217 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10218 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10219 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10220 }
10221 }
10222 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10223 gpa_hfinfo.len++;
10224 hfinfo->id = gpa_hfinfo.len - 1;
10225
10226 /* if we have real names, enter this field in the name tree */
10227 /* Already checked in tmp_fld_check_assert */
10228 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10229 {
10230
10231 header_field_info *same_name_next_hfinfo;
10232
10233 /* We allow multiple hfinfo's to be registered under the same
10234 * abbreviation. This was done for X.25, as, depending
10235 * on whether it's modulo-8 or modulo-128 operation,
10236 * some bitfield fields may be in different bits of
10237 * a byte, and we want to be able to refer to that field
10238 * with one name regardless of whether the packets
10239 * are modulo-8 or modulo-128 packets. */
10240
10241 /* wmem_map_insert - if key is already present the previous
10242 * hfinfo with the same key/name is returned, otherwise NULL */
10243 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10244 if (same_name_hfinfo) {
10245 /* There's already a field with this name.
10246 * Put the current field *before* that field
10247 * in the list of fields with this name, Thus,
10248 * we end up with an effectively
10249 * doubly-linked-list of same-named hfinfo's,
10250 * with the head of the list (stored in the
10251 * hash) being the last seen hfinfo.
10252 */
10253 same_name_next_hfinfo =
10254 same_name_hfinfo->same_name_next;
10255
10256 hfinfo->same_name_next = same_name_next_hfinfo;
10257 if (same_name_next_hfinfo)
10258 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10259
10260 same_name_hfinfo->same_name_next = hfinfo;
10261 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10262#ifdef ENABLE_CHECK_FILTER
10263 while (same_name_hfinfo) {
10264 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10265 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", 10265
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10266 same_name_hfinfo = same_name_hfinfo->same_name_next;
10267 }
10268#endif
10269 }
10270 }
10271
10272 return hfinfo->id;
10273}
10274
10275void
10276proto_register_subtree_array(int * const *indices, const int num_indices)
10277{
10278 int i;
10279 int *const *ptr = indices;
10280
10281 /*
10282 * If we've already allocated the array of tree types, expand
10283 * it; this lets plugins such as mate add tree types after
10284 * the initial startup. (If we haven't already allocated it,
10285 * we don't allocate it; on the first pass, we just assign
10286 * ett values and keep track of how many we've assigned, and
10287 * when we're finished registering all dissectors we allocate
10288 * the array, so that we do only one allocation rather than
10289 * wasting CPU time and memory by growing the array for each
10290 * dissector that registers ett values.)
10291 */
10292 if (tree_is_expanded != NULL((void*)0)) {
10293 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10294
10295 /* set new items to 0 */
10296 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10297 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10298 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10299 }
10300
10301 /*
10302 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10303 * returning the indices through the pointers in the array whose
10304 * first element is pointed to by "indices", and update
10305 * "num_tree_types" appropriately.
10306 */
10307 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10308 if (**ptr != -1 && **ptr != 0) {
10309 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.")
10310 " 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.")
10311 " 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.")
10312 " 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.")
;
10313 }
10314 **ptr = num_tree_types;
10315 }
10316}
10317
10318static void
10319mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10320{
10321 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10322 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10323 char *last_char;
10324
10325 /* ..... field_name: dataaaaaaaaaaaaa
10326 * |
10327 * ^^^^^ name_pos
10328 *
10329 * ..... field_name […]: dataaaaaaaaaaaaa
10330 *
10331 * name_pos==0 means that we have only data or only a field_name
10332 */
10333
10334 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10334, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10335
10336 if (name_pos >= size - trunc_len) {
10337 /* No room for trunc_str after the field_name, put it first. */
10338 name_pos = 0;
10339 }
10340
10341 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10342 if (name_pos == 0) {
10343 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10344 memcpy(label_str, trunc_str + 1, trunc_len);
10345 } else {
10346 memcpy(label_str + name_pos, trunc_str, trunc_len);
10347 }
10348 /* in general, label_str is UTF-8
10349 we can truncate it only at the beginning of a new character
10350 we go backwards from the byte right after our buffer and
10351 find the next starting byte of a UTF-8 character, this is
10352 where we cut
10353 there's no need to use g_utf8_find_prev_char(), the search
10354 will always succeed since we copied trunc_str into the
10355 buffer */
10356 /* g_utf8_prev_char does not deference the memory address
10357 * passed in (until after decrementing it, so it is perfectly
10358 * legal to pass in a pointer one past the last element.
10359 */
10360 last_char = g_utf8_prev_char(label_str + size);
10361 *last_char = '\0';
10362 /* This is unnecessary (above always terminates), but try to
10363 * convince Coverity to avoid dozens of false positives. */
10364 label_str[size - 1] = '\0';
10365
10366 if (value_pos && *value_pos > 0) {
10367 if (name_pos == 0) {
10368 *value_pos += trunc_len;
10369 } else {
10370 /* Move one back to include trunc_str in the value. */
10371 *value_pos -= 1;
10372 }
10373 }
10374
10375 /* Check if value_pos is past label_str. */
10376 if (value_pos && *value_pos >= size) {
10377 *value_pos = size - 1;
10378 }
10379}
10380
10381static void
10382label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10383{
10384 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10385}
10386
10387static size_t
10388label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10389{
10390 size_t name_pos;
10391
10392 /* "%s: %s", hfinfo->name, text */
10393 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)
;
10394 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10395 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10396 if (value_pos) {
10397 *value_pos = pos;
10398 }
10399 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10400 }
10401
10402 if (pos >= ITEM_LABEL_LENGTH240) {
10403 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10404 label_mark_truncated(label_str, name_pos, value_pos);
10405 }
10406
10407 return pos;
10408}
10409
10410static size_t
10411label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10412{
10413 size_t name_pos;
10414
10415 /* "%s: %s (%s)", hfinfo->name, text, descr */
10416 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)
;
10417 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10418 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10419 if (value_pos) {
10420 *value_pos = pos;
10421 }
10422 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10423 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)
;
10424 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)
;
10425 } else {
10426 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)
;
10427 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10428 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)
;
10429 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10430 }
10431 }
10432
10433 if (pos >= ITEM_LABEL_LENGTH240) {
10434 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10435 label_mark_truncated(label_str, name_pos, value_pos);
10436 }
10437
10438 return pos;
10439}
10440
10441void
10442proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10443{
10444 const header_field_info *hfinfo;
10445 const char *str;
10446 const uint8_t *bytes;
10447 uint32_t integer;
10448 const ipv4_addr_and_mask *ipv4;
10449 const ipv6_addr_and_prefix *ipv6;
10450 const e_guid_t *guid;
10451 char *name;
10452 address addr;
10453 char *addr_str;
10454 char *tmp;
10455
10456 if (!label_str) {
10457 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10457, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10458 return;
10459 }
10460
10461 label_str[0]= '\0';
10462
10463 if (!fi) {
10464 return;
10465 }
10466
10467 hfinfo = fi->hfinfo;
10468
10469 switch (hfinfo->type) {
10470 case FT_NONE:
10471 case FT_PROTOCOL:
10472 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10473 if (value_pos) {
10474 *value_pos = strlen(hfinfo->name);
10475 }
10476 break;
10477
10478 case FT_BOOLEAN:
10479 fill_label_boolean(fi, label_str, value_pos);
10480 break;
10481
10482 case FT_BYTES:
10483 case FT_UINT_BYTES:
10484 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10485 fvalue_get_bytes_data(fi->value),
10486 (unsigned)fvalue_length2(fi->value));
10487 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10488 wmem_free(NULL((void*)0), tmp);
10489 break;
10490
10491 case FT_CHAR:
10492 if (hfinfo->bitmask) {
10493 fill_label_bitfield_char(fi, label_str, value_pos);
10494 } else {
10495 fill_label_char(fi, label_str, value_pos);
10496 }
10497 break;
10498
10499 /* Four types of integers to take care of:
10500 * Bitfield, with val_string
10501 * Bitfield, w/o val_string
10502 * Non-bitfield, with val_string
10503 * Non-bitfield, w/o val_string
10504 */
10505 case FT_UINT8:
10506 case FT_UINT16:
10507 case FT_UINT24:
10508 case FT_UINT32:
10509 if (hfinfo->bitmask) {
10510 fill_label_bitfield(fi, label_str, value_pos, false0);
10511 } else {
10512 fill_label_number(fi, label_str, value_pos, false0);
10513 }
10514 break;
10515
10516 case FT_FRAMENUM:
10517 fill_label_number(fi, label_str, value_pos, false0);
10518 break;
10519
10520 case FT_UINT40:
10521 case FT_UINT48:
10522 case FT_UINT56:
10523 case FT_UINT64:
10524 if (hfinfo->bitmask) {
10525 fill_label_bitfield64(fi, label_str, value_pos, false0);
10526 } else {
10527 fill_label_number64(fi, label_str, value_pos, false0);
10528 }
10529 break;
10530
10531 case FT_INT8:
10532 case FT_INT16:
10533 case FT_INT24:
10534 case FT_INT32:
10535 if (hfinfo->bitmask) {
10536 fill_label_bitfield(fi, label_str, value_pos, true1);
10537 } else {
10538 fill_label_number(fi, label_str, value_pos, true1);
10539 }
10540 break;
10541
10542 case FT_INT40:
10543 case FT_INT48:
10544 case FT_INT56:
10545 case FT_INT64:
10546 if (hfinfo->bitmask) {
10547 fill_label_bitfield64(fi, label_str, value_pos, true1);
10548 } else {
10549 fill_label_number64(fi, label_str, value_pos, true1);
10550 }
10551 break;
10552
10553 case FT_FLOAT:
10554 case FT_DOUBLE:
10555 fill_label_float(fi, label_str, value_pos);
10556 break;
10557
10558 case FT_ABSOLUTE_TIME:
10559 {
10560 const nstime_t *value = fvalue_get_time(fi->value);
10561 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10562 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10563 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10564 }
10565 if (hfinfo->strings) {
10566 /*
10567 * Table of time values to be displayed
10568 * specially.
10569 *
10570 * XXX - Initializing these time_value_strings can be a pain
10571 * because the special times usually have special values in
10572 * the original encoding, not when converted to a nstime_t
10573 * relative to the UN*X epoch.
10574 */
10575 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10576 if (time_string != NULL((void*)0)) {
10577 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10578 break;
10579 }
10580 }
10581 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10582 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10583 wmem_free(NULL((void*)0), tmp);
10584 break;
10585 }
10586 case FT_RELATIVE_TIME:
10587 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10588 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10589 wmem_free(NULL((void*)0), tmp);
10590 break;
10591
10592 case FT_IPXNET:
10593 integer = fvalue_get_uinteger(fi->value);
10594 tmp = get_ipxnet_name(NULL((void*)0), integer);
10595 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10596 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10597 wmem_free(NULL((void*)0), tmp);
10598 wmem_free(NULL((void*)0), addr_str);
10599 break;
10600
10601 case FT_VINES:
10602 addr.type = AT_VINES;
10603 addr.len = VINES_ADDR_LEN6;
10604 addr.data = fvalue_get_bytes_data(fi->value);
10605
10606 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10607 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10608 wmem_free(NULL((void*)0), addr_str);
10609 break;
10610
10611 case FT_ETHER:
10612 bytes = fvalue_get_bytes_data(fi->value);
10613
10614 addr.type = AT_ETHER;
10615 addr.len = 6;
10616 addr.data = bytes;
10617
10618 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10619 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10620 wmem_free(NULL((void*)0), addr_str);
10621 break;
10622
10623 case FT_IPv4:
10624 ipv4 = fvalue_get_ipv4(fi->value);
10625 set_address_ipv4(&addr, ipv4);
10626
10627 if (hfinfo->display == BASE_NETMASK) {
10628 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10629 } else {
10630 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10631 }
10632 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10633 wmem_free(NULL((void*)0), addr_str);
10634 free_address(&addr);
10635 break;
10636
10637 case FT_IPv6:
10638 ipv6 = fvalue_get_ipv6(fi->value);
10639 set_address_ipv6(&addr, ipv6);
10640
10641 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10642 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10643 wmem_free(NULL((void*)0), addr_str);
10644 free_address(&addr);
10645 break;
10646
10647 case FT_FCWWN:
10648 bytes = fvalue_get_bytes_data(fi->value);
10649 addr.type = AT_FCWWN;
10650 addr.len = FCWWN_ADDR_LEN8;
10651 addr.data = bytes;
10652
10653 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10654 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10655 wmem_free(NULL((void*)0), addr_str);
10656 break;
10657
10658 case FT_GUID:
10659 guid = fvalue_get_guid(fi->value);
10660 tmp = guid_to_str(NULL((void*)0), guid);
10661 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10662 wmem_free(NULL((void*)0), tmp);
10663 break;
10664
10665 case FT_OID:
10666 bytes = fvalue_get_bytes_data(fi->value);
10667 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10668 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10669 if (name) {
10670 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10671 wmem_free(NULL((void*)0), name);
10672 } else {
10673 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10674 }
10675 wmem_free(NULL((void*)0), tmp);
10676 break;
10677
10678 case FT_REL_OID:
10679 bytes = fvalue_get_bytes_data(fi->value);
10680 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10681 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10682 if (name) {
10683 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10684 wmem_free(NULL((void*)0), name);
10685 } else {
10686 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10687 }
10688 wmem_free(NULL((void*)0), tmp);
10689 break;
10690
10691 case FT_SYSTEM_ID:
10692 bytes = fvalue_get_bytes_data(fi->value);
10693 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10694 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10695 wmem_free(NULL((void*)0), tmp);
10696 break;
10697
10698 case FT_EUI64:
10699 bytes = fvalue_get_bytes_data(fi->value);
10700 addr.type = AT_EUI64;
10701 addr.len = EUI64_ADDR_LEN8;
10702 addr.data = bytes;
10703
10704 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10705 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10706 wmem_free(NULL((void*)0), addr_str);
10707 break;
10708 case FT_STRING:
10709 case FT_STRINGZ:
10710 case FT_UINT_STRING:
10711 case FT_STRINGZPAD:
10712 case FT_STRINGZTRUNC:
10713 case FT_AX25:
10714 str = fvalue_get_string(fi->value);
10715 label_fill(label_str, 0, hfinfo, str, value_pos);
10716 break;
10717
10718 case FT_IEEE_11073_SFLOAT:
10719 case FT_IEEE_11073_FLOAT:
10720 fill_label_ieee_11073_float(fi, label_str, value_pos);
10721 break;
10722
10723 default:
10724 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
))
10725 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
))
10726 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
))
10727 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
))
;
10728 break;
10729 }
10730}
10731
10732static void
10733fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10734{
10735 char *p;
10736 unsigned bitfield_byte_length = 0;
10737 int bitwidth;
10738 uint64_t unshifted_value;
10739 uint64_t value;
10740
10741 const header_field_info *hfinfo = fi->hfinfo;
10742
10743 value = fvalue_get_uinteger64(fi->value);
10744 if (hfinfo->bitmask) {
10745 /* Figure out the bit width */
10746 bitwidth = hfinfo_container_bitwidth(hfinfo);
10747
10748 /* Un-shift bits */
10749 unshifted_value = value;
10750 unshifted_value <<= hfinfo_bitshift(hfinfo);
10751
10752 /* Create the bitfield first */
10753 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10754 bitfield_byte_length = (unsigned) (p - label_str);
10755 }
10756
10757 /* Fill in the textual info */
10758 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10759}
10760
10761static const char *
10762hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10763{
10764 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10765 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10766
10767 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10768 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10769 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10770 else
10771 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10772 }
10773
10774 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10775 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10776
10777 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10778 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10779
10780 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10781}
10782
10783static const char *
10784hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10785{
10786 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10787 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10788 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10789 else
10790 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10791 }
10792
10793 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10794 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10795
10796 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10797 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10798
10799 /* If this is reached somebody registered a 64-bit field with a 32-bit
10800 * value-string, which isn't right. */
10801 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)
10802 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10803
10804 /* This is necessary to squelch MSVC errors; is there
10805 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10806 never returns? */
10807 return NULL((void*)0);
10808}
10809
10810static const char *
10811hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10812{
10813 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10814 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10815
10816 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)
;
10817
10818 /* This is necessary to squelch MSVC errors; is there
10819 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10820 never returns? */
10821 return NULL((void*)0);
10822}
10823
10824static const char *
10825hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10826{
10827 const char *str = hf_try_val_to_str(value, hfinfo);
10828
10829 return (str) ? str : unknown_str;
10830}
10831
10832static const char *
10833hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10834{
10835 const char *str = hf_try_val64_to_str(value, hfinfo);
10836
10837 return (str) ? str : unknown_str;
10838}
10839
10840/* Fills data for bitfield chars with val_strings */
10841static void
10842fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10843{
10844 char *p;
10845 unsigned bitfield_byte_length;
10846 int bitwidth;
10847 uint32_t unshifted_value;
10848 uint32_t value;
10849
10850 char buf[32];
10851 const char *out;
10852
10853 const header_field_info *hfinfo = fi->hfinfo;
10854
10855 /* Figure out the bit width */
10856 bitwidth = hfinfo_container_bitwidth(hfinfo);
10857
10858 /* Un-shift bits */
10859 value = fvalue_get_uinteger(fi->value);
10860
10861 unshifted_value = value;
10862 if (hfinfo->bitmask) {
10863 unshifted_value <<= hfinfo_bitshift(hfinfo);
10864 }
10865
10866 /* Create the bitfield first */
10867 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10868 bitfield_byte_length = (unsigned) (p - label_str);
10869
10870 /* Fill in the textual info using stored (shifted) value */
10871 if (hfinfo->display == BASE_CUSTOM) {
10872 char tmp[ITEM_LABEL_LENGTH240];
10873 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10874
10875 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10875, "fmtfunc"))))
;
10876 fmtfunc(tmp, value);
10877 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10878 }
10879 else if (hfinfo->strings) {
10880 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10881
10882 out = hfinfo_char_vals_format(hfinfo, buf, value);
10883 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10884 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10885 else
10886 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10887 }
10888 else {
10889 out = hfinfo_char_value_format(hfinfo, buf, value);
10890
10891 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10892 }
10893}
10894
10895/* Fills data for bitfield ints with val_strings */
10896static void
10897fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10898{
10899 char *p;
10900 unsigned bitfield_byte_length;
10901 int bitwidth;
10902 uint32_t value, unshifted_value;
10903 char buf[NUMBER_LABEL_LENGTH80];
10904 const char *out;
10905
10906 const header_field_info *hfinfo = fi->hfinfo;
10907
10908 /* Figure out the bit width */
10909 if (fi->flags & FI_VARINT0x00040000)
10910 bitwidth = fi->length*8;
10911 else
10912 bitwidth = hfinfo_container_bitwidth(hfinfo);
10913
10914 /* Un-shift bits */
10915 if (is_signed)
10916 value = fvalue_get_sinteger(fi->value);
10917 else
10918 value = fvalue_get_uinteger(fi->value);
10919
10920 unshifted_value = value;
10921 if (hfinfo->bitmask) {
10922 unshifted_value <<= hfinfo_bitshift(hfinfo);
10923 }
10924
10925 /* Create the bitfield first */
10926 if (fi->flags & FI_VARINT0x00040000)
10927 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10928 else
10929 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10930 bitfield_byte_length = (unsigned) (p - label_str);
10931
10932 /* Fill in the textual info using stored (shifted) value */
10933 if (hfinfo->display == BASE_CUSTOM) {
10934 char tmp[ITEM_LABEL_LENGTH240];
10935 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10936
10937 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10937, "fmtfunc"))))
;
10938 fmtfunc(tmp, value);
10939 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10940 }
10941 else if (hfinfo->strings) {
10942 const char *val_str = hf_try_val_to_str(value, hfinfo);
10943
10944 out = hfinfo_number_vals_format(hfinfo, buf, value);
10945 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10946 /*
10947 * Unique values only display value_string string
10948 * if there is a match. Otherwise it's just a number
10949 */
10950 if (val_str) {
10951 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10952 } else {
10953 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10954 }
10955 } else {
10956 if (val_str == NULL((void*)0))
10957 val_str = "Unknown";
10958
10959 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10960 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10961 else
10962 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10963 }
10964 }
10965 else {
10966 out = hfinfo_number_value_format(hfinfo, buf, value);
10967
10968 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10969 }
10970}
10971
10972static void
10973fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10974{
10975 char *p;
10976 unsigned bitfield_byte_length;
10977 int bitwidth;
10978 uint64_t value, unshifted_value;
10979 char buf[NUMBER_LABEL_LENGTH80];
10980 const char *out;
10981
10982 const header_field_info *hfinfo = fi->hfinfo;
10983
10984 /* Figure out the bit width */
10985 if (fi->flags & FI_VARINT0x00040000)
10986 bitwidth = fi->length*8;
10987 else
10988 bitwidth = hfinfo_container_bitwidth(hfinfo);
10989
10990 /* Un-shift bits */
10991 if (is_signed)
10992 value = fvalue_get_sinteger64(fi->value);
10993 else
10994 value = fvalue_get_uinteger64(fi->value);
10995
10996 unshifted_value = value;
10997 if (hfinfo->bitmask) {
10998 unshifted_value <<= hfinfo_bitshift(hfinfo);
10999 }
11000
11001 /* Create the bitfield first */
11002 if (fi->flags & FI_VARINT0x00040000)
11003 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11004 else
11005 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11006 bitfield_byte_length = (unsigned) (p - label_str);
11007
11008 /* Fill in the textual info using stored (shifted) value */
11009 if (hfinfo->display == BASE_CUSTOM) {
11010 char tmp[ITEM_LABEL_LENGTH240];
11011 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11012
11013 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11013, "fmtfunc64"
))))
;
11014 fmtfunc64(tmp, value);
11015 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
11016 }
11017 else if (hfinfo->strings) {
11018 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11019
11020 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11021 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11022 /*
11023 * Unique values only display value_string string
11024 * if there is a match. Otherwise it's just a number
11025 */
11026 if (val_str) {
11027 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11028 } else {
11029 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11030 }
11031 } else {
11032 if (val_str == NULL((void*)0))
11033 val_str = "Unknown";
11034
11035 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11036 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
11037 else
11038 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11039 }
11040 }
11041 else {
11042 out = hfinfo_number_value_format64(hfinfo, buf, value);
11043
11044 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11045 }
11046}
11047
11048static void
11049fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
11050{
11051 const header_field_info *hfinfo = fi->hfinfo;
11052 uint32_t value;
11053
11054 char buf[32];
11055 const char *out;
11056
11057 value = fvalue_get_uinteger(fi->value);
11058
11059 /* Fill in the textual info */
11060 if (hfinfo->display == BASE_CUSTOM) {
11061 char tmp[ITEM_LABEL_LENGTH240];
11062 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11063
11064 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11064, "fmtfunc"))))
;
11065 fmtfunc(tmp, value);
11066 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11067 }
11068 else if (hfinfo->strings) {
11069 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
11070
11071 out = hfinfo_char_vals_format(hfinfo, buf, value);
11072 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11073 }
11074 else {
11075 out = hfinfo_char_value_format(hfinfo, buf, value);
11076
11077 label_fill(label_str, 0, hfinfo, out, value_pos);
11078 }
11079}
11080
11081static void
11082fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11083{
11084 const header_field_info *hfinfo = fi->hfinfo;
11085 uint32_t value;
11086
11087 char buf[NUMBER_LABEL_LENGTH80];
11088 const char *out;
11089
11090 if (is_signed)
11091 value = fvalue_get_sinteger(fi->value);
11092 else
11093 value = fvalue_get_uinteger(fi->value);
11094
11095 /* Fill in the textual info */
11096 if (hfinfo->display == BASE_CUSTOM) {
11097 char tmp[ITEM_LABEL_LENGTH240];
11098 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11099
11100 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11100, "fmtfunc"))))
;
11101 fmtfunc(tmp, value);
11102 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11103 }
11104 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
11105 /*
11106 * It makes no sense to have a value-string table for a
11107 * frame-number field - they're just integers giving
11108 * the ordinal frame number.
11109 */
11110 const char *val_str = hf_try_val_to_str(value, hfinfo);
11111
11112 out = hfinfo_number_vals_format(hfinfo, buf, value);
11113 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11114 /*
11115 * Unique values only display value_string string
11116 * if there is a match. Otherwise it's just a number
11117 */
11118 if (val_str) {
11119 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11120 } else {
11121 label_fill(label_str, 0, hfinfo, out, value_pos);
11122 }
11123 } else {
11124 if (val_str == NULL((void*)0))
11125 val_str = "Unknown";
11126
11127 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11128 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11129 else
11130 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11131 }
11132 }
11133 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
))
) {
11134 char tmp[ITEM_LABEL_LENGTH240];
11135
11136 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11137 display_to_port_type((field_display_e)hfinfo->display), value);
11138 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11139 }
11140 else {
11141 out = hfinfo_number_value_format(hfinfo, buf, value);
11142
11143 label_fill(label_str, 0, hfinfo, out, value_pos);
11144 }
11145}
11146
11147static void
11148fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11149{
11150 const header_field_info *hfinfo = fi->hfinfo;
11151 uint64_t value;
11152
11153 char buf[NUMBER_LABEL_LENGTH80];
11154 const char *out;
11155
11156 if (is_signed)
11157 value = fvalue_get_sinteger64(fi->value);
11158 else
11159 value = fvalue_get_uinteger64(fi->value);
11160
11161 /* Fill in the textual info */
11162 if (hfinfo->display == BASE_CUSTOM) {
11163 char tmp[ITEM_LABEL_LENGTH240];
11164 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11165
11166 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 11166, "fmtfunc64"
))))
;
11167 fmtfunc64(tmp, value);
11168 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11169 }
11170 else if (hfinfo->strings) {
11171 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11172
11173 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11174 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11175 /*
11176 * Unique values only display value_string string
11177 * if there is a match. Otherwise it's just a number
11178 */
11179 if (val_str) {
11180 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11181 } else {
11182 label_fill(label_str, 0, hfinfo, out, value_pos);
11183 }
11184 } else {
11185 if (val_str == NULL((void*)0))
11186 val_str = "Unknown";
11187
11188 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11189 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11190 else
11191 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11192 }
11193 }
11194 else {
11195 out = hfinfo_number_value_format64(hfinfo, buf, value);
11196
11197 label_fill(label_str, 0, hfinfo, out, value_pos);
11198 }
11199}
11200
11201static size_t
11202fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11203{
11204 int display;
11205 int n;
11206 double value;
11207
11208 if (label_str_size < 12) {
11209 /* Not enough room to write an entire floating point value. */
11210 return 0;
11211 }
11212
11213 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11214 value = fvalue_get_floating(fi->value);
11215
11216 if (display == BASE_CUSTOM) {
11217 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11218 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11218, "fmtfunc"))))
;
11219 fmtfunc(label_str, value);
11220 return strlen(label_str);
11221 }
11222
11223 switch (display) {
11224 case BASE_NONE:
11225 if (fi->hfinfo->type == FT_FLOAT) {
11226 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11227 } else {
11228 n = (int)strlen(dtoa_g_fmt(label_str, value));
11229 }
11230 break;
11231 case BASE_DEC:
11232 n = snprintf(label_str, label_str_size, "%f", value);
11233 break;
11234 case BASE_HEX:
11235 n = snprintf(label_str, label_str_size, "%a", value);
11236 break;
11237 case BASE_EXP:
11238 n = snprintf(label_str, label_str_size, "%e", value);
11239 break;
11240 default:
11241 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11241
, __func__, "assertion \"not reached\" failed")
;
11242 }
11243 if (n < 0) {
11244 return 0; /* error */
11245 }
11246 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11247 const char *hf_str_val;
11248 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11249 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11250 }
11251 if (n > label_str_size) {
11252 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11252, __func__, "label length too small"); } } while (0)
;
11253 return strlen(label_str);
11254 }
11255
11256 return n;
11257}
11258
11259void
11260fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11261{
11262 char tmp[ITEM_LABEL_LENGTH240];
11263
11264 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11265 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11266}
11267
11268static size_t
11269fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11270{
11271 int display;
11272 size_t pos = 0;
11273 double value;
11274 char* tmp_str;
11275
11276 if (label_str_size < 12) {
11277 /* Not enough room to write an entire floating point value. */
11278 return 0;
11279 }
11280
11281 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11282 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11283 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11284 wmem_free(NULL((void*)0), tmp_str);
11285
11286 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11287 const char *hf_str_val;
11288 fvalue_to_double(fi->value, &value);
11289 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11290 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)
;
11291 }
11292 if ((int)pos > label_str_size) {
11293 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11293, __func__, "label length too small"); } } while (0)
;
11294 return strlen(label_str);
11295 }
11296
11297 return pos;
11298}
11299
11300void
11301fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11302{
11303 char tmp[ITEM_LABEL_LENGTH240];
11304
11305 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11306 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11307}
11308
11309int
11310hfinfo_bitshift(const header_field_info *hfinfo)
11311{
11312 return ws_ctz(hfinfo->bitmask);
11313}
11314
11315
11316static int
11317hfinfo_bitoffset(const header_field_info *hfinfo)
11318{
11319 if (!hfinfo->bitmask) {
11320 return 0;
11321 }
11322
11323 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11324 * as the first bit */
11325 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11326}
11327
11328static int
11329hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11330{
11331 if (!hfinfo->bitmask) {
11332 return 0;
11333 }
11334
11335 /* ilog2 = first set bit, ctz = last set bit */
11336 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11337}
11338
11339static int
11340hfinfo_type_bitwidth(enum ftenum type)
11341{
11342 int bitwidth = 0;
11343
11344 switch (type) {
11345 case FT_CHAR:
11346 case FT_UINT8:
11347 case FT_INT8:
11348 bitwidth = 8;
11349 break;
11350 case FT_UINT16:
11351 case FT_INT16:
11352 bitwidth = 16;
11353 break;
11354 case FT_UINT24:
11355 case FT_INT24:
11356 bitwidth = 24;
11357 break;
11358 case FT_UINT32:
11359 case FT_INT32:
11360 bitwidth = 32;
11361 break;
11362 case FT_UINT40:
11363 case FT_INT40:
11364 bitwidth = 40;
11365 break;
11366 case FT_UINT48:
11367 case FT_INT48:
11368 bitwidth = 48;
11369 break;
11370 case FT_UINT56:
11371 case FT_INT56:
11372 bitwidth = 56;
11373 break;
11374 case FT_UINT64:
11375 case FT_INT64:
11376 bitwidth = 64;
11377 break;
11378 default:
11379 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11379))
;
11380 ;
11381 }
11382 return bitwidth;
11383}
11384
11385
11386static int
11387hfinfo_container_bitwidth(const header_field_info *hfinfo)
11388{
11389 if (!hfinfo->bitmask) {
11390 return 0;
11391 }
11392
11393 if (hfinfo->type == FT_BOOLEAN) {
11394 return hfinfo->display; /* hacky? :) */
11395 }
11396
11397 return hfinfo_type_bitwidth(hfinfo->type);
11398}
11399
11400static int
11401hfinfo_hex_digits(const header_field_info *hfinfo)
11402{
11403 int bitwidth;
11404
11405 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11406 * appropriate to determine the number of hex digits for the field.
11407 * So instead, we compute it from the bitmask.
11408 */
11409 if (hfinfo->bitmask != 0) {
11410 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11411 } else {
11412 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11413 }
11414
11415 /* Divide by 4, rounding up, to get number of hex digits. */
11416 return (bitwidth + 3) / 4;
11417}
11418
11419const char *
11420hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11421{
11422 char *ptr = &buf[6];
11423 static const char hex_digits[16] =
11424 { '0', '1', '2', '3', '4', '5', '6', '7',
11425 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11426
11427 *ptr = '\0';
11428 *(--ptr) = '\'';
11429 /* Properly format value */
11430 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11431 /*
11432 * Printable, so just show the character, and, if it needs
11433 * to be escaped, escape it.
11434 */
11435 *(--ptr) = value;
11436 if (value == '\\' || value == '\'')
11437 *(--ptr) = '\\';
11438 } else {
11439 /*
11440 * Non-printable; show it as an escape sequence.
11441 */
11442 switch (value) {
11443
11444 case '\0':
11445 /*
11446 * Show a NUL with only one digit.
11447 */
11448 *(--ptr) = '0';
11449 break;
11450
11451 case '\a':
11452 case '\b':
11453 case '\f':
11454 case '\n':
11455 case '\r':
11456 case '\t':
11457 case '\v':
11458 *(--ptr) = value - '\a' + 'a';
11459 break;
11460
11461 default:
11462 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11463
11464 case BASE_OCT:
11465 *(--ptr) = (value & 0x7) + '0';
11466 value >>= 3;
11467 *(--ptr) = (value & 0x7) + '0';
11468 value >>= 3;
11469 *(--ptr) = (value & 0x7) + '0';
11470 break;
11471
11472 case BASE_HEX:
11473 *(--ptr) = hex_digits[value & 0x0F];
11474 value >>= 4;
11475 *(--ptr) = hex_digits[value & 0x0F];
11476 *(--ptr) = 'x';
11477 break;
11478
11479 default:
11480 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11481 }
11482 }
11483 *(--ptr) = '\\';
11484 }
11485 *(--ptr) = '\'';
11486 return ptr;
11487}
11488
11489static const char *
11490hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11491{
11492 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11493 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
))
;
11494
11495 *ptr = '\0';
11496 /* Properly format value */
11497 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11498 case BASE_DEC:
11499 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11500
11501 case BASE_DEC_HEX:
11502 *(--ptr) = ')';
11503 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11504 *(--ptr) = '(';
11505 *(--ptr) = ' ';
11506 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11507 return ptr;
11508
11509 case BASE_OCT:
11510 return oct_to_str_back(ptr, value);
11511
11512 case BASE_HEX:
11513 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11514
11515 case BASE_HEX_DEC:
11516 *(--ptr) = ')';
11517 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11518 *(--ptr) = '(';
11519 *(--ptr) = ' ';
11520 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11521 return ptr;
11522
11523 case BASE_PT_UDP:
11524 case BASE_PT_TCP:
11525 case BASE_PT_DCCP:
11526 case BASE_PT_SCTP:
11527 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11528 display_to_port_type((field_display_e)display), value);
11529 return buf;
11530 case BASE_OUI:
11531 {
11532 uint8_t p_oui[3];
11533 const char *manuf_name;
11534
11535 p_oui[0] = value >> 16 & 0xFF;
11536 p_oui[1] = value >> 8 & 0xFF;
11537 p_oui[2] = value & 0xFF;
11538
11539 /* Attempt an OUI lookup. */
11540 manuf_name = uint_get_manuf_name_if_known(value);
11541 if (manuf_name == NULL((void*)0)) {
11542 /* Could not find an OUI. */
11543 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11544 }
11545 else {
11546 /* Found an address string. */
11547 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11548 }
11549 return buf;
11550 }
11551
11552 default:
11553 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11554 }
11555 return ptr;
11556}
11557
11558static const char *
11559hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11560{
11561 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11562 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
))
;
11563
11564 *ptr = '\0';
11565 /* Properly format value */
11566 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11567 case BASE_DEC:
11568 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11569
11570 case BASE_DEC_HEX:
11571 *(--ptr) = ')';
11572 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11573 *(--ptr) = '(';
11574 *(--ptr) = ' ';
11575 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11576 return ptr;
11577
11578 case BASE_OCT:
11579 return oct64_to_str_back(ptr, value);
11580
11581 case BASE_HEX:
11582 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11583
11584 case BASE_HEX_DEC:
11585 *(--ptr) = ')';
11586 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11587 *(--ptr) = '(';
11588 *(--ptr) = ' ';
11589 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11590 return ptr;
11591
11592 default:
11593 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11594 }
11595
11596 return ptr;
11597}
11598
11599static const char *
11600hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11601{
11602 int display = hfinfo->display;
11603
11604 if (hfinfo->type == FT_FRAMENUM) {
11605 /*
11606 * Frame numbers are always displayed in decimal.
11607 */
11608 display = BASE_DEC;
11609 }
11610
11611 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11612}
11613
11614static const char *
11615hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11616{
11617 int display = hfinfo->display;
11618
11619 if (hfinfo->type == FT_FRAMENUM) {
11620 /*
11621 * Frame numbers are always displayed in decimal.
11622 */
11623 display = BASE_DEC;
11624 }
11625
11626 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11627}
11628
11629static const char *
11630hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11631{
11632 /* Get the underlying BASE_ value */
11633 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11634
11635 return hfinfo_char_value_format_display(display, buf, value);
11636}
11637
11638static const char *
11639hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11640{
11641 /* Get the underlying BASE_ value */
11642 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11643
11644 if (hfinfo->type == FT_FRAMENUM) {
11645 /*
11646 * Frame numbers are always displayed in decimal.
11647 */
11648 display = BASE_DEC;
11649 }
11650
11651 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11652 display = BASE_DEC;
11653 } else if (display == BASE_OUI) {
11654 display = BASE_HEX;
11655 }
11656
11657 switch (display) {
11658 case BASE_NONE:
11659 /* case BASE_DEC: */
11660 case BASE_DEC_HEX:
11661 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11662 case BASE_CUSTOM:
11663 display = BASE_DEC;
11664 break;
11665
11666 /* case BASE_HEX: */
11667 case BASE_HEX_DEC:
11668 display = BASE_HEX;
11669 break;
11670 }
11671
11672 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11673}
11674
11675static const char *
11676hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11677{
11678 /* Get the underlying BASE_ value */
11679 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11680
11681 if (hfinfo->type == FT_FRAMENUM) {
11682 /*
11683 * Frame numbers are always displayed in decimal.
11684 */
11685 display = BASE_DEC;
11686 }
11687
11688 switch (display) {
11689 case BASE_NONE:
11690 /* case BASE_DEC: */
11691 case BASE_DEC_HEX:
11692 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11693 case BASE_CUSTOM:
11694 display = BASE_DEC;
11695 break;
11696
11697 /* case BASE_HEX: */
11698 case BASE_HEX_DEC:
11699 display = BASE_HEX;
11700 break;
11701 }
11702
11703 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11704}
11705
11706static const char *
11707hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11708{
11709 /* Get the underlying BASE_ value */
11710 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11711
11712 return hfinfo_char_value_format_display(display, buf, value);
11713}
11714
11715static const char *
11716hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11717{
11718 /* Get the underlying BASE_ value */
11719 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11720
11721 if (display == BASE_NONE)
11722 return NULL((void*)0);
11723
11724 if (display == BASE_DEC_HEX)
11725 display = BASE_DEC;
11726 if (display == BASE_HEX_DEC)
11727 display = BASE_HEX;
11728
11729 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11730}
11731
11732static const char *
11733hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11734{
11735 /* Get the underlying BASE_ value */
11736 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11737
11738 if (display == BASE_NONE)
11739 return NULL((void*)0);
11740
11741 if (display == BASE_DEC_HEX)
11742 display = BASE_DEC;
11743 if (display == BASE_HEX_DEC)
11744 display = BASE_HEX;
11745
11746 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11747}
11748
11749const char *
11750proto_registrar_get_name(const int n)
11751{
11752 header_field_info *hfinfo;
11753
11754 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", 11754
, __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", 11754
, "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", 11754, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11755 return hfinfo->name;
11756}
11757
11758const char *
11759proto_registrar_get_abbrev(const int n)
11760{
11761 header_field_info *hfinfo;
11762
11763 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", 11763
, __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", 11763
, "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", 11763, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11764 return hfinfo->abbrev;
11765}
11766
11767enum ftenum
11768proto_registrar_get_ftype(const int n)
11769{
11770 header_field_info *hfinfo;
11771
11772 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", 11772
, __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", 11772
, "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", 11772, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11773 return hfinfo->type;
11774}
11775
11776int
11777proto_registrar_get_parent(const int n)
11778{
11779 header_field_info *hfinfo;
11780
11781 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", 11781
, __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", 11781
, "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", 11781, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11782 return hfinfo->parent;
11783}
11784
11785bool_Bool
11786proto_registrar_is_protocol(const int n)
11787{
11788 header_field_info *hfinfo;
11789
11790 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", 11790
, __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", 11790
, "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", 11790, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11791 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11792}
11793
11794/* Returns length of field in packet (not necessarily the length
11795 * in our internal representation, as in the case of IPv4).
11796 * 0 means undeterminable at time of registration
11797 * -1 means the field is not registered. */
11798int
11799proto_registrar_get_length(const int n)
11800{
11801 header_field_info *hfinfo;
11802
11803 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", 11803
, __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", 11803
, "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", 11803, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11804 return ftype_wire_size(hfinfo->type);
11805}
11806
11807size_t
11808proto_registrar_get_count(struct proto_registrar_stats *stats)
11809{
11810 header_field_info *hfinfo;
11811
11812 // Index zero is not used. We have to skip it.
11813 size_t total_count = gpa_hfinfo.len - 1;
11814 if (stats == NULL((void*)0)) {
11815 return total_count;
11816 }
11817 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11818 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11819 stats->deregistered_count++;
11820 continue; /* This is a deregistered protocol or header field */
11821 }
11822
11823 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", 11823
, __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", 11823, "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", 11823, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11824
11825 if (proto_registrar_is_protocol(id))
11826 stats->protocol_count++;
11827
11828 if (hfinfo->same_name_prev_id != -1)
11829 stats->same_name_count++;
11830 }
11831
11832 return total_count;
11833}
11834
11835/* Looks for a protocol or a field in a proto_tree. Returns true if
11836 * it exists anywhere, or false if it exists nowhere. */
11837bool_Bool
11838proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11839{
11840 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11841
11842 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11843 return true1;
11844 }
11845 else {
11846 return false0;
11847 }
11848}
11849
11850/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11851 * This only works if the hfindex was "primed" before the dissection
11852 * took place, as we just pass back the already-created GPtrArray*.
11853 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11854 * handles that. */
11855GPtrArray *
11856proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11857{
11858 if (!tree)
11859 return NULL((void*)0);
11860
11861 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11862 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11863 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11864 else
11865 return NULL((void*)0);
11866}
11867
11868bool_Bool
11869proto_tracking_interesting_fields(const proto_tree *tree)
11870{
11871 GHashTable *interesting_hfids;
11872
11873 if (!tree)
11874 return false0;
11875
11876 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11877
11878 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11879}
11880
11881/* Helper struct for proto_find_info() and proto_all_finfos() */
11882typedef struct {
11883 GPtrArray *array;
11884 int id;
11885} ffdata_t;
11886
11887/* Helper function for proto_find_info() */
11888static bool_Bool
11889find_finfo(proto_node *node, void * data)
11890{
11891 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11892 if (fi && fi->hfinfo) {
11893 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11894 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11895 }
11896 }
11897
11898 /* Don't stop traversing. */
11899 return false0;
11900}
11901
11902/* Helper function for proto_find_first_info() */
11903static bool_Bool
11904find_first_finfo(proto_node *node, void *data)
11905{
11906 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11907 if (fi && fi->hfinfo) {
11908 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11909 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11910
11911 /* Stop traversing. */
11912 return true1;
11913 }
11914 }
11915
11916 /* Continue traversing. */
11917 return false0;
11918}
11919
11920/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11921* This works on any proto_tree, primed or unprimed, but actually searches
11922* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11923* The caller does need to free the returned GPtrArray with
11924* g_ptr_array_free(<array>, true).
11925*/
11926GPtrArray *
11927proto_find_finfo(proto_tree *tree, const int id)
11928{
11929 ffdata_t ffdata;
11930
11931 ffdata.array = g_ptr_array_new();
11932 ffdata.id = id;
11933
11934 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11935
11936 return ffdata.array;
11937}
11938
11939/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11940* This works on any proto_tree, primed or unprimed, but actually searches
11941* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11942* The caller does need to free the returned GPtrArray with
11943* g_ptr_array_free(<array>, true).
11944*/
11945GPtrArray *
11946proto_find_first_finfo(proto_tree *tree, const int id)
11947{
11948 ffdata_t ffdata;
11949
11950 ffdata.array = g_ptr_array_new();
11951 ffdata.id = id;
11952
11953 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11954
11955 return ffdata.array;
11956}
11957
11958/* Helper function for proto_all_finfos() */
11959static bool_Bool
11960every_finfo(proto_node *node, void * data)
11961{
11962 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11963 if (fi && fi->hfinfo) {
11964 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11965 }
11966
11967 /* Don't stop traversing. */
11968 return false0;
11969}
11970
11971/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11972 * The caller does need to free the returned GPtrArray with
11973 * g_ptr_array_free(<array>, true).
11974 */
11975GPtrArray *
11976proto_all_finfos(proto_tree *tree)
11977{
11978 ffdata_t ffdata;
11979
11980 /* Pre allocate enough space to hold all fields in most cases */
11981 ffdata.array = g_ptr_array_sized_new(512);
11982 ffdata.id = 0;
11983
11984 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11985
11986 return ffdata.array;
11987}
11988
11989
11990typedef struct {
11991 unsigned offset;
11992 field_info *finfo;
11993 tvbuff_t *tvb;
11994} offset_search_t;
11995
11996static bool_Bool
11997check_for_offset(proto_node *node, void * data)
11998{
11999 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12000 offset_search_t *offsearch = (offset_search_t *)data;
12001
12002 /* !fi == the top most container node which holds nothing */
12003 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
12004 if (offsearch->offset >= (unsigned) fi->start &&
12005 offsearch->offset < (unsigned) (fi->start + fi->length)) {
12006
12007 offsearch->finfo = fi;
12008 return false0; /* keep traversing */
12009 }
12010 }
12011 return false0; /* keep traversing */
12012}
12013
12014/* Search a proto_tree backwards (from leaves to root) looking for the field
12015 * whose start/length occupies 'offset' */
12016/* XXX - I couldn't find an easy way to search backwards, so I search
12017 * forwards, w/o stopping. Therefore, the last finfo I find will the be
12018 * the one I want to return to the user. This algorithm is inefficient
12019 * and could be re-done, but I'd have to handle all the children and
12020 * siblings of each node myself. When I have more time I'll do that.
12021 * (yeah right) */
12022field_info *
12023proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
12024{
12025 offset_search_t offsearch;
12026
12027 offsearch.offset = offset;
12028 offsearch.finfo = NULL((void*)0);
12029 offsearch.tvb = tvb;
12030
12031 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
12032
12033 return offsearch.finfo;
12034}
12035
12036typedef struct {
12037 unsigned length;
12038 char *buf;
12039} decoded_data_t;
12040
12041static bool_Bool
12042check_for_undecoded(proto_node *node, void * data)
12043{
12044 field_info *fi = PNODE_FINFO(node)((node)->finfo);
12045 decoded_data_t* decoded = (decoded_data_t*)data;
12046 unsigned i;
12047 unsigned byte;
12048 unsigned bit;
12049
12050 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
12051 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
12052 byte = i / 8;
12053 bit = i % 8;
12054 decoded->buf[byte] |= (1 << bit);
12055 }
12056 }
12057
12058 return false0;
12059}
12060
12061char*
12062proto_find_undecoded_data(proto_tree *tree, unsigned length)
12063{
12064 decoded_data_t decoded;
12065 decoded.length = length;
12066 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
12067
12068 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
12069 return decoded.buf;
12070}
12071
12072/* Dumps the protocols in the registration database to stdout. An independent
12073 * program can take this output and format it into nice tables or HTML or
12074 * whatever.
12075 *
12076 * There is one record per line. The fields are tab-delimited.
12077 *
12078 * Field 1 = protocol name
12079 * Field 2 = protocol short name
12080 * Field 3 = protocol filter name
12081 * Field 4 = protocol enabled
12082 * Field 5 = protocol enabled by default
12083 * Field 6 = protocol can toggle
12084 */
12085void
12086proto_registrar_dump_protocols(void)
12087{
12088 protocol_t *protocol;
12089 int i;
12090 void *cookie = NULL((void*)0);
12091
12092
12093 i = proto_get_first_protocol(&cookie);
12094 while (i != -1) {
12095 protocol = find_protocol_by_id(i);
12096 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
12097 protocol->name,
12098 protocol->short_name,
12099 protocol->filter_name,
12100 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
12101 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
12102 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
12103 i = proto_get_next_protocol(&cookie);
12104 }
12105}
12106
12107/* Dumps the value_strings, extended value string headers, range_strings
12108 * or true/false strings for fields that have them.
12109 * There is one record per line. Fields are tab-delimited.
12110 * There are four types of records: Value String, Extended Value String Header,
12111 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
12112 * the type of record.
12113 *
12114 * Note that a record will be generated only if the value_string,... is referenced
12115 * in a registered hfinfo entry.
12116 *
12117 *
12118 * Value Strings
12119 * -------------
12120 * Field 1 = 'V'
12121 * Field 2 = Field abbreviation to which this value string corresponds
12122 * Field 3 = Integer value
12123 * Field 4 = String
12124 *
12125 * Extended Value String Headers
12126 * -----------------------------
12127 * Field 1 = 'E'
12128 * Field 2 = Field abbreviation to which this extended value string header corresponds
12129 * Field 3 = Extended Value String "Name"
12130 * Field 4 = Number of entries in the associated value_string array
12131 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12132 *
12133 * Range Strings
12134 * -------------
12135 * Field 1 = 'R'
12136 * Field 2 = Field abbreviation to which this range string corresponds
12137 * Field 3 = Integer value: lower bound
12138 * Field 4 = Integer value: upper bound
12139 * Field 5 = String
12140 *
12141 * True/False Strings
12142 * ------------------
12143 * Field 1 = 'T'
12144 * Field 2 = Field abbreviation to which this true/false string corresponds
12145 * Field 3 = True String
12146 * Field 4 = False String
12147 */
12148void
12149proto_registrar_dump_values(void)
12150{
12151 header_field_info *hfinfo;
12152 int i, len, vi;
12153 const value_string *vals;
12154 const val64_string *vals64;
12155 const range_string *range;
12156 const true_false_string *tfs;
12157 const unit_name_string *units;
12158
12159 len = gpa_hfinfo.len;
12160 for (i = 1; i < len ; i++) {
12161 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12162 continue; /* This is a deregistered protocol or field */
12163
12164 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", 12164
, __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", 12164
, "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", 12164, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12165
12166 if (hfinfo->id == hf_text_only) {
12167 continue;
12168 }
12169
12170 /* ignore protocols */
12171 if (proto_registrar_is_protocol(i)) {
12172 continue;
12173 }
12174 /* process header fields */
12175#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12176 /*
12177 * If this field isn't at the head of the list of
12178 * fields with this name, skip this field - all
12179 * fields with the same name are really just versions
12180 * of the same field stored in different bits, and
12181 * should have the same type/radix/value list, and
12182 * just differ in their bit masks. (If a field isn't
12183 * a bitfield, but can be, say, 1 or 2 bytes long,
12184 * it can just be made FT_UINT16, meaning the
12185 * *maximum* length is 2 bytes, and be used
12186 * for all lengths.)
12187 */
12188 if (hfinfo->same_name_prev_id != -1)
12189 continue;
12190#endif
12191 vals = NULL((void*)0);
12192 vals64 = NULL((void*)0);
12193 range = NULL((void*)0);
12194 tfs = NULL((void*)0);
12195 units = NULL((void*)0);
12196
12197 if (hfinfo->strings != NULL((void*)0)) {
12198 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12199 (hfinfo->type == FT_CHAR ||
12200 hfinfo->type == FT_UINT8 ||
12201 hfinfo->type == FT_UINT16 ||
12202 hfinfo->type == FT_UINT24 ||
12203 hfinfo->type == FT_UINT32 ||
12204 hfinfo->type == FT_UINT40 ||
12205 hfinfo->type == FT_UINT48 ||
12206 hfinfo->type == FT_UINT56 ||
12207 hfinfo->type == FT_UINT64 ||
12208 hfinfo->type == FT_INT8 ||
12209 hfinfo->type == FT_INT16 ||
12210 hfinfo->type == FT_INT24 ||
12211 hfinfo->type == FT_INT32 ||
12212 hfinfo->type == FT_INT40 ||
12213 hfinfo->type == FT_INT48 ||
12214 hfinfo->type == FT_INT56 ||
12215 hfinfo->type == FT_INT64 ||
12216 hfinfo->type == FT_FLOAT ||
12217 hfinfo->type == FT_DOUBLE)) {
12218
12219 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12220 range = (const range_string *)hfinfo->strings;
12221 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12222 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12223 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12224 } else {
12225 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12226 }
12227 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12228 vals64 = (const val64_string *)hfinfo->strings;
12229 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12230 units = (const unit_name_string *)hfinfo->strings;
12231 } else {
12232 vals = (const value_string *)hfinfo->strings;
12233 }
12234 }
12235 else if (hfinfo->type == FT_BOOLEAN) {
12236 tfs = (const struct true_false_string *)hfinfo->strings;
12237 }
12238 }
12239
12240 /* Print value strings? */
12241 if (vals) {
12242 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12243 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12244 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12245 if (!val64_string_ext_validate(vse_p)) {
12246 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12246, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12247 continue;
12248 }
12249 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12250 printf("E\t%s\t%u\t%s\t%s\n",
12251 hfinfo->abbrev,
12252 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12253 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12254 val64_string_ext_match_type_str(vse_p));
12255 } else {
12256 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12257 if (!value_string_ext_validate(vse_p)) {
12258 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12258, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12259 continue;
12260 }
12261 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12262 printf("E\t%s\t%u\t%s\t%s\n",
12263 hfinfo->abbrev,
12264 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12265 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12266 value_string_ext_match_type_str(vse_p));
12267 }
12268 }
12269 vi = 0;
12270 while (vals[vi].strptr) {
12271 /* Print in the proper base */
12272 if (hfinfo->type == FT_CHAR) {
12273 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12274 printf("V\t%s\t'%c'\t%s\n",
12275 hfinfo->abbrev,
12276 vals[vi].value,
12277 vals[vi].strptr);
12278 } else {
12279 if (hfinfo->display == BASE_HEX) {
12280 printf("V\t%s\t'\\x%02x'\t%s\n",
12281 hfinfo->abbrev,
12282 vals[vi].value,
12283 vals[vi].strptr);
12284 }
12285 else {
12286 printf("V\t%s\t'\\%03o'\t%s\n",
12287 hfinfo->abbrev,
12288 vals[vi].value,
12289 vals[vi].strptr);
12290 }
12291 }
12292 } else {
12293 if (hfinfo->display == BASE_HEX) {
12294 printf("V\t%s\t0x%x\t%s\n",
12295 hfinfo->abbrev,
12296 vals[vi].value,
12297 vals[vi].strptr);
12298 }
12299 else {
12300 printf("V\t%s\t%u\t%s\n",
12301 hfinfo->abbrev,
12302 vals[vi].value,
12303 vals[vi].strptr);
12304 }
12305 }
12306 vi++;
12307 }
12308 }
12309 else if (vals64) {
12310 vi = 0;
12311 while (vals64[vi].strptr) {
12312 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12313 hfinfo->abbrev,
12314 vals64[vi].value,
12315 vals64[vi].strptr);
12316 vi++;
12317 }
12318 }
12319
12320 /* print range strings? */
12321 else if (range) {
12322 vi = 0;
12323 while (range[vi].strptr) {
12324 /* Print in the proper base */
12325 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12326 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12327 hfinfo->abbrev,
12328 range[vi].value_min,
12329 range[vi].value_max,
12330 range[vi].strptr);
12331 }
12332 else {
12333 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12334 hfinfo->abbrev,
12335 range[vi].value_min,
12336 range[vi].value_max,
12337 range[vi].strptr);
12338 }
12339 vi++;
12340 }
12341 }
12342
12343 /* Print true/false strings? */
12344 else if (tfs) {
12345 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12346 tfs->true_string, tfs->false_string);
12347 }
12348 /* Print unit strings? */
12349 else if (units) {
12350 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12351 units->singular, units->plural ? units->plural : "(no plural)");
12352 }
12353 }
12354}
12355
12356/* Prints the number of registered fields.
12357 * Useful for determining an appropriate value for
12358 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12359 *
12360 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12361 * the number of fields, true otherwise.
12362 */
12363bool_Bool
12364proto_registrar_dump_fieldcount(void)
12365{
12366 struct proto_registrar_stats stats = {0, 0, 0};
12367 size_t total_count = proto_registrar_get_count(&stats);
12368
12369 printf("There are %zu header fields registered, of which:\n"
12370 "\t%zu are deregistered\n"
12371 "\t%zu are protocols\n"
12372 "\t%zu have the same name as another field\n\n",
12373 total_count, stats.deregistered_count, stats.protocol_count,
12374 stats.same_name_count);
12375
12376 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12377 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12378 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12379 "\n");
12380
12381 printf("The header field table consumes %u KiB of memory.\n",
12382 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12383 printf("The fields themselves consume %u KiB of memory.\n",
12384 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12385
12386 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12387}
12388
12389static void
12390elastic_add_base_mapping(json_dumper *dumper)
12391{
12392 json_dumper_set_member_name(dumper, "index_patterns");
12393 json_dumper_begin_array(dumper);
12394 // The index names from write_json_index() in print.c
12395 json_dumper_value_string(dumper, "packets-*");
12396 json_dumper_end_array(dumper);
12397
12398 json_dumper_set_member_name(dumper, "settings");
12399 json_dumper_begin_object(dumper);
12400 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12401 json_dumper_value_anyf(dumper, "%d", 1000000);
12402 json_dumper_end_object(dumper);
12403}
12404
12405static char*
12406ws_type_to_elastic(unsigned type)
12407{
12408 switch(type) {
12409 case FT_INT8:
12410 return "byte";
12411 case FT_UINT8:
12412 case FT_INT16:
12413 return "short";
12414 case FT_UINT16:
12415 case FT_INT32:
12416 case FT_UINT24:
12417 case FT_INT24:
12418 return "integer";
12419 case FT_FRAMENUM:
12420 case FT_UINT32:
12421 case FT_UINT40:
12422 case FT_UINT48:
12423 case FT_UINT56:
12424 case FT_INT40:
12425 case FT_INT48:
12426 case FT_INT56:
12427 case FT_INT64:
12428 return "long";
12429 case FT_UINT64:
12430 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12431 case FT_FLOAT:
12432 return "float";
12433 case FT_DOUBLE:
12434 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12435 return "double";
12436 case FT_IPv6:
12437 case FT_IPv4:
12438 return "ip";
12439 case FT_ABSOLUTE_TIME:
12440 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12441 case FT_BOOLEAN:
12442 return "boolean";
12443 default:
12444 return NULL((void*)0);
12445 }
12446}
12447
12448static char*
12449dot_to_underscore(char* str)
12450{
12451 unsigned i;
12452 for (i = 0; i < strlen(str); i++) {
12453 if (str[i] == '.')
12454 str[i] = '_';
12455 }
12456 return str;
12457}
12458
12459/* Dumps a mapping file for ElasticSearch
12460 * This is the v1 (legacy) _template API.
12461 * At some point it may need to be updated with the composable templates
12462 * introduced in Elasticsearch 7.8 (_index_template)
12463 */
12464void
12465proto_registrar_dump_elastic(const char* filter)
12466{
12467 header_field_info *hfinfo;
12468 header_field_info *parent_hfinfo;
12469 unsigned i;
12470 bool_Bool open_object = true1;
12471 const char* prev_proto = NULL((void*)0);
12472 char* str;
12473 char** protos = NULL((void*)0);
12474 char* proto;
12475 bool_Bool found;
12476 unsigned j;
12477 char* type;
12478 char* prev_item = NULL((void*)0);
12479
12480 /* We have filtering protocols. Extract them. */
12481 if (filter) {
12482 protos = g_strsplit(filter, ",", -1);
12483 }
12484
12485 /*
12486 * To help tracking down the json tree, objects have been appended with a comment:
12487 * n.label -> where n is the indentation level and label the name of the object
12488 */
12489
12490 json_dumper dumper = {
12491 .output_file = stdoutstdout,
12492 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12493 };
12494 json_dumper_begin_object(&dumper); // 1.root
12495 elastic_add_base_mapping(&dumper);
12496
12497 json_dumper_set_member_name(&dumper, "mappings");
12498 json_dumper_begin_object(&dumper); // 2.mappings
12499
12500 json_dumper_set_member_name(&dumper, "properties");
12501 json_dumper_begin_object(&dumper); // 3.properties
12502 json_dumper_set_member_name(&dumper, "timestamp");
12503 json_dumper_begin_object(&dumper); // 4.timestamp
12504 json_dumper_set_member_name(&dumper, "type");
12505 json_dumper_value_string(&dumper, "date");
12506 json_dumper_end_object(&dumper); // 4.timestamp
12507
12508 json_dumper_set_member_name(&dumper, "layers");
12509 json_dumper_begin_object(&dumper); // 4.layers
12510 json_dumper_set_member_name(&dumper, "properties");
12511 json_dumper_begin_object(&dumper); // 5.properties
12512
12513 for (i = 1; i < gpa_hfinfo.len; i++) {
12514 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12515 continue; /* This is a deregistered protocol or header field */
12516
12517 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", 12517
, __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", 12517
, "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", 12517, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12518
12519 /*
12520 * Skip the pseudo-field for "proto_tree_add_text()" since
12521 * we don't want it in the list of filterable protocols.
12522 */
12523 if (hfinfo->id == hf_text_only)
12524 continue;
12525
12526 if (!proto_registrar_is_protocol(i)) {
12527 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", 12527
, __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", 12527
, "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", 12527
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12528
12529 /*
12530 * Skip the field if filter protocols have been set and this one's
12531 * parent is not listed.
12532 */
12533 if (protos) {
12534 found = false0;
12535 j = 0;
12536 proto = protos[0];
12537 while(proto) {
12538 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12539 found = true1;
12540 break;
12541 }
12542 j++;
12543 proto = protos[j];
12544 }
12545 if (!found)
12546 continue;
12547 }
12548
12549 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12550 json_dumper_end_object(&dumper); // 7.properties
12551 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12552 open_object = true1;
12553 }
12554
12555 prev_proto = parent_hfinfo->abbrev;
12556
12557 if (open_object) {
12558 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12559 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12560 json_dumper_set_member_name(&dumper, "properties");
12561 json_dumper_begin_object(&dumper); // 7.properties
12562 open_object = false0;
12563 }
12564 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12565 type = ws_type_to_elastic(hfinfo->type);
12566 /* when type is NULL, we have the default mapping: string */
12567 if (type) {
12568 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12569 dot_to_underscore(str);
12570 if (g_strcmp0(prev_item, str)) {
12571 json_dumper_set_member_name(&dumper, str);
12572 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12573 json_dumper_set_member_name(&dumper, "type");
12574 json_dumper_value_string(&dumper, type);
12575 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12576 }
12577 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)
;
12578 prev_item = str;
12579 }
12580 }
12581 }
12582 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)
;
12583
12584 if (prev_proto) {
12585 json_dumper_end_object(&dumper); // 7.properties
12586 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12587 }
12588
12589 json_dumper_end_object(&dumper); // 5.properties
12590 json_dumper_end_object(&dumper); // 4.layers
12591 json_dumper_end_object(&dumper); // 3.properties
12592 json_dumper_end_object(&dumper); // 2.mappings
12593 json_dumper_end_object(&dumper); // 1.root
12594 bool_Bool ret = json_dumper_finish(&dumper);
12595 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12595, "ret"))))
;
12596
12597 g_strfreev(protos);
12598}
12599
12600/* Dumps the contents of the registration database to stdout. An independent
12601 * program can take this output and format it into nice tables or HTML or
12602 * whatever.
12603 *
12604 * There is one record per line. Each record is either a protocol or a header
12605 * field, differentiated by the first field. The fields are tab-delimited.
12606 *
12607 * Protocols
12608 * ---------
12609 * Field 1 = 'P'
12610 * Field 2 = descriptive protocol name
12611 * Field 3 = protocol abbreviation
12612 *
12613 * Header Fields
12614 * -------------
12615 * Field 1 = 'F'
12616 * Field 2 = descriptive field name
12617 * Field 3 = field abbreviation
12618 * Field 4 = type ( textual representation of the ftenum type )
12619 * Field 5 = parent protocol abbreviation
12620 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12621 * Field 7 = bitmask: format: hex: 0x....
12622 * Field 8 = blurb describing field
12623 */
12624void
12625proto_registrar_dump_fields(void)
12626{
12627 header_field_info *hfinfo, *parent_hfinfo;
12628 int i, len;
12629 const char *enum_name;
12630 const char *base_name;
12631 const char *blurb;
12632 char width[5];
12633
12634 len = gpa_hfinfo.len;
12635 for (i = 1; i < len ; i++) {
12636 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12637 continue; /* This is a deregistered protocol or header field */
12638
12639 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", 12639
, __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", 12639
, "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", 12639, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12640
12641 /*
12642 * Skip the pseudo-field for "proto_tree_add_text()" since
12643 * we don't want it in the list of filterable fields.
12644 */
12645 if (hfinfo->id == hf_text_only)
12646 continue;
12647
12648 /* format for protocols */
12649 if (proto_registrar_is_protocol(i)) {
12650 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12651 }
12652 /* format for header fields */
12653 else {
12654 /*
12655 * If this field isn't at the head of the list of
12656 * fields with this name, skip this field - all
12657 * fields with the same name are really just versions
12658 * of the same field stored in different bits, and
12659 * should have the same type/radix/value list, and
12660 * just differ in their bit masks. (If a field isn't
12661 * a bitfield, but can be, say, 1 or 2 bytes long,
12662 * it can just be made FT_UINT16, meaning the
12663 * *maximum* length is 2 bytes, and be used
12664 * for all lengths.)
12665 */
12666 if (hfinfo->same_name_prev_id != -1)
12667 continue;
12668
12669 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", 12669
, __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", 12669
, "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", 12669
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12670
12671 enum_name = ftype_name(hfinfo->type);
12672 base_name = "";
12673
12674 if (hfinfo->type == FT_CHAR ||
12675 hfinfo->type == FT_UINT8 ||
12676 hfinfo->type == FT_UINT16 ||
12677 hfinfo->type == FT_UINT24 ||
12678 hfinfo->type == FT_UINT32 ||
12679 hfinfo->type == FT_UINT40 ||
12680 hfinfo->type == FT_UINT48 ||
12681 hfinfo->type == FT_UINT56 ||
12682 hfinfo->type == FT_UINT64 ||
12683 hfinfo->type == FT_INT8 ||
12684 hfinfo->type == FT_INT16 ||
12685 hfinfo->type == FT_INT24 ||
12686 hfinfo->type == FT_INT32 ||
12687 hfinfo->type == FT_INT40 ||
12688 hfinfo->type == FT_INT48 ||
12689 hfinfo->type == FT_INT56 ||
12690 hfinfo->type == FT_INT64) {
12691
12692 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12693 case BASE_NONE:
12694 case BASE_DEC:
12695 case BASE_HEX:
12696 case BASE_OCT:
12697 case BASE_DEC_HEX:
12698 case BASE_HEX_DEC:
12699 case BASE_CUSTOM:
12700 case BASE_PT_UDP:
12701 case BASE_PT_TCP:
12702 case BASE_PT_DCCP:
12703 case BASE_PT_SCTP:
12704 case BASE_OUI:
12705 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12706 break;
12707 default:
12708 base_name = "????";
12709 break;
12710 }
12711 } else if (hfinfo->type == FT_BOOLEAN) {
12712 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12713 snprintf(width, sizeof(width), "%d", hfinfo->display);
12714 base_name = width;
12715 }
12716
12717 blurb = hfinfo->blurb;
12718 if (blurb == NULL((void*)0))
12719 blurb = "";
12720 else if (strlen(blurb) == 0)
12721 blurb = "\"\"";
12722
12723 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12724 hfinfo->name, hfinfo->abbrev, enum_name,
12725 parent_hfinfo->abbrev, base_name,
12726 hfinfo->bitmask, blurb);
12727 }
12728 }
12729}
12730
12731/* Dumps all abbreviated field and protocol completions of the given string to
12732 * stdout. An independent program may use this for command-line tab completion
12733 * of fields.
12734 */
12735bool_Bool
12736proto_registrar_dump_field_completions(const char *prefix)
12737{
12738 header_field_info *hfinfo;
12739 int i, len;
12740 size_t prefix_len;
12741 bool_Bool matched = false0;
12742
12743 prefix_len = strlen(prefix);
12744 len = gpa_hfinfo.len;
12745 for (i = 1; i < len ; i++) {
12746 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12747 continue; /* This is a deregistered protocol or header field */
12748
12749 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", 12749
, __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", 12749
, "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", 12749, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12750
12751 /*
12752 * Skip the pseudo-field for "proto_tree_add_text()" since
12753 * we don't want it in the list of filterable fields.
12754 */
12755 if (hfinfo->id == hf_text_only)
12756 continue;
12757
12758 /* format for protocols */
12759 if (proto_registrar_is_protocol(i)) {
12760 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12761 matched = true1;
12762 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12763 }
12764 }
12765 /* format for header fields */
12766 else {
12767 /*
12768 * If this field isn't at the head of the list of
12769 * fields with this name, skip this field - all
12770 * fields with the same name are really just versions
12771 * of the same field stored in different bits, and
12772 * should have the same type/radix/value list, and
12773 * just differ in their bit masks. (If a field isn't
12774 * a bitfield, but can be, say, 1 or 2 bytes long,
12775 * it can just be made FT_UINT16, meaning the
12776 * *maximum* length is 2 bytes, and be used
12777 * for all lengths.)
12778 */
12779 if (hfinfo->same_name_prev_id != -1)
12780 continue;
12781
12782 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12783 matched = true1;
12784 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12785 }
12786 }
12787 }
12788 return matched;
12789}
12790
12791/* Dumps field types and descriptive names to stdout. An independent
12792 * program can take this output and format it into nice tables or HTML or
12793 * whatever.
12794 *
12795 * There is one record per line. The fields are tab-delimited.
12796 *
12797 * Field 1 = field type name, e.g. FT_UINT8
12798 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12799 */
12800void
12801proto_registrar_dump_ftypes(void)
12802{
12803 int fte;
12804
12805 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12806 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12807 }
12808}
12809
12810/* This function indicates whether it's possible to construct a
12811 * "match selected" display filter string for the specified field,
12812 * returns an indication of whether it's possible, and, if it's
12813 * possible and "filter" is non-null, constructs the filter and
12814 * sets "*filter" to point to it.
12815 * You do not need to [g_]free() this string since it will be automatically
12816 * freed once the next packet is dissected.
12817 */
12818static bool_Bool
12819construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12820 char **filter)
12821{
12822 const header_field_info *hfinfo;
12823 int start, length, length_remaining;
12824
12825 if (!finfo)
12826 return false0;
12827
12828 hfinfo = finfo->hfinfo;
12829 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12829, "hfinfo"))))
;
12830
12831 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12832 * then "the numeric value ... is not used when preparing
12833 * filters for the field in question." If it's any other
12834 * base, we'll generate the filter normally (which will
12835 * be numeric, even though the human-readable string does
12836 * work for filtering.)
12837 *
12838 * XXX - It might be nice to use fvalue_to_string_repr() in
12839 * "proto_item_fill_label()" as well, although, there, you'd
12840 * have to deal with the base *and* with resolved values for
12841 * addresses.
12842 *
12843 * Perhaps in addition to taking the repr type (DISPLAY
12844 * or DFILTER) and the display (base), fvalue_to_string_repr()
12845 * should have the the "strings" values in the header_field_info
12846 * structure for the field as a parameter, so it can have
12847 * if the field is Boolean or an enumerated integer type,
12848 * the tables used to generate human-readable values.
12849 */
12850 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12851 const char *str = NULL((void*)0);
12852
12853 switch (hfinfo->type) {
12854
12855 case FT_INT8:
12856 case FT_INT16:
12857 case FT_INT24:
12858 case FT_INT32:
12859 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12860 break;
12861
12862 case FT_CHAR:
12863 case FT_UINT8:
12864 case FT_UINT16:
12865 case FT_UINT24:
12866 case FT_UINT32:
12867 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12868 break;
12869
12870 default:
12871 break;
12872 }
12873
12874 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12875 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12876 return true1;
12877 }
12878 }
12879
12880 switch (hfinfo->type) {
12881
12882 case FT_PROTOCOL:
12883 if (filter != NULL((void*)0))
12884 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12885 break;
12886
12887 case FT_NONE:
12888 /*
12889 * If the length is 0, just match the name of the
12890 * field.
12891 *
12892 * (Also check for negative values, just in case,
12893 * as we'll cast it to an unsigned value later.)
12894 */
12895 length = finfo->length;
12896 if (length == 0) {
12897 if (filter != NULL((void*)0))
12898 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12899 break;
12900 }
12901 if (length < 0)
12902 return false0;
12903
12904 /*
12905 * This doesn't have a value, so we'd match
12906 * on the raw bytes at this address.
12907 *
12908 * Should we be allowed to access to the raw bytes?
12909 * If "edt" is NULL, the answer is "no".
12910 */
12911 if (edt == NULL((void*)0))
12912 return false0;
12913
12914 /*
12915 * Is this field part of the raw frame tvbuff?
12916 * If not, we can't use "frame[N:M]" to match
12917 * it.
12918 *
12919 * XXX - should this be frame-relative, or
12920 * protocol-relative?
12921 *
12922 * XXX - does this fallback for non-registered
12923 * fields even make sense?
12924 */
12925 if (finfo->ds_tvb != edt->tvb)
12926 return false0; /* you lose */
12927
12928 /*
12929 * Don't go past the end of that tvbuff.
12930 */
12931 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12932 if (length > length_remaining)
12933 length = length_remaining;
12934 if (length <= 0)
12935 return false0;
12936
12937 if (filter != NULL((void*)0)) {
12938 start = finfo->start;
12939 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12940 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12941 wmem_free(NULL((void*)0), str);
12942 }
12943 break;
12944
12945 /* By default, use the fvalue's "to_string_repr" method. */
12946 default:
12947 if (filter != NULL((void*)0)) {
12948 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12949 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12950 wmem_free(NULL((void*)0), str);
12951 }
12952 break;
12953 }
12954
12955 return true1;
12956}
12957
12958/*
12959 * Returns true if we can do a "match selected" on the field, false
12960 * otherwise.
12961 */
12962bool_Bool
12963proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12964{
12965 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12966}
12967
12968/* This function attempts to construct a "match selected" display filter
12969 * string for the specified field; if it can do so, it returns a pointer
12970 * to the string, otherwise it returns NULL.
12971 *
12972 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12973 */
12974char *
12975proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12976{
12977 char *filter = NULL((void*)0);
12978
12979 if (!construct_match_selected_string(finfo, edt, &filter))
12980 {
12981 wmem_free(NULL((void*)0), filter);
12982 return NULL((void*)0);
12983 }
12984 return filter;
12985}
12986
12987/* This function is common code for all proto_tree_add_bitmask... functions.
12988 */
12989
12990static bool_Bool
12991proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12992 const unsigned len, const int ett, int * const *fields,
12993 const int flags, bool_Bool first,
12994 bool_Bool use_parent_tree,
12995 proto_tree* tree, uint64_t value)
12996{
12997 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12998 uint64_t bitmask = 0;
12999 uint64_t tmpval;
13000 header_field_info *hf;
13001 uint32_t integer32;
13002 int bit_offset;
13003 int no_of_bits;
13004
13005 if (!*fields)
13006 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"
)
;
13007
13008 if (len > 8)
13009 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
13010 /**
13011 * packet-frame.c uses len=0 since the value is taken from the packet
13012 * metadata, not the packet bytes. In that case, assume that all bits
13013 * in the provided value are valid.
13014 */
13015 if (len > 0) {
13016 available_bits >>= (8 - len)*8;
13017 }
13018
13019 if (use_parent_tree == false0)
13020 tree = proto_item_add_subtree(item, ett);
13021
13022 while (*fields) {
13023 uint64_t present_bits;
13024 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", 13024, __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", 13024
, "**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", 13024, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
13025 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", 13025
, "hf->bitmask != 0", hf->abbrev))))
;
13026
13027 bitmask |= hf->bitmask;
13028
13029 /* Skip fields that aren't fully present */
13030 present_bits = available_bits & hf->bitmask;
13031 if (present_bits != hf->bitmask) {
13032 fields++;
13033 continue;
13034 }
13035
13036 switch (hf->type) {
13037 case FT_CHAR:
13038 case FT_UINT8:
13039 case FT_UINT16:
13040 case FT_UINT24:
13041 case FT_UINT32:
13042 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
13043 break;
13044
13045 case FT_INT8:
13046 case FT_INT16:
13047 case FT_INT24:
13048 case FT_INT32:
13049 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
13050 break;
13051
13052 case FT_UINT40:
13053 case FT_UINT48:
13054 case FT_UINT56:
13055 case FT_UINT64:
13056 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
13057 break;
13058
13059 case FT_INT40:
13060 case FT_INT48:
13061 case FT_INT56:
13062 case FT_INT64:
13063 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
13064 break;
13065
13066 case FT_BOOLEAN:
13067 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
13068 break;
13069
13070 default:
13071 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))
13072 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))
13073 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))
13074 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))
;
13075 break;
13076 }
13077 if (flags & BMT_NO_APPEND0x01) {
13078 fields++;
13079 continue;
13080 }
13081 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
13082
13083 /* XXX: README.developer and the comments have always defined
13084 * BMT_NO_INT as "only boolean flags are added to the title /
13085 * don't add non-boolean (integral) fields", but the
13086 * implementation has always added BASE_CUSTOM and fields with
13087 * value_strings, though not fields with unit_strings.
13088 * Possibly this is because some dissectors use a FT_UINT8
13089 * with a value_string for fields that should be a FT_BOOLEAN.
13090 */
13091 switch (hf->type) {
13092 case FT_CHAR:
13093 if (hf->display == BASE_CUSTOM) {
13094 char lbl[ITEM_LABEL_LENGTH240];
13095 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13096
13097 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13097, "fmtfunc"))))
;
13098 fmtfunc(lbl, (uint32_t) tmpval);
13099 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13100 hf->name, lbl);
13101 first = false0;
13102 }
13103 else if (hf->strings) {
13104 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13105 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13106 first = false0;
13107 }
13108 else if (!(flags & BMT_NO_INT0x02)) {
13109 char buf[32];
13110 const char *out;
13111
13112 if (!first) {
13113 proto_item_append_text(item, ", ");
13114 }
13115
13116 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13117 proto_item_append_text(item, "%s: %s", hf->name, out);
13118 first = false0;
13119 }
13120
13121 break;
13122
13123 case FT_UINT8:
13124 case FT_UINT16:
13125 case FT_UINT24:
13126 case FT_UINT32:
13127 if (hf->display == BASE_CUSTOM) {
13128 char lbl[ITEM_LABEL_LENGTH240];
13129 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13130
13131 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13131, "fmtfunc"))))
;
13132 fmtfunc(lbl, (uint32_t) tmpval);
13133 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13134 hf->name, lbl);
13135 first = false0;
13136 }
13137 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13138 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13139 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13140 first = false0;
13141 }
13142 else if (!(flags & BMT_NO_INT0x02)) {
13143 char buf[NUMBER_LABEL_LENGTH80];
13144 const char *out = NULL((void*)0);
13145
13146 if (!first) {
13147 proto_item_append_text(item, ", ");
13148 }
13149
13150 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13151 out = hf_try_val_to_str((uint32_t) tmpval, hf);
13152 }
13153 if (out == NULL((void*)0)) {
13154 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13155 }
13156 proto_item_append_text(item, "%s: %s", hf->name, out);
13157 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13158 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13159 }
13160 first = false0;
13161 }
13162
13163 break;
13164
13165 case FT_INT8:
13166 case FT_INT16:
13167 case FT_INT24:
13168 case FT_INT32:
13169 integer32 = (uint32_t) tmpval;
13170 if (hf->bitmask) {
13171 no_of_bits = ws_count_ones(hf->bitmask);
13172 integer32 = ws_sign_ext32(integer32, no_of_bits);
13173 }
13174 if (hf->display == BASE_CUSTOM) {
13175 char lbl[ITEM_LABEL_LENGTH240];
13176 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13177
13178 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13178, "fmtfunc"))))
;
13179 fmtfunc(lbl, (int32_t) integer32);
13180 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13181 hf->name, lbl);
13182 first = false0;
13183 }
13184 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13185 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13186 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13187 first = false0;
13188 }
13189 else if (!(flags & BMT_NO_INT0x02)) {
13190 char buf[NUMBER_LABEL_LENGTH80];
13191 const char *out = NULL((void*)0);
13192
13193 if (!first) {
13194 proto_item_append_text(item, ", ");
13195 }
13196
13197 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13198 out = hf_try_val_to_str((int32_t) integer32, hf);
13199 }
13200 if (out == NULL((void*)0)) {
13201 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13202 }
13203 proto_item_append_text(item, "%s: %s", hf->name, out);
13204 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13205 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13206 }
13207 first = false0;
13208 }
13209
13210 break;
13211
13212 case FT_UINT40:
13213 case FT_UINT48:
13214 case FT_UINT56:
13215 case FT_UINT64:
13216 if (hf->display == BASE_CUSTOM) {
13217 char lbl[ITEM_LABEL_LENGTH240];
13218 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13219
13220 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13220, "fmtfunc"))))
;
13221 fmtfunc(lbl, tmpval);
13222 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13223 hf->name, lbl);
13224 first = false0;
13225 }
13226 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13227 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13228 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13229 first = false0;
13230 }
13231 else if (!(flags & BMT_NO_INT0x02)) {
13232 char buf[NUMBER_LABEL_LENGTH80];
13233 const char *out = NULL((void*)0);
13234
13235 if (!first) {
13236 proto_item_append_text(item, ", ");
13237 }
13238
13239 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13240 out = hf_try_val64_to_str(tmpval, hf);
13241 }
13242 if (out == NULL((void*)0)) {
13243 out = hfinfo_number_value_format64(hf, buf, tmpval);
13244 }
13245 proto_item_append_text(item, "%s: %s", hf->name, out);
13246 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13247 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13248 }
13249 first = false0;
13250 }
13251
13252 break;
13253
13254 case FT_INT40:
13255 case FT_INT48:
13256 case FT_INT56:
13257 case FT_INT64:
13258 if (hf->bitmask) {
13259 no_of_bits = ws_count_ones(hf->bitmask);
13260 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13261 }
13262 if (hf->display == BASE_CUSTOM) {
13263 char lbl[ITEM_LABEL_LENGTH240];
13264 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13265
13266 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13266, "fmtfunc"))))
;
13267 fmtfunc(lbl, (int64_t) tmpval);
13268 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13269 hf->name, lbl);
13270 first = false0;
13271 }
13272 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13273 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13274 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13275 first = false0;
13276 }
13277 else if (!(flags & BMT_NO_INT0x02)) {
13278 char buf[NUMBER_LABEL_LENGTH80];
13279 const char *out = NULL((void*)0);
13280
13281 if (!first) {
13282 proto_item_append_text(item, ", ");
13283 }
13284
13285 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13286 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13287 }
13288 if (out == NULL((void*)0)) {
13289 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13290 }
13291 proto_item_append_text(item, "%s: %s", hf->name, out);
13292 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13293 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13294 }
13295 first = false0;
13296 }
13297
13298 break;
13299
13300 case FT_BOOLEAN:
13301 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13302 /* If we have true/false strings, emit full - otherwise messages
13303 might look weird */
13304 const struct true_false_string *tfs =
13305 (const struct true_false_string *)hf->strings;
13306
13307 if (tmpval) {
13308 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13309 hf->name, tfs->true_string);
13310 first = false0;
13311 } else if (!(flags & BMT_NO_FALSE0x04)) {
13312 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13313 hf->name, tfs->false_string);
13314 first = false0;
13315 }
13316 } else if (hf->bitmask & value) {
13317 /* If the flag is set, show the name */
13318 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13319 first = false0;
13320 }
13321 break;
13322 default:
13323 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))
13324 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))
13325 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))
13326 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))
;
13327 break;
13328 }
13329
13330 fields++;
13331 }
13332
13333 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13334 * but then again most dissectors don't set the bitmask field for
13335 * the higher level bitmask hfi, so calculate the bitmask from the
13336 * fields present. */
13337 if (item) {
13338 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13339 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13340 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)
;
13341 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)
;
13342 }
13343 return first;
13344}
13345
13346/* This function will dissect a sequence of bytes that describe a
13347 * bitmask and supply the value of that sequence through a pointer.
13348 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13349 * to be dissected.
13350 * This field will form an expansion under which the individual fields of the
13351 * bitmask is dissected and displayed.
13352 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13353 *
13354 * fields is an array of pointers to int that lists all the fields of the
13355 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13356 * or another integer of the same type/size as hf_hdr with a mask specified.
13357 * This array is terminated by a NULL entry.
13358 *
13359 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13360 * FT_integer fields that have a value_string attached will have the
13361 * matched string displayed on the expansion line.
13362 */
13363proto_item *
13364proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13365 const unsigned offset, const int hf_hdr,
13366 const int ett, int * const *fields,
13367 const unsigned encoding, uint64_t *retval)
13368{
13369 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);
13370}
13371
13372/* This function will dissect a sequence of bytes that describe a
13373 * bitmask.
13374 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13375 * to be dissected.
13376 * This field will form an expansion under which the individual fields of the
13377 * bitmask is dissected and displayed.
13378 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13379 *
13380 * fields is an array of pointers to int that lists all the fields of the
13381 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13382 * or another integer of the same type/size as hf_hdr with a mask specified.
13383 * This array is terminated by a NULL entry.
13384 *
13385 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13386 * FT_integer fields that have a value_string attached will have the
13387 * matched string displayed on the expansion line.
13388 */
13389proto_item *
13390proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13391 const unsigned offset, const int hf_hdr,
13392 const int ett, int * const *fields,
13393 const unsigned encoding)
13394{
13395 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13396}
13397
13398/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13399 * what data is appended to the header.
13400 */
13401proto_item *
13402proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13403 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13404 uint64_t *retval)
13405{
13406 proto_item *item = NULL((void*)0);
13407 header_field_info *hf;
13408 unsigned len;
13409 uint64_t value;
13410
13411 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", 13411, __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", 13411
, "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", 13411, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13412 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", 13412, (hf)->abbrev)))
;
13413 len = ftype_wire_size(hf->type);
13414 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13415
13416 if (parent_tree) {
13417 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13418 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13419 flags, false0, false0, NULL((void*)0), value);
13420 }
13421
13422 *retval = value;
13423 if (hf->bitmask) {
13424 /* Mask out irrelevant portions */
13425 *retval &= hf->bitmask;
13426 /* Shift bits */
13427 *retval >>= hfinfo_bitshift(hf);
13428 }
13429
13430 return item;
13431}
13432
13433/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13434 * what data is appended to the header.
13435 */
13436proto_item *
13437proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13438 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13439{
13440 proto_item *item = NULL((void*)0);
13441 header_field_info *hf;
13442 unsigned len;
13443 uint64_t value;
13444
13445 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", 13445, __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", 13445
, "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", 13445, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13446 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", 13446, (hf)->abbrev)))
;
13447
13448 if (parent_tree) {
13449 len = ftype_wire_size(hf->type);
13450 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13451 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13452 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13453 flags, false0, false0, NULL((void*)0), value);
13454 }
13455
13456 return item;
13457}
13458
13459/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13460 can't be retrieved directly from tvb) */
13461proto_item *
13462proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13463 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13464{
13465 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13466 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13467}
13468
13469/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13470WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13471proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13472 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13473{
13474 proto_item *item = NULL((void*)0);
13475 header_field_info *hf;
13476 unsigned len;
13477
13478 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", 13478, __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", 13478
, "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", 13478, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13479 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", 13479, (hf)->abbrev)))
;
13480 /* the proto_tree_add_uint/_uint64() calls below
13481 will fail if tvb==NULL and len!=0 */
13482 len = tvb ? ftype_wire_size(hf->type) : 0;
13483
13484 if (parent_tree) {
13485 if (len <= 4)
13486 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13487 else
13488 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13489
13490 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13491 flags, false0, false0, NULL((void*)0), value);
13492 }
13493
13494 return item;
13495}
13496
13497/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13498void
13499proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13500 const unsigned len, int * const *fields, const unsigned encoding)
13501{
13502 uint64_t value;
13503
13504 if (tree) {
13505 value = get_uint64_value(tree, tvb, offset, len, encoding);
13506 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13507 BMT_NO_APPEND0x01, false0, true1, tree, value);
13508 }
13509}
13510
13511WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13512proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13513 const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13514{
13515 uint64_t value;
13516
13517 value = get_uint64_value(tree, tvb, offset, len, encoding);
13518 if (tree) {
13519 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13520 BMT_NO_APPEND0x01, false0, true1, tree, value);
13521 }
13522 if (retval) {
13523 *retval = value;
13524 }
13525}
13526
13527WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13528proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13529 const unsigned len, int * const *fields, const uint64_t value)
13530{
13531 if (tree) {
13532 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13533 BMT_NO_APPEND0x01, false0, true1, tree, value);
13534 }
13535}
13536
13537
13538/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13539 * This is intended to support bitmask fields whose lengths can vary, perhaps
13540 * as the underlying standard evolves over time.
13541 * With this API there is the possibility of being called to display more or
13542 * less data than the dissector was coded to support.
13543 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13544 * Thus when presented with "too much" or "too little" data, MSbits will be
13545 * ignored or MSfields sacrificed.
13546 *
13547 * Only fields for which all defined bits are available are displayed.
13548 */
13549proto_item *
13550proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13551 const unsigned offset, const unsigned len, const int hf_hdr,
13552 const int ett, int * const *fields, struct expert_field* exp,
13553 const unsigned encoding)
13554{
13555 proto_item *item = NULL((void*)0);
13556 header_field_info *hf;
13557 unsigned decodable_len;
13558 unsigned decodable_offset;
13559 uint32_t decodable_value;
13560 uint64_t value;
13561
13562 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", 13562, __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", 13562
, "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", 13562, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13563 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", 13563, (hf)->abbrev)))
;
13564
13565 decodable_offset = offset;
13566 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13567
13568 /* If we are ftype_wire_size-limited,
13569 * make sure we decode as many LSBs as possible.
13570 */
13571 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13572 decodable_offset += (len - decodable_len);
13573 }
13574
13575 if (parent_tree) {
13576 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13577 decodable_len, encoding);
13578
13579 /* The root item covers all the bytes even if we can't decode them all */
13580 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13581 decodable_value);
13582 }
13583
13584 if (decodable_len < len) {
13585 /* Dissector likely requires updating for new protocol revision */
13586 expert_add_info_format(NULL((void*)0), item, exp,
13587 "Only least-significant %d of %d bytes decoded",
13588 decodable_len, len);
13589 }
13590
13591 if (item) {
13592 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13593 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13594 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13595 }
13596
13597 return item;
13598}
13599
13600/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13601proto_item *
13602proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13603 const unsigned offset, const unsigned len,
13604 const char *name, const char *fallback,
13605 const int ett, int * const *fields,
13606 const unsigned encoding, const int flags)
13607{
13608 proto_item *item = NULL((void*)0);
13609 uint64_t value;
13610
13611 if (parent_tree) {
13612 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13613 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13614 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13615 flags, true1, false0, NULL((void*)0), value) && fallback) {
13616 /* Still at first item - append 'fallback' text if any */
13617 proto_item_append_text(item, "%s", fallback);
13618 }
13619 }
13620
13621 return item;
13622}
13623
13624proto_item *
13625proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13626 const unsigned bit_offset, const int no_of_bits,
13627 const unsigned encoding)
13628{
13629 header_field_info *hfinfo;
13630 int octet_length;
13631 unsigned octet_offset;
13632
13633 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", 13633, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13633
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13633, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13634
13635 if (no_of_bits < 0) {
13636 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13637 }
13638 octet_length = (no_of_bits + 7) >> 3;
13639 octet_offset = bit_offset >> 3;
13640 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13641
13642 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13643 * but only after doing a bunch more work (which we can, in the common
13644 * case, shortcut here).
13645 */
13646 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13647 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", 13647
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13647, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13647, "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", 13647, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13648
13649 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13650}
13651
13652/*
13653 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13654 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13655 * Offset should be given in bits from the start of the tvb.
13656 */
13657
13658static proto_item *
13659_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13660 const unsigned bit_offset, const int no_of_bits,
13661 uint64_t *return_value, const unsigned encoding)
13662{
13663 unsigned offset;
13664 unsigned length;
13665 uint8_t tot_no_bits;
13666 char *bf_str;
13667 char lbl_str[ITEM_LABEL_LENGTH240];
13668 uint64_t value = 0;
13669 uint8_t *bytes = NULL((void*)0);
13670 size_t bytes_length = 0;
13671
13672 proto_item *pi;
13673 header_field_info *hf_field;
13674
13675 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13676 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", 13676, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13676
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13676, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13677
13678 if (hf_field->bitmask != 0) {
13679 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)
13680 " 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)
13681 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)
;
13682 }
13683
13684 if (no_of_bits < 0) {
13685 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13686 } else if (no_of_bits == 0) {
13687 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)
13688 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)
;
13689 }
13690
13691 /* Byte align offset */
13692 offset = bit_offset>>3;
13693
13694 /*
13695 * Calculate the number of octets used to hold the bits
13696 */
13697 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13698 length = (tot_no_bits + 7) >> 3;
13699
13700 if (no_of_bits < 65) {
13701 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13702 } else if (hf_field->type != FT_BYTES) {
13703 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)
13704 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)
;
13705 return NULL((void*)0);
13706 }
13707
13708 /* Sign extend for signed types */
13709 switch (hf_field->type) {
13710 case FT_INT8:
13711 case FT_INT16:
13712 case FT_INT24:
13713 case FT_INT32:
13714 case FT_INT40:
13715 case FT_INT48:
13716 case FT_INT56:
13717 case FT_INT64:
13718 value = ws_sign_ext64(value, no_of_bits);
13719 break;
13720
13721 default:
13722 break;
13723 }
13724
13725 if (return_value) {
13726 *return_value = value;
13727 }
13728
13729 /* Coast clear. Try and fake it */
13730 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13731 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", 13731
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13731, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13731, "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", 13731, __func__, "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); } } }
;
13732
13733 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13734
13735 switch (hf_field->type) {
13736 case FT_BOOLEAN:
13737 /* Boolean field */
13738 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13739 "%s = %s: %s",
13740 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13741 break;
13742
13743 case FT_CHAR:
13744 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13745 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13746 break;
13747
13748 case FT_UINT8:
13749 case FT_UINT16:
13750 case FT_UINT24:
13751 case FT_UINT32:
13752 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13753 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13754 break;
13755
13756 case FT_INT8:
13757 case FT_INT16:
13758 case FT_INT24:
13759 case FT_INT32:
13760 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13761 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13762 break;
13763
13764 case FT_UINT40:
13765 case FT_UINT48:
13766 case FT_UINT56:
13767 case FT_UINT64:
13768 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13769 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13770 break;
13771
13772 case FT_INT40:
13773 case FT_INT48:
13774 case FT_INT56:
13775 case FT_INT64:
13776 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13777 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13778 break;
13779
13780 case FT_BYTES:
13781 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13782 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13783 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13784 proto_item_set_text(pi, "%s", lbl_str);
13785 return pi;
13786
13787 /* TODO: should handle FT_UINT_BYTES ? */
13788
13789 default:
13790 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))
13791 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))
13792 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))
13793 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))
;
13794 return NULL((void*)0);
13795 }
13796
13797 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13798 return pi;
13799}
13800
13801proto_item *
13802proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13803 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13804 uint64_t *return_value)
13805{
13806 proto_item *pi;
13807 int no_of_bits;
13808 unsigned octet_offset;
13809 unsigned mask_initial_bit_offset;
13810 unsigned mask_greatest_bit_offset;
13811 unsigned octet_length;
13812 uint8_t i;
13813 char bf_str[256];
13814 char lbl_str[ITEM_LABEL_LENGTH240];
13815 uint64_t value;
13816 uint64_t composite_bitmask;
13817 uint64_t composite_bitmap;
13818
13819 header_field_info *hf_field;
13820
13821 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13822 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", 13822, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13822
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13822, "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
13823
13824 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13825 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)
13826 " 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)
13827 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)
;
13828 }
13829
13830 mask_initial_bit_offset = bit_offset % 8;
13831
13832 no_of_bits = 0;
13833 value = 0;
13834 i = 0;
13835 mask_greatest_bit_offset = 0;
13836 composite_bitmask = 0;
13837 composite_bitmap = 0;
13838
13839 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
13840 uint64_t crumb_mask, crumb_value;
13841 uint8_t crumb_end_bit_offset;
13842
13843 crumb_value = tvb_get_bits64(tvb,
13844 bit_offset + crumb_spec[i].crumb_bit_offset,
13845 crumb_spec[i].crumb_bit_length,
13846 ENC_BIG_ENDIAN0x00000000);
13847 value += crumb_value;
13848 no_of_bits += crumb_spec[i].crumb_bit_length;
13849 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", 13849
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13850
13851 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13852 octet containing the initial offset.
13853 If the mask is beyond 32 bits, then give up on bit map display.
13854 This could be improved in future, probably showing a table
13855 of 32 or 64 bits per row */
13856 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13857 crumb_end_bit_offset = mask_initial_bit_offset
13858 + crumb_spec[i].crumb_bit_offset
13859 + crumb_spec[i].crumb_bit_length;
13860 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'
13861
13862 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13863 mask_greatest_bit_offset = crumb_end_bit_offset;
13864 }
13865 /* Currently the bitmap of the crumbs are only shown if
13866 * smaller than 32 bits. Do not bother calculating the
13867 * mask if it is larger than that. */
13868 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13869 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'
13870 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13871 }
13872 }
13873 /* Shift left for the next segment */
13874 value <<= crumb_spec[++i].crumb_bit_length;
13875 }
13876
13877 /* Sign extend for signed types */
13878 switch (hf_field->type) {
13879 case FT_INT8:
13880 case FT_INT16:
13881 case FT_INT24:
13882 case FT_INT32:
13883 case FT_INT40:
13884 case FT_INT48:
13885 case FT_INT56:
13886 case FT_INT64:
13887 value = ws_sign_ext64(value, no_of_bits);
13888 break;
13889 default:
13890 break;
13891 }
13892
13893 if (return_value) {
13894 *return_value = value;
13895 }
13896
13897 /* Coast clear. Try and fake it */
13898 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13899 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", 13899
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13899, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13899, "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", 13899, __func__, "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); } } }
;
13900
13901 /* initialise the format string */
13902 bf_str[0] = '\0';
13903
13904 octet_offset = bit_offset >> 3;
13905
13906 /* Round up mask length to nearest octet */
13907 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13908 mask_greatest_bit_offset = octet_length << 3;
13909
13910 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13911 It would be a useful enhancement to eliminate this restriction. */
13912 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13913 other_decode_bitfield_value(bf_str,
13914 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13915 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13916 mask_greatest_bit_offset);
13917 } else {
13918 /* If the bitmask is too large, try to describe its contents. */
13919 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13920 }
13921
13922 switch (hf_field->type) {
13923 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13924 /* Boolean field */
13925 return proto_tree_add_boolean_format(tree, hfindex,
13926 tvb, octet_offset, octet_length, value,
13927 "%s = %s: %s",
13928 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13929 break;
13930
13931 case FT_CHAR:
13932 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13933 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13934 break;
13935
13936 case FT_UINT8:
13937 case FT_UINT16:
13938 case FT_UINT24:
13939 case FT_UINT32:
13940 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13941 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13942 break;
13943
13944 case FT_INT8:
13945 case FT_INT16:
13946 case FT_INT24:
13947 case FT_INT32:
13948 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13949 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13950 break;
13951
13952 case FT_UINT40:
13953 case FT_UINT48:
13954 case FT_UINT56:
13955 case FT_UINT64:
13956 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13957 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13958 break;
13959
13960 case FT_INT40:
13961 case FT_INT48:
13962 case FT_INT56:
13963 case FT_INT64:
13964 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13965 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13966 break;
13967
13968 default:
13969 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))
13970 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))
13971 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))
13972 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))
;
13973 return NULL((void*)0);
13974 }
13975 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13976 return pi;
13977}
13978
13979void
13980proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13981 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13982{
13983 header_field_info *hfinfo;
13984 unsigned start = bit_offset >> 3;
13985 unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13986
13987 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13988 * so that we can use the tree's memory scope in calculating the string */
13989 tvb_ensure_bytes_exist(tvb, start, length);
13990 if (!tree) return;
13991
13992 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", 13992, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13992
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13992, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13993 proto_tree_add_text_internal(tree, tvb, start, length,
13994 "%s crumb %d of %s (decoded above)",
13995 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13996 tvb_get_bits32(tvb,
13997 bit_offset,
13998 crumb_spec[crumb_index].crumb_bit_length,
13999 ENC_BIG_ENDIAN0x00000000),
14000 ENC_BIG_ENDIAN0x00000000),
14001 crumb_index,
14002 hfinfo->name);
14003}
14004
14005proto_item *
14006proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14007 const unsigned bit_offset, const int no_of_bits,
14008 uint64_t *return_value, const unsigned encoding)
14009{
14010 proto_item *item;
14011
14012 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
14013 bit_offset, no_of_bits,
14014 return_value, encoding))) {
14015 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)
;
14016 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)
;
14017 }
14018 return item;
14019}
14020
14021static proto_item *
14022_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14023 tvbuff_t *tvb, const unsigned bit_offset,
14024 const int no_of_bits, void *value_ptr,
14025 const unsigned encoding, char *value_str)
14026{
14027 unsigned offset;
14028 unsigned length;
14029 uint8_t tot_no_bits;
14030 char *str;
14031 uint64_t value = 0;
14032 header_field_info *hf_field;
14033
14034 /* We do not have to return a value, try to fake it as soon as possible */
14035 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14036 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", 14036
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14036, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14036, "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", 14036, __func__, "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); } } }
;
14037
14038 if (hf_field->bitmask != 0) {
14039 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)
14040 " 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)
14041 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)
;
14042 }
14043
14044 if (no_of_bits < 0) {
14045 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
14046 } else if (no_of_bits == 0) {
14047 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)
14048 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)
;
14049 }
14050
14051 /* Byte align offset */
14052 offset = bit_offset>>3;
14053
14054 /*
14055 * Calculate the number of octets used to hold the bits
14056 */
14057 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
14058 length = tot_no_bits>>3;
14059 /* If we are using part of the next octet, increase length by 1 */
14060 if (tot_no_bits & 0x07)
14061 length++;
14062
14063 if (no_of_bits < 65) {
14064 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
14065 } else {
14066 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)
14067 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)
;
14068 return NULL((void*)0);
14069 }
14070
14071 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
14072
14073 (void) g_strlcat(str, " = ", 256+64);
14074 (void) g_strlcat(str, hf_field->name, 256+64);
14075
14076 /*
14077 * This function does not receive an actual value but a dimensionless pointer to that value.
14078 * For this reason, the type of the header field is examined in order to determine
14079 * what kind of value we should read from this address.
14080 * The caller of this function must make sure that for the specific header field type the address of
14081 * a compatible value is provided.
14082 */
14083 switch (hf_field->type) {
14084 case FT_BOOLEAN:
14085 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14086 "%s: %s", str, value_str);
14087 break;
14088
14089 case FT_CHAR:
14090 case FT_UINT8:
14091 case FT_UINT16:
14092 case FT_UINT24:
14093 case FT_UINT32:
14094 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
14095 "%s: %s", str, value_str);
14096 break;
14097
14098 case FT_UINT40:
14099 case FT_UINT48:
14100 case FT_UINT56:
14101 case FT_UINT64:
14102 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14103 "%s: %s", str, value_str);
14104 break;
14105
14106 case FT_INT8:
14107 case FT_INT16:
14108 case FT_INT24:
14109 case FT_INT32:
14110 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
14111 "%s: %s", str, value_str);
14112 break;
14113
14114 case FT_INT40:
14115 case FT_INT48:
14116 case FT_INT56:
14117 case FT_INT64:
14118 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14119 "%s: %s", str, value_str);
14120 break;
14121
14122 case FT_FLOAT:
14123 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14124 "%s: %s", str, value_str);
14125 break;
14126
14127 default:
14128 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))
14129 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))
14130 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))
14131 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))
;
14132 return NULL((void*)0);
14133 }
14134}
14135
14136static proto_item *
14137proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14138 tvbuff_t *tvb, const unsigned bit_offset,
14139 const int no_of_bits, void *value_ptr,
14140 const unsigned encoding, char *value_str)
14141{
14142 proto_item *item;
14143
14144 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14145 tvb, bit_offset, no_of_bits,
14146 value_ptr, encoding, value_str))) {
14147 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)
;
14148 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)
;
14149 }
14150 return item;
14151}
14152
14153#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);
\
14154 va_start(ap, format)__builtin_va_start(ap, format); \
14155 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14156 va_end(ap)__builtin_va_end(ap);
14157
14158proto_item *
14159proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14160 tvbuff_t *tvb, const unsigned bit_offset,
14161 const int no_of_bits, uint32_t value,
14162 const unsigned encoding,
14163 const char *format, ...)
14164{
14165 va_list ap;
14166 char *dst;
14167 header_field_info *hf_field;
14168
14169 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14170
14171 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", 14171
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14171, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14171, "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", 14171, __func__, "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); } } }
;
14172
14173 switch (hf_field->type) {
14174 case FT_UINT8:
14175 case FT_UINT16:
14176 case FT_UINT24:
14177 case FT_UINT32:
14178 break;
14179
14180 default:
14181 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)
14182 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)
;
14183 return NULL((void*)0);
14184 }
14185
14186 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);
;
14187
14188 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14189}
14190
14191proto_item *
14192proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14193 tvbuff_t *tvb, const unsigned bit_offset,
14194 const int no_of_bits, uint64_t value,
14195 const unsigned encoding,
14196 const char *format, ...)
14197{
14198 va_list ap;
14199 char *dst;
14200 header_field_info *hf_field;
14201
14202 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14203
14204 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", 14204
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14204, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14204, "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", 14204, __func__, "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); } } }
;
14205
14206 switch (hf_field->type) {
14207 case FT_UINT40:
14208 case FT_UINT48:
14209 case FT_UINT56:
14210 case FT_UINT64:
14211 break;
14212
14213 default:
14214 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)
14215 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)
;
14216 return NULL((void*)0);
14217 }
14218
14219 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);
;
14220
14221 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14222}
14223
14224proto_item *
14225proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14226 tvbuff_t *tvb, const unsigned bit_offset,
14227 const int no_of_bits, float value,
14228 const unsigned encoding,
14229 const char *format, ...)
14230{
14231 va_list ap;
14232 char *dst;
14233 header_field_info *hf_field;
14234
14235 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14236
14237 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", 14237
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14237, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14237, "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", 14237, __func__, "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); } } }
;
14238
14239 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",
14239, ((hf_field))->abbrev))))
;
14240
14241 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);
;
14242
14243 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14244}
14245
14246proto_item *
14247proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14248 tvbuff_t *tvb, const unsigned bit_offset,
14249 const int no_of_bits, int32_t value,
14250 const unsigned encoding,
14251 const char *format, ...)
14252{
14253 va_list ap;
14254 char *dst;
14255 header_field_info *hf_field;
14256
14257 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14258
14259 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", 14259
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14259, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14259, "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", 14259, __func__, "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); } } }
;
14260
14261 switch (hf_field->type) {
14262 case FT_INT8:
14263 case FT_INT16:
14264 case FT_INT24:
14265 case FT_INT32:
14266 break;
14267
14268 default:
14269 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)
14270 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)
;
14271 return NULL((void*)0);
14272 }
14273
14274 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);
;
14275
14276 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14277}
14278
14279proto_item *
14280proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14281 tvbuff_t *tvb, const unsigned bit_offset,
14282 const int no_of_bits, int64_t value,
14283 const unsigned encoding,
14284 const char *format, ...)
14285{
14286 va_list ap;
14287 char *dst;
14288 header_field_info *hf_field;
14289
14290 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14291
14292 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", 14292
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14292, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14292, "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", 14292, __func__, "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); } } }
;
14293
14294 switch (hf_field->type) {
14295 case FT_INT40:
14296 case FT_INT48:
14297 case FT_INT56:
14298 case FT_INT64:
14299 break;
14300
14301 default:
14302 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)
14303 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)
;
14304 return NULL((void*)0);
14305 }
14306
14307 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);
;
14308
14309 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14310}
14311
14312proto_item *
14313proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14314 tvbuff_t *tvb, const unsigned bit_offset,
14315 const int no_of_bits, uint64_t value,
14316 const unsigned encoding,
14317 const char *format, ...)
14318{
14319 va_list ap;
14320 char *dst;
14321 header_field_info *hf_field;
14322
14323 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14324
14325 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", 14325
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14325, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14325, "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", 14325, __func__, "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); } } }
;
14326
14327 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"
, 14327, ((hf_field))->abbrev))))
;
14328
14329 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);
;
14330
14331 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14332}
14333
14334proto_item *
14335proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14336 const unsigned bit_offset, const int no_of_chars)
14337{
14338 proto_item *pi;
14339 header_field_info *hfinfo;
14340 int byte_length;
14341 unsigned byte_offset;
14342 char *string;
14343
14344 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14345
14346 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", 14346
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14346, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14346, "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", 14346, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14347
14348 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"
, 14348, ((hfinfo))->abbrev))))
;
14349
14350 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14351 byte_offset = bit_offset >> 3;
14352
14353 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14354
14355 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14356 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14356, "byte_length >= 0"
))))
;
14357 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14358
14359 return pi;
14360}
14361
14362proto_item *
14363proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14364 const unsigned bit_offset, const int no_of_chars)
14365{
14366 proto_item *pi;
14367 header_field_info *hfinfo;
14368 int byte_length;
14369 unsigned byte_offset;
14370 char *string;
14371
14372 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14373
14374 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", 14374
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14374, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14374, "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", 14374, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14375
14376 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"
, 14376, ((hfinfo))->abbrev))))
;
14377
14378 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14379 byte_offset = bit_offset >> 3;
14380
14381 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14382
14383 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14384 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14384, "byte_length >= 0"
))))
;
14385 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14386
14387 return pi;
14388}
14389
14390const value_string proto_checksum_vals[] = {
14391 { PROTO_CHECKSUM_E_BAD, "Bad" },
14392 { PROTO_CHECKSUM_E_GOOD, "Good" },
14393 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14394 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14395 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14396
14397 { 0, NULL((void*)0) }
14398};
14399
14400#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14401
14402proto_item *
14403proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14404 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14405 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14406{
14407 header_field_info *hfinfo;
14408 uint32_t checksum;
14409 uint32_t len;
14410 proto_item* ti = NULL((void*)0);
14411 proto_item* ti2;
14412 bool_Bool incorrect_checksum = true1;
14413
14414 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", 14414, __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", 14414
, "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", 14414, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14415
14416 switch (hfinfo->type) {
14417 case FT_UINT8:
14418 len = 1;
14419 break;
14420 case FT_UINT16:
14421 len = 2;
14422 break;
14423 case FT_UINT24:
14424 len = 3;
14425 break;
14426 case FT_UINT32:
14427 len = 4;
14428 break;
14429 default:
14430 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)
14431 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14432 }
14433
14434 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14435 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14436 proto_item_set_generated(ti);
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, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14440 proto_item_set_generated(ti2);
14441 }
14442 return ti;
14443 }
14444
14445 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14446 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14447 proto_item_set_generated(ti);
14448 } else {
14449 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14450 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14451 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14452 if (computed_checksum == 0) {
14453 proto_item_append_text(ti, " [correct]");
14454 // Backward compatible with use of -1
14455 if (hf_checksum_status > 0) {
14456 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14457 proto_item_set_generated(ti2);
14458 }
14459 incorrect_checksum = false0;
14460 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14461 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14462 /* XXX - This can't distinguish between "shouldbe"
14463 * 0x0000 and 0xFFFF unless we know whether there
14464 * were any nonzero bits (other than the checksum).
14465 * Protocols should not use this path if they might
14466 * have an all zero packet.
14467 * Some implementations put the wrong zero; maybe
14468 * we should have a special expert info for that?
14469 */
14470 }
14471 } else {
14472 if (checksum == computed_checksum) {
14473 proto_item_append_text(ti, " [correct]");
14474 // Backward compatible with use of -1
14475 if (hf_checksum_status > 0) {
14476 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14477 proto_item_set_generated(ti2);
14478 }
14479 incorrect_checksum = false0;
14480 }
14481 }
14482
14483 if (incorrect_checksum) {
14484 // Backward compatible with use of -1
14485 if (hf_checksum_status > 0) {
14486 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14487 proto_item_set_generated(ti2);
14488 }
14489 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14490 proto_item_append_text(ti, " [incorrect]");
14491 if (bad_checksum_expert != NULL((void*)0))
14492 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14493 } else {
14494 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14495 if (bad_checksum_expert != NULL((void*)0))
14496 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);
14497 }
14498 }
14499 } else {
14500 // Backward compatible with use of -1
14501 if (hf_checksum_status > 0) {
14502 proto_item_append_text(ti, " [unverified]");
14503 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14504 proto_item_set_generated(ti2);
14505 }
14506 }
14507 }
14508
14509 return ti;
14510}
14511
14512proto_item *
14513proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14514 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14515 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14516{
14517 header_field_info *hfinfo;
14518 uint8_t *checksum = NULL((void*)0);
14519 proto_item* ti = NULL((void*)0);
14520 proto_item* ti2;
14521 bool_Bool incorrect_checksum = true1;
14522
14523 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", 14523, __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", 14523
, "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", 14523, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14524
14525 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",
14525, ((hfinfo))->abbrev))))
;
14526
14527 /* Make sure a NULL computed_checksum isn't dereferenced.
14528 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14529 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14530 * cases the behavior is unexpected and still a programmer error;
14531 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14532 * _NOT_PRESENT nor _GENERATED is correct.
14533 */
14534 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", 14534, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14535
14536 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14537 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14538 proto_item_set_generated(ti);
14539 // Backward compatible with use of -1
14540 if (hf_checksum_status > 0) {
14541 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14542 proto_item_set_generated(ti2);
14543 }
14544 return ti;
14545 }
14546
14547 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14548 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14549 proto_item_set_generated(ti);
14550 return ti;
14551 }
14552
14553 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14554 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14555 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14556 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14557 bool_Bool non_zero_flag = false0;
14558 for (size_t index = 0; index < checksum_len; index++) {
14559 if (computed_checksum[index]) {
14560 non_zero_flag = true1;
14561 break;
14562 }
14563 }
14564 if (!non_zero_flag) {
14565 proto_item_append_text(ti, " [correct]");
14566 // Backward compatible with use of -1
14567 if (hf_checksum_status > 0) {
14568 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14569 proto_item_set_generated(ti2);
14570 }
14571 incorrect_checksum = false0;
14572 }
14573 } else {
14574 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14575 proto_item_append_text(ti, " [correct]");
14576 // Backward compatible with use of -1
14577 if (hf_checksum_status > 0) {
14578 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14579 proto_item_set_generated(ti2);
14580 }
14581 incorrect_checksum = false0;
14582 }
14583 }
14584
14585 if (incorrect_checksum) {
14586 // Backward compatible with use of -1
14587 if (hf_checksum_status > 0) {
14588 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14589 proto_item_set_generated(ti2);
14590 }
14591 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14592 proto_item_append_text(ti, " [incorrect]");
14593 if (bad_checksum_expert != NULL((void*)0))
14594 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14595 } else {
14596 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14597 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14598 if (bad_checksum_expert != NULL((void*)0))
14599 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14600 }
14601 }
14602 } else {
14603 // Backward compatible with use of -1
14604 if (hf_checksum_status > 0) {
14605 proto_item_append_text(ti, " [unverified]");
14606 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14607 proto_item_set_generated(ti2);
14608 }
14609 }
14610
14611 return ti;
14612}
14613
14614unsigned char
14615proto_check_field_name(const char *field_name)
14616{
14617 return module_check_valid_name(field_name, false0);
14618}
14619
14620unsigned char
14621proto_check_field_name_lower(const char *field_name)
14622{
14623 return module_check_valid_name(field_name, true1);
14624}
14625
14626bool_Bool
14627tree_expanded(int tree_type)
14628{
14629 if (tree_type <= 0) {
14630 return false0;
14631 }
14632 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", 14632, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14633 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14634}
14635
14636void
14637tree_expanded_set(int tree_type, bool_Bool value)
14638{
14639 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", 14639, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14640
14641 if (value)
14642 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14643 else
14644 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14645}
14646
14647/*
14648 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14649 *
14650 * Local variables:
14651 * c-basic-offset: 8
14652 * tab-width: 8
14653 * indent-tabs-mode: t
14654 * End:
14655 *
14656 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14657 * :indentSize=8:tabSize=8:noTabs=false:
14658 */